mybatis 源码解析,mybatis 数据源

  mybatis 源码解析,mybatis 数据源

  00-1010前言jdbc思考传统JDBC源代码分析和数据源总结的弊端

  00-1010上述MyBatis部署运行并根据官网运行一个demo:一步部署运行MyBatis3源代码保姆级。

  00-1010张贴JDBC操作的另一种测试方法。流程是:

  加载JDBC驱动程序;获取数据库连接;创建JDBC报表对象;设置SQL语句的传入参数;执行SQL语句并获得查询结果;转换查询结果并返回处理结果;释放相关资源(关闭连接、关闭语句、关闭结果集);@ Test public void JDBC Test(){ String driver= com . MySQL . CJ . JDBC . driver ;string URL= JDBC : my SQL ://localhost :3306/news?character encoding=utf 8 server time zone=Asia/Shanghai use SSL=false allowpublickeyretrieval=true ;字符串user= rootString pwd= root123456Connection connection=null结果集rs=nullPreparedStatement stmt=null尝试{ class . forname(driver);//Get数据库连接connection=driver manager . Get connection(URL,user,pwd);字符串SQL= select * from t _ level where name=?;//创建一个语句对象(每条语句都是一个数据库执行请求)stmt=connection . prepare Statement(SQL);//设置传入参数stmt.setString(1,张三);//执行SQL语句RS=stmt . Execute query(SQL);resultset metaData metaData=RS . get metaData();//处理查询结果——这里什么都不做。int column count=metadata . get column count();system . out . println(column count);} catch(Exception e){ e . printstacktrace();}最后{try{ //关闭结果集if(rs!=null){ RS . close();rs=null}//如果(stmt!=null){ stmt . close();stmt=null}如果(连接!=null){ connection . close();connection=null} } catch(SQLException e){ e . printstacktrace();} } }

  

目录
JDBC底层不使用连接池,需要频繁创建和关闭连接来操作数据库,消耗大量资源;最初的JDBC代码是用Java编写的。一旦SQL需要修改,Java需要整体编译,不利于系统维护。如果PreparedStatement是预编译的,则变量设置为数字,如1、2、3等。而且这样的序列号不利于维护;result返回的结果集也需要硬编码。

  00-1010对比上面的JDBC测试案例和mybatis测试案例,你能发现什么共同点?

  点?

  

 @Test public void test() throws IOException { InputStream input = Resources.getResourceAsStream("SqlSessionConfig.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(input); SqlSession sqlSession = sessionFactory.openSession(); LevelDao dao = sqlSession.getMapper(LevelDao.class); List<Level> all = dao.findAll(); }
首先他们都要有数据源,这是毋庸置疑的。其次还要有执行sql语句,再有就是执行操作。

  

  

源码分析

接下来进入到源码分析阶段。

  由于我们是根据官网 Building SqlSessionFactory from XML的方式来测试demo的,接下来我们的解析就按照XML文件配置形式来讲解。

  

  

获取数据源

数据源4大元素包括:驱动、 url、 用户名、 密码。

  在看代码之前,先看一下我们的配置文件结构。

  

  mybatis是什么时候获取到数据源的呢?要从测试方法生成SqlSessionFactory说起。

  通过断点进入到SqlSessionFactoryBuilderbuild方法中,方法体就两行关键代码,首先new了一个XML 配置生成器,接着调用了其parse()生成一个Configuration对象。

  

 public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { } } } public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
parse方法执行了下面这条语句:

  

parseConfiguration(parser.evalNode("/configuration"));
parser.evalNode会生成一个mybatis封装的XNode对象,copy后发现就是我们配置文件中<configuration>标签中的内容。

  

  

  进入到parseConfiguration方法中,可以看出好多方法的字符串参数都和我们<configuration>标签中的一些标签名称相同。没错,每一步都是去扫描到对应参数的标签内容从而进行一些配置处理。

  

 private void parseConfiguration(XNode root) { try { //issue #117 read properties first propertiesElement(root.evalNode("properties")); Properties settings = settingsAsProperties(root.evalNode("settings")); loadCustomVfs(settings); loadCustomLogImpl(settings); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); reflectorFactoryElement(root.evalNode("reflectorFactory")); settingsElement(settings); // read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments")); databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } }
我们此处不研究其他处内容,直接看environmentsElement方法的内容。root.evalNode("environments")返回的XNode对象的value就是我们的environments标签内容。

  

  

  进入到environmentsElement方法中,会循环遍历下一级的environment,此处便是解析xml配置多数据源的地方。

  

 private void environmentsElement(XNode context) throws Exception { if (context != null) { if (environment == null) { environment = context.getStringAttribute("default"); } //xml配置多数据源 for (XNode child : context.getChildren()) { String id = child.getStringAttribute("id"); if (isSpecifiedEnvironment(id)) { TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager")); //<dataSource></dataSource> DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource")); //获得到数据库源 DataSource dataSource = dsFactory.getDataSource(); Environment.Builder environmentBuilder = new Environment.Builder(id) .transactionFactory(txFactory) .dataSource(dataSource); configuration.setEnvironment(environmentBuilder.build()); } } } }
dataSourceElement方法会拿到dataSource标签的内容生成一个DataSourceFactory ,并根据我们的配置给其属性赋值。

  通过getDataSource()方法便可以拿到我们的数据源。

  最后调用configuration.setEnvironment给到全局配置中的。

  执行流程图如下:

  

  

  

总结

到此这篇关于MyBatis3源码解析之如何获取数据源的文章就介绍到这了,更多相关MyBatis3获取数据源内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: