最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis3源碼解析之如何獲取數(shù)據(jù)源詳解

 更新時間:2022年06月26日 09:23:56   作者:張國榮南京分榮  
用myBatis3與spring整合的時候,我們可以通過多種方式獲取數(shù)據(jù)源,下面這篇文章主要給大家介紹了關(guān)于MyBatis3源碼解析之如何獲取數(shù)據(jù)源的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

上文講的MyBatis部署運行且根據(jù)官網(wǎng)運行了一個demo:一步到位部署運行MyBatis3源碼<保姆級>

jdbc

再貼一個JDBC運行的測試方法,流程為:

  • 加載JDBC驅(qū)動;
  • 獲取數(shù)據(jù)庫連接;
  • 創(chuàng)建JDBC Statements對象;
  • 設(shè)置SQL語句的傳入?yún)?shù);
  • 執(zhí)行SQL語句并獲得查詢結(jié)果;
  • 對查詢結(jié)果進(jìn)行轉(zhuǎn)換處理并將處理結(jié)果返回;
  • 釋放相關(guān)資源(關(guān)閉Connection,關(guān)閉Statement,關(guān)閉ResultSet);
    @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);
            //獲取數(shù)據(jù)庫連接
            connection = DriverManager.getConnection(url,user,pwd);
            String sql = "select * from t_level where name=?";
            //創(chuàng)建Statement對象(每一個Statement為一次數(shù)據(jù)庫執(zhí)行請求)
            stmt=connection.prepareStatement(sql);
            //設(shè)置傳入?yún)?shù)
            stmt.setString(1,"zhangsan");
            //執(zhí)行SQL語句
            rs = stmt.executeQuery(sql);
            ResultSetMetaData metaData =rs.getMetaData();
            //處理查詢結(jié)果-----此處未做操作
            int columnCount= metaData.getColumnCount();
            System.out.println(columnCount);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try{
                //關(guān)閉結(jié)果集
                if(rs!=null){
                    rs.close();
                    rs=null;
                }
                //關(guān)閉執(zhí)行
                if(stmt!=null){
                    stmt.close();
                    stmt=null;
                }
                if(connection!=null){
                    connection.close();
                    connection=null;
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }

傳統(tǒng)JDBC弊端

  • JDBC 底層沒有用連接池,操作數(shù)據(jù)庫需要頻繁的創(chuàng)建和關(guān)閉連接,消耗很大的資源;
  • 原生的 JDBC 代碼在 Java 中,一旦需要修改 SQL,Java 需要整體編譯,不利于系統(tǒng)維護(hù);
  • 使用 PreparedStatement 預(yù)編譯的話,對變量進(jìn)行設(shè)置 1、2、3 等數(shù)字,這樣的序號不利于維護(hù);
  • 返回 result 結(jié)果集也需要硬編碼。

思考

拿JDBC測試用例和上文mybatis的測試用例對比,可以發(fā)現(xiàn)哪些些共同點?

    @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();
    }

首先他們都要有數(shù)據(jù)源,這是毋庸置疑的。其次還要有執(zhí)行sql語句,再有就是執(zhí)行操作。

源碼分析

接下來進(jìn)入到源碼分析階段。

由于我們是根據(jù)官網(wǎng) Building SqlSessionFactory from XML的方式來測試demo的,接下來我們的解析就按照XML文件配置形式來講解。

獲取數(shù)據(jù)源

數(shù)據(jù)源4大元素包括:驅(qū)動、 url、 用戶名、 密碼。

在看代碼之前,先看一下我們的配置文件結(jié)構(gòu)。

mybatis是什么時候獲取到數(shù)據(jù)源的呢?要從測試方法生成SqlSessionFactory說起。

通過斷點進(jìn)入到SqlSessionFactoryBuilderbuild方法中,方法體就兩行關(guān)鍵代碼,首先new了一個XML 配置生成器,接著調(diào)用了其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方法執(zhí)行了下面這條語句:

parseConfiguration(parser.evalNode("/configuration"));

parser.evalNode會生成一個mybatis封裝的XNode對象,copy后發(fā)現(xiàn)就是我們配置文件中<configuration>標(biāo)簽中的內(nèi)容。

進(jìn)入到parseConfiguration方法中,可以看出好多方法的字符串參數(shù)都和我們<configuration>標(biāo)簽中的一些標(biāo)簽名稱相同。沒錯,每一步都是去掃描到對應(yīng)參數(shù)的標(biāo)簽內(nèi)容從而進(jìn)行一些配置處理。

  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);
    }
  }

我們此處不研究其他處內(nèi)容,直接看environmentsElement方法的內(nèi)容。root.evalNode("environments")返回的XNode對象的value就是我們的environments標(biāo)簽內(nèi)容。

進(jìn)入到environmentsElement方法中,會循環(huán)遍歷下一級的environment,此處便是解析xml配置多數(shù)據(jù)源的地方。

  private void environmentsElement(XNode context) throws Exception {
    if (context != null) {
      if (environment == null) {
        environment = context.getStringAttribute("default");
      }
      //xml配置多數(shù)據(jù)源
      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"));
          //獲得到數(shù)據(jù)庫源
          DataSource dataSource = dsFactory.getDataSource();
          Environment.Builder environmentBuilder = new Environment.Builder(id)
              .transactionFactory(txFactory)
              .dataSource(dataSource);
          configuration.setEnvironment(environmentBuilder.build());
        }
      }
    }
  }

dataSourceElement方法會拿到dataSource標(biāo)簽的內(nèi)容生成一個DataSourceFactory ,并根據(jù)我們的配置給其屬性賦值。

通過getDataSource()方法便可以拿到我們的數(shù)據(jù)源。

最后調(diào)用configuration.setEnvironment給到全局配置中的。

執(zhí)行流程圖如下:

總結(jié)

到此這篇關(guān)于MyBatis3源碼解析之如何獲取數(shù)據(jù)源的文章就介紹到這了,更多相關(guān)MyBatis3獲取數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java多線程處理文件的示例詳解

    Java多線程處理文件的示例詳解

    在Java編程中,文件處理是一項常見的任務(wù),為了提高文件處理的效率,我們可以使用多線程技術(shù),本文將詳細(xì)介紹如何使用Java多線程來處理文件,需要的可以參考下
    2024-12-12
  • SpringBoot基于AbstractRoutingDataSource實現(xiàn)多數(shù)據(jù)源動態(tài)切換

    SpringBoot基于AbstractRoutingDataSource實現(xiàn)多數(shù)據(jù)源動態(tài)切換

    本文主要介紹了SpringBoot基于AbstractRoutingDataSource實現(xiàn)多數(shù)據(jù)源動態(tài)切換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 導(dǎo)入renren-fast出現(xiàn)問題以及解決方案

    導(dǎo)入renren-fast出現(xiàn)問題以及解決方案

    文章介紹了在導(dǎo)入renren-fast項目時遇到的maven繼承parent問題,并提供了解決方案,即在pom文件中添加``標(biāo)簽,此外,還詳細(xì)解釋了Maven的``標(biāo)簽的作用以及MAVEN構(gòu)建jar包時的查找順序
    2024-11-11
  • TKMybatis的介紹和使用詳解

    TKMybatis的介紹和使用詳解

    TKMybatis 是基于 Mybatis 框架開發(fā)的一個工具,本文主要介紹了TKMybatis的介紹和使用詳解,內(nèi)部實現(xiàn)了對單表的基本數(shù)據(jù)操作,只需要簡單繼承 TKMybatis 提供的接口,就能夠?qū)崿F(xiàn)無需編寫任何 sql 即能完成單表操作,感興趣的可以了解一下
    2021-12-12
  • idea版本控制忽略.idea文件和.iml文件的問題

    idea版本控制忽略.idea文件和.iml文件的問題

    這篇文章主要介紹了idea版本控制忽略.idea文件和.iml文件,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • jar包的各種啟動方式超詳細(xì)總結(jié)

    jar包的各種啟動方式超詳細(xì)總結(jié)

    jar文件是一種軟件包文件格式,通常用于聚合大量的JAVA類文件,以jar為文件擴(kuò)展名,下面這篇文章主要給大家介紹了關(guān)于jar包的各種啟動方式,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • Mybatis實現(xiàn)一對多映射處理

    Mybatis實現(xiàn)一對多映射處理

    MyBatis是一種流行的Java持久化框架,這篇文章主要為大家介紹了Mybatis如何實現(xiàn)一對多映射處理,文中的示例代碼講解詳細(xì),需要的可以參考下
    2023-08-08
  • Maven導(dǎo)入本地jar包的實現(xiàn)步驟

    Maven導(dǎo)入本地jar包的實現(xiàn)步驟

    本文主要介紹了Maven導(dǎo)入本地jar包的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • SpringBoot靜態(tài)資源的訪問方法詳細(xì)介紹

    SpringBoot靜態(tài)資源的訪問方法詳細(xì)介紹

    最近在做SpringBoot項目的時候遇到了“白頁”問題,通過查資料對SpringBoot訪問靜態(tài)資源做了總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • springboot配置aop切面日志打印過程解析

    springboot配置aop切面日志打印過程解析

    這篇文章主要介紹了springboot配置aop切面日志打印過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01

最新評論

固阳县| 河津市| 德州市| 铅山县| 北京市| 德保县| 曲松县| 绥棱县| 仁怀市| 渭南市| 大城县| 武汉市| 石阡县| 忻城县| 越西县| 合阳县| 剑川县| 台北市| 长治县| 兴城市| 武乡县| 昌江| 新乡县| 栖霞市| 来凤县| 弥渡县| 普宁市| 获嘉县| 井陉县| 晴隆县| 铁力市| 中阳县| 于田县| 平果县| 彰化县| 安岳县| 连平县| 和龙市| 吉木萨尔县| 赫章县| 河西区|