什么是mybatis
MyBatis是一个优秀的持久层框架,支持自定义SQL、存储过程、高级映射。MyBatis省去了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解将原始类型、接口和JavaPOJO(PlainOldJavaObjects,PlainOldJavaObjects)配置映射为数据库中的记录。
mybatis初始化
Stringresource="mybatis-config.xml";
InputStreaminputStream=资源。getResourceAsStream(资源);
//创建SqlSessionFacory
SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactoryBuilder#build会初始化配置文件中的信息形成Configuration
看初始化代码
privatevoidparseConfiguration(XNoderoot){
尝试{
//issue#117首先读取属性
//初始化各种属性
propertiesElement(root.evalNode("properties"));
属性设置=settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(设置);
//初始化别名
typeAliasesElement(root.evalNode("typeAliases"));
//初始化各种拦截器
pluginElement(root.evalNode("插件"));
//初始化对象工厂objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
设置元素(设置);
//在objectFactory和objectWrapperFactory问题之后读取它#631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
//对象转换类,java类和数据库类型映射
typeHandlerElement(root.evalNode("typeHandlers"));
//xxxxMapper.xml文件
mapperElement(root.evalNode("mappers"));
}赶上(异常e){
thrownewBuilderException("解析SQL映射器配置时出错。原因:"+e,e);
}
}
mybatis在执行过程中的动态代理
mybatis的mapper没有实现类。这是如何实施的?让我们看看这里的SqlSession#getMapper。点击进入后,
publicTgetMapper(Classtype,SqlSessionsqlSession){finalMapperProxyFactorymapperProxyFactory=(MapperProxyFactory)knownMappers.get(类型);
如果(mapperProxyFactory==null){
thrownewBindingException("Type"+type+"不为MapperRegistry所知。");
}
尝试{
返回mapperProxyFactory.newInstance(sqlSession);
}赶上(异常e){
thrownewBindingException("获取映射器实例时出错。原因:"+e,e);
}
}
点击查看jdk的动态代理
protectedTnewInstance(MapperProxymapperProxy){
返回(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{mapperInterface},mapperProxy);
}
mybatis缓存
对于会话(Session)级别的数据缓存,我们称之为一级数据缓存,简称为一级缓存。
让我们看看BaseExecutor#query代码
@Override
publicListquery(MappedStatementms,Objectparameter,RowBoundsrowBounds,ResultHandlerresultHandler)throwsSQLException{
BoundSqlboundSql=ms.getBoundSql(参数);CacheKeykey=createCacheKey(ms,parameter,rowBounds,boundSql);
返回查询(ms,参数,rowBounds,resultHandler,键,boundSql);
}
@SuppressWarnings("未检查")
@覆盖
publicListquery(MappedStatementms,Objectparameter,RowBoundsrowBounds,ResultHandlerresultHandler,CacheKeykey,BoundSqlboundSql)throwsSQLException{
ErrorContext.instance().resource(ms.getResource()).activity("执行查询").object(ms.getId());
如果(关闭){
thrownewExecutorException("Executorwasclosed.");
}
如果(queryStack==0&&ms.isFlushCacheRequired()){
清除本地缓存();
}
列表列表;
尝试{
查询堆栈++;
列表=结果处理程序==空?(List)localCache.getObject(key):null;
如果(列表!=null){
handleLocallyCachedOutputParameters(ms,key,parameter,boundSql);
}别的{list=queryFromDatabase(ms,parameter,rowBounds,resultHandler,key,boundSql);
}
}最后{
查询堆栈--;
}
如果(queryStack==0){
对于(DeferredLoaddeferredLoad:deferredLoads){
deferredLoad.load();
}
//问题#601
deferredLoads.clear();
如果(configuration.getLocalCacheScope()==LocalCacheScope.STATEMENT){
//问题#482
清除本地缓存();
}
}
返回列表;}