文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MyBatis3源码解析之怎么获取数据源

2023-07-02 13:01

关注

这篇文章主要讲解了“MyBatis3源码解析之怎么获取数据源”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MyBatis3源码解析之怎么获取数据源”吧!

jdbc

再贴一个JDBC运行的测试方法,流程为:

    @Test    public void jdbcTest(){        String driver = "com.mysql.cj.jdbc.Driver";        String url = "jdbc:mysql://localhost:3306/news?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true";        String user = "root";        String pwd = "root123456";        Connection connection=null;        ResultSet rs=null;        PreparedStatement stmt=null;        try {            Class.forName(driver);            //获取数据库连接            connection = DriverManager.getConnection(url,user,pwd);            String sql = "select * from t_level where name=?";            //创建Statement对象(每一个Statement为一次数据库执行请求)            stmt=connection.prepareStatement(sql);            //设置传入参数            stmt.setString(1,"zhangsan");            //执行SQL语句            rs = stmt.executeQuery(sql);            ResultSetMetaData metaData =rs.getMetaData();            //处理查询结果-----此处未做操作            int columnCount= metaData.getColumnCount();            System.out.println(columnCount);        } catch (Exception e) {            e.printStackTrace();        }finally {            try{                //关闭结果集                if(rs!=null){                    rs.close();                    rs=null;                }                //关闭执行                if(stmt!=null){                    stmt.close();                    stmt=null;                }                if(connection!=null){                    connection.close();                    connection=null;                }            }catch(SQLException e){                e.printStackTrace();            }        }    }

传统JDBC弊端

思考

拿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、 用户名、 密码。

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

MyBatis3源码解析之怎么获取数据源

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>标签中的内容。

MyBatis3源码解析之怎么获取数据源

MyBatis3源码解析之怎么获取数据源

进入到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标签内容。

MyBatis3源码解析之怎么获取数据源

MyBatis3源码解析之怎么获取数据源

进入到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源码解析之怎么获取数据源”的内容了,经过本文的学习后,相信大家对MyBatis3源码解析之怎么获取数据源这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯