日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义MyBatis

發布時間:2025/3/14 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义MyBatis 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自定義MyBatis是為了深入了解MyBatis的原理

主要的調用是這樣的:

//1.讀取配置文件 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); //2.創建SqlSessionFactory工廠 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(in); //3.使用工廠生產SqlSession對象 SqlSession session = factory.openSession(); //4.使用SQLSession創建Dao接口的代理對象 UserDao userDao = session.getMapper(UserDao.class); //5.使用代理對象執行方法 List<User> users = userDao.findAll(); for (User user : users) {System.out.println(user); } //6.釋放資源 session.close(); in.close();

首先第一步:將配置文件SqlMapConfig.xml轉為流文件

<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE configuration><configuration><!--配置環境--><environments default="mysql"><!--配置mysql的環境--><environment id="mysql"><!--配置事務類型--><transactionManager type="JDBC"></transactionManager><!--配置數據源(連接池)--><dataSource type="POOLED"><!--配置連接數據庫的基本信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url"value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8"/><property name="username" value="root"/><property name="password" value="1234"/></dataSource></environment></environments><!--指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件--><!--<mappers><mapper resource="com/jinke/dao/UserDao.xml"/></mappers>--><!--如果是用注解來配置--><mappers><mapper class="com.jinke.dao.UserDao"/></mappers> </configuration> import java.io.InputStream;/*使用類加載器讀取配置文件的類*/ public class Resources {public static InputStream getResourceAsStream(String filePath) {return Resources.class.getClassLoader().getResourceAsStream(filePath);} }

第二步:解析配置文件

import com.jinke.mybatis.cfg.Configuration; import com.jinke.mybatis.sqlsession.defaults.DefaultSqlSessionFactory; import com.jinke.mybatis.utils.XMLConfigBuilder;import java.io.InputStream;public class SqlSessionFactoryBuilder {public SqlSessionFactory build(InputStream config) {Configuration cfg = XMLConfigBuilder.loadConfiguration(config);return new DefaultSqlSessionFactory(cfg);} }

主要是通過反射將屬性值保存到map中

import com.jinke.mybatis.annotations.Select; import com.jinke.mybatis.cfg.Configuration; import com.jinke.mybatis.cfg.Mapper; import com.jinke.mybatis.io.Resources; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.List; import java.util.Map;public class XMLConfigBuilder {public static Configuration loadConfiguration(InputStream config) {Configuration cfg = new Configuration();try {SAXReader reader = new SAXReader();Document document = reader.read(config);Element root = document.getRootElement();List<Element> propertyElements = root.selectNodes("//property");for (Element propertyElement : propertyElements) {String name = propertyElement.attributeValue("name");if ("driver".equals(name)) {String driver = propertyElement.attributeValue("value");cfg.setDriver(driver);}if ("url".equals(name)) {String url = propertyElement.attributeValue("value");cfg.setUrl(url);}if ("username".equals(name)) {String username = propertyElement.attributeValue("value");cfg.setUsername(username);}if ("password".equals(name)) {String password = propertyElement.attributeValue("value");cfg.setPassword(password);}}List<Element> mapperElements = root.selectNodes("//mappers/mapper");for (Element mapperElement : mapperElements) {Attribute attribute = mapperElement.attribute("resource");if (attribute != null) {System.out.println("使用的是XML");String mapperPath = attribute.getValue();Map<String, Mapper> mappers = loadMapperConfiguration(mapperPath);cfg.setMappers(mappers);} else {System.out.println("使用的是注解");String daoClassPath = mapperElement.attributeValue("class");Map<String, Mapper> mappers = loadMapperAnnotation(daoClassPath);cfg.setMappers(mappers);}}return cfg;} catch (Exception e) {e.printStackTrace();} finally {try {config.close();} catch (IOException e) {e.printStackTrace();}}return cfg;}private static Map<String, Mapper> loadMapperConfiguration(String mapperPath) throws IOException {InputStream in = null;Map<String, Mapper> mappers = new HashMap<String, Mapper>();try {in = Resources.getResourceAsStream(mapperPath);SAXReader reader = new SAXReader();Document document = reader.read(in);Element root = document.getRootElement();String namespace = root.attributeValue("namespace");List<Element> selectElements = root.selectNodes("//select");for (Element selectElement : selectElements) {String id = selectElement.attributeValue("id");String resultType = selectElement.attributeValue("resultType");String queryString = selectElement.getText();String key = namespace + "." + id;Mapper mapper = new Mapper();mapper.setQueryString(queryString);mapper.setResultType(resultType);mappers.put(key, mapper);}return mappers;} catch (Exception e) {e.printStackTrace();}return mappers;}private static Map<String, Mapper> loadMapperAnnotation(String daoClassPath) throws Exception {Map<String, Mapper> mappers = new HashMap<String, Mapper>();Class daoClass = Class.forName(daoClassPath);Method[] methods = daoClass.getMethods();for (Method method : methods) {boolean isAnnotated = method.isAnnotationPresent(Select.class);if (isAnnotated) {Mapper mapper = new Mapper();Select selectAnno = method.getAnnotation(Select.class);String queryString = selectAnno.value();mapper.setQueryString(queryString);Type type = method.getGenericReturnType();if (type instanceof ParameterizedType) {ParameterizedType ptype = (ParameterizedType) type;Type[] types = ptype.getActualTypeArguments();Class domainClass = (Class) types[0];String resultType = domainClass.getName();mapper.setResultType(resultType);}String methodName = method.getName();String className = method.getDeclaringClass().getName();String key = className + "." + methodName;mappers.put(key, mapper);}}return mappers;} }

第三步:DefaultSqlSessionFactory工廠生產出DefaultSqlSession對象

import com.jinke.mybatis.cfg.Configuration; import com.jinke.mybatis.sqlsession.SqlSession; import com.jinke.mybatis.sqlsession.SqlSessionFactory;public class DefaultSqlSessionFactory implements SqlSessionFactory {private Configuration cfg;public DefaultSqlSessionFactory(Configuration cfg) {this.cfg = cfg;}public SqlSession openSession() {return new DefaultSqlSession(cfg);} }

第四步:DefaultSqlSession執行動態代理

import com.jinke.mybatis.cfg.Configuration; import com.jinke.mybatis.sqlsession.SqlSession; import com.jinke.mybatis.sqlsession.proxy.MapperProxy; import com.jinke.mybatis.utils.DataSourceUtil;import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException;public class DefaultSqlSession implements SqlSession {private Configuration cfg;private Connection connection;public DefaultSqlSession(Configuration cfg) {this.cfg = cfg;this.connection = DataSourceUtil.getConnection(cfg);}public <T> T getMapper(Class<T> daoInterfaceClass) {return (T) Proxy.newProxyInstance(daoInterfaceClass.getClassLoader(), new Class[]{daoInterfaceClass}, new MapperProxy(cfg.getMappers(), connection));}public void close() {if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}} }

執行sql語句

import com.jinke.mybatis.cfg.Mapper; import com.jinke.mybatis.utils.Executor;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.sql.Connection; import java.util.Map;public class MapperProxy implements InvocationHandler {private Map<String, Mapper> mappers;private Connection connection;public MapperProxy(Map<String, Mapper> mappers, Connection connection) {this.mappers = mappers;this.connection = connection;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String methodName = method.getName();String className = method.getDeclaringClass().getName();String key = className + "." + methodName;Mapper mapper = mappers.get(key);if (mapper == null) {throw new IllegalArgumentException("傳入的參數有誤");}return new Executor().selectList(mapper, connection);} } import com.jinke.mybatis.cfg.Mapper;import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.sql.*; import java.util.ArrayList; import java.util.List;public class Executor {public <E> List<E> selectList(Mapper mapper, Connection conn) {PreparedStatement pstm = null;ResultSet rs = null;try {String queryString = mapper.getQueryString();String resultType = mapper.getResultType();Class domainClass = Class.forName(resultType);pstm = conn.prepareStatement(queryString);rs = pstm.executeQuery();List<E> list = new ArrayList<E>();while (rs.next()) {E obj = (E) domainClass.newInstance();ResultSetMetaData rsmd = rs.getMetaData();int columnCount = rsmd.getColumnCount();for (int i = 1; i < columnCount; i++) {String columnName = rsmd.getColumnName(i);Object columnValue = rs.getObject(columnName);PropertyDescriptor pd = new PropertyDescriptor(columnName, domainClass);Method writeMethod = pd.getWriteMethod();writeMethod.invoke(obj, columnValue);}list.add(obj);}return list;} catch (Exception e) {e.printStackTrace();} finally {release(pstm, rs);}return null;}private void release(PreparedStatement pstm, ResultSet rs) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (pstm != null) {try {pstm.close();} catch (SQLException e) {e.printStackTrace();}}} }

最后放一張文件結構圖

代碼地址?https://github.com/king1039/MyBatis

歡迎關注我的微信公眾號:安卓圈

轉載于:https://www.cnblogs.com/anni-qianqian/p/11103040.html

總結

以上是生活随笔為你收集整理的自定义MyBatis的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。