首页 > 社交 > 科普中国

Mybatis源码学习

常驻编辑 科普中国 2022-12-04 都会   分布式   初始化   缓存   二级缓存   源码   接口   级别   对象   成本   类型   代码   环境   数据库   方法   数据   科技

什么是mybatis

MyBatis是一个优秀的持久层框架,支持自定义SQL、存储过程、高级映射。MyBatis省去了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解将原始类型、接口和JavaPOJO(PlainOldJavaObjects,PlainOldJavaObjects)配置映射为数据库中的记录。H7N拜客生活常识网

mybatis初始化

Stringresource="mybatis-config.xml";
InputStreaminputStream=资源。getResourceAsStream(资源);
//创建SqlSessionFacory
SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactoryBuilder#build会初始化配置文件中的信息形成ConfigurationH7N拜客生活常识网

看初始化代码H7N拜客生活常识网

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。点击进入后,H7N拜客生活常识网

publicTgetMapper(Classtype,SqlSessionsqlSession){finalMapperProxyFactorymapperProxyFactory=(MapperProxyFactory)knownMappers.get(类型);
如果(mapperProxyFactory==null){
thrownewBindingException("Type"+type+"不为MapperRegistry所知。");
}
尝试{
返回mapperProxyFactory.newInstance(sqlSession);
}赶上(异常e){
thrownewBindingException("获取映射器实例时出错。原因:"+e,e);
}
}

点击查看jdk的动态代理H7N拜客生活常识网

protectedTnewInstance(MapperProxymapperProxy){
返回(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{mapperInterface},mapperProxy);
}

mybatis缓存

对于会话(Session)级别的数据缓存,我们称之为一级数据缓存,简称为一级缓存。H7N拜客生活常识网

让我们看看BaseExecutor#query代码H7N拜客生活常识网

@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
清除本地缓存();
}
}
返回列表;}    

相关阅读:

  • 万用金多久到账(申请万用金一般都会通过吗)
  • 1969年属鸡的幸运数字,属鸡的幸运数字是多少
  • 鍏斿瓙鎭嬬埍鎵嬪唽,卯兔的最完整恋爱手册
  • 生肖兔:一生感情多磨难,属兔人情感坎坷
  • 难受孕的女性,身体都会有这四个信号,需要及时调理
  • 迪士尼是许多人向往的地方,它深受喜欢的理由是什么?
  • 孩子总被欺负,你会怎么做?国外教师:绕开霸凌者和他父母
  • 峰回路转:人生几何
  • 如何提高自己的为人处世能力?
  • 发脾气,是孩子发出的“求救”信号
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。