借鉴:https://blog.youkuaiyun.com/weixin_49267169/article/details/127348722
https://blog.youkuaiyun.com/xxxzzzqqq_/article/details/130258855
https://blog.youkuaiyun.com/weixin_32128491/article/details/125602941
一:Mybatis的执行流程
1.读取Mybatis的全局配置文件Mybatis-Config.xml :运行环境(数据库连接的参数等)
2.加载映射文件Mapper.xml
3.构建会话工厂SqlSessionFactory
4.构建一个Sqlsession对象
5.Executor执行器,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护
6.Mapped Statement对象,mapper.xml 的一个Sql语句对应Mapped statement的一个对象,mapper.xml中的id与mapped statement中的id对应起来;
7.输出结果
二:sql生成原理
@Mapper
public interface UserMapper {
UserEntity getById(Long id);
}
1.实现类SqlSessionTemplate调用sqlSession接口的getMapper方法sqlSession.getMapper(RoleMapper.class)。
2.调Configuration类的getMapper(),调MapperRegistry的getMapper()方法返回MapperProxyFactory
2.MapperProxyFactory工厂创建代理对象 mapperProxyFactory.newInstance(sqlSession)返回MapperProxy代理类
3.创建的mapperProxy实现了InvocationHandler接口,invoke方法中对代理对象接口方法的调用进行了增强。通过invoke方法去执行sql操作mapperMethod.execute(sqlSession, args)。
SqlSession接口的实现类SqlSessionTemplate的getMapper()方法中调用了Configuration类中的getMapper()方法
try(InputStream in = Resources.getResourceAsStream("com/myboy/demo/sqlsession/mybatis-config.xml")){
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
# 拿到代理类对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
# 执行方法
UserEntity userEntity = mapper.getById(2L);
System.out.println(userEntity);
sqlSession.close();
}catch (Exception e){
e.printStackTrace();
}
Configuration 类的getMapper()方法
public class Configuration {
.......
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}
}
MapperRegistry 类的getMapper()方法:
public class MapperRegistry {
.........
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
MapperProxyFactory类的newInstance()方法:
public class MapperProxyFactory<T> {
......
public T newInstance(SqlSession sqlSession) {
MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
return this.newInstance(mapperProxy);
}
}
MapperProxy的invoke()方法:
public class MapperProxy<T> implements InvocationHandler, Serializable {
private static final long serialVersionUID = -4724728412955527868L;
........
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
}