如何深度理解mybatis?( 三 )


方法对应一个Mapper对象

如何深度理解mybatis?

文章插图
 
然后再根据结果类型, 判断是什么类型相关的操作,方便后期执行对应的sql语句
如何深度理解mybatis?

文章插图
 
四. 编写核心类SqlSessionFacotry 1.回顾那个地方创建的SqlSessionFacotry对象
经过SqlSessionFacotryBuilder的努力, 我们成功的将配置文件中核心的信息解析出来并放入了configuration对象中了, 然后我们此时将解析好的configuration传入到SqlSessionFacotry中
如何深度理解mybatis?

文章插图
 
SqlSessionFactory的实现类如下:
public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; private TransactionManagement defaultTransactionManagement; public DefaultSqlSessionFactory(Configuration configuration) { this.configuration =configuration; defaultTransactionManagement = new DefaultTransactionManagement(configuration.getDataSource()); } @Override public SqlSession openSession() { return new DefaultSqlSession(configuration,defaultTransactionManagement,false); } } 2.添加事务管理器
事务管理是一个小的功能, 里面希望使用ThreadLocal集合来保证一个用户拿到的链接是同一个
如何深度理解mybatis?

文章插图
 
事务管理的代码如下:
public class DefaultTransactionManagement implements TransactionManagement { private ThreadLocal threadLocal = new ThreadLocal<>(); private DataSource dataSource; public DefaultTransactionManagement(DataSource dataSource) { this.dataSource = dataSource; } public Connection getConnection() { Connection connection = threadLocal.get(); if (connection == null) { try { connection = dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } threadLocal.set(connection); } return connection; } @Override public void commit() { Connection connection = threadLocal.get(); if (connection != null ) { try { connection.commit(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void rollback() { Connection connection = threadLocal.get(); if (connection != null) { try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } } } public void close() { Connection connection = threadLocal.get(); if (connection != null) { try { connection.close(); threadLocal.remove(); } catch (SQLException e) { e.printStackTrace(); } } } @Override public void begin() { Connection connection = threadLocal.get(); if (connection != null) { try { connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } } } 五. 深度分析解析SqlSessionFacotry干的核心工作 1. SqlSession openSession() 方法做的工作
可以看的出来我们在这个方法创建了DefaultSqlSession对象,并传入封装好的configuration,默认的事务管理器
默认通过openSession事务是开启的等等相关的参数
如何深度理解mybatis?

文章插图
 
六.编写核心类SqlSession
其实有SqlSession的接口,我们使用的实现类是DefaultSession, 这里记录了解析的配置对象configuration
默认事务管理器对象transactionManagement, 默认事务开启的状态tx标记
package com.itheima.ibatis.core.session.impl; import com.itheima.ibatis.configuration.Configuration; import com.itheima.ibatis.configuration.Mapper; import com.itheima.ibatis.core.BaseExecutor; import com.itheima.ibatis.core.annotation.Param; import com.itheima.ibatis.core.session.SqlSession; import com.itheima.ibatis.core.transaction.TransactionManagement; import java.lang.reflect.*; import java.util.HashMap; import java.util.List; import java.util.Map; public class DefaultSqlSession implements SqlSession { private final Configuration configuration; private final boolean tx; private TransactionManagement transactionManagement; public DefaultSqlSession(Configuration configuration, TransactionManagement transactionManagement, boolean tx) { this.configuration = configuration; this.transactionManagement = transactionManagement; this.tx = tx; } public void close() { transactionManagement.close(); } @Override public void commit() { transactionManagement.commit(); } @Override public void rollback() { transactionManagement.rollback(); } @Override public List selectList(String sqlId) { return selectList(sqlId, null); } @Override public List selectList(String sqlId, Object param) { List list = new BaseExecutor(transactionManagement, tx).queryList(getMapper(sqlId), param); return (List) list; } @Override public T selectOne(String sqlId) { return selectOne(sqlId, null); } @Override public T selectOne(String sqlId, Object param) { return new BaseExecutor(transactionManagement, tx).query(getMapper(sqlId), param); } @Override public int delete(String sqlId) { return update0(sqlId, null); } @Override public int delete(String sqlId, Object param) { return update0(sqlId, param); } @Override public int update(String sqlId) { return update0(sqlId, null); } @Override public int update(String sqlId, Object param) { return update0(sqlId, param); } @Override public int insert(String sqlId) { return update0(sqlId, null); } @Override public int insert(String sqlId, Object param) { return update0(sqlId, param); } @Override public T getMapper(Class clazz) { Object o = Proxy.newProxyInstance( clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String sqlId = clazz.getName() + "." + method.getName(); Mapper mapper = configuration.getMappers().get(sqlId); String type = mapper.getType(); Object findParam = null; if (args != null) { if (args.length == 1) { Object param = args[0]; boolean isArray = param.getClass().isArray(); if (!isArray) { findParam = param; } } else { Map map = new HashMap<>(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { Param param = parameters[i].getAnnotation(Param.class); String key = "arg"+i; if(param !=null){ key = param.value(); } map.put(key, args[i]); } findParam = map; } } if (type.equals("SELECT")) { boolean selectList = mapper.isSelectList(); if (selectList) return selectList(sqlId, findParam); else return selectOne(sqlId, findParam); } else { return update0(sqlId, findParam); } } }); return (T) o; } private int update0(String sqlId, Object param) { return new BaseExecutor(transactionManagement, tx).update(getMapper(sqlId), param); } public Mapper getMapper(String sqlId) { Mapper mapper = configuration.getMappers().get(sqlId); if (mapper == null) { throw new RuntimeException("没有找到sql映射,请检查"); } return mapper; } }七.深度分析解析SqlSession干的核心工作1.selectOne & selectList做的工作


推荐阅读