<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的家園

    我的家園

    1. 準備工作

    ? 編寫測試代碼(具體請參考《Mybatis入門示例》),設置斷點,Debug模式運行,具體代碼如下:?

    String resource = "mybatis.cfg.xml";
    
    Reader reader = Resources.getResourceAsReader(resource);
    
    SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
    
    SqlSession session = ssf.openSession();
    

    ???

    2.源碼分析

    我們此次就對上面的代碼進行跟蹤和分析,let's go。

    首先我們按照順序先看看第一行和第二行代碼,看看它主要完成什么事情:

    String resource = "mybatis.cfg.xml";
    
    Reader reader = Resources.getResourceAsReader(resource);

    ????

    讀取Mybaits的主配置配置文件,并返回該文件的輸入流,我們知道Mybatis所有的SQL語句都寫在XML配置文件里面,所以第一步就需要讀取這些XML配置文件,這個不難理解,關鍵是讀取文件后怎么存放。

    ?

    我們接著看第三行代碼(如下),該代碼主要是讀取配置文件流并將這些配置信息存放到Configuration類中。

    SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);

    ?

    ????

    SqlSessionFactoryBuilderbuild的方法如下:

    public SqlSessionFactory build(Reader reader) {
        return build(reader, null, null);
      }

    ??

    其實是調用該類的另一個build方法來執行的,具體代碼如下:

    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) {
    
            // Intentionally ignore. Prefer previous error.
    
          }
    
        }
    
      }

    ??

    我們重點看一下里面兩行:

    //創建一個配置文件流的解析對象XMLConfigBuilder,其實這里是將環境和配置文件流賦予解析類
    XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
    
    // 解析類對配置文件進行解析并將解析的內容存放到Configuration對象中,并返回SqlSessionFactory
    return build(parser.parse());

    ??

    這里的XMLConfigBuilder初始化其實調用的代碼如下:?

    private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        super(new Configuration());
    
        ErrorContext.instance().resource("SQL Mapper Configuration");
    
        this.configuration.setVariables(props);
    
        this.parsed = false;
    
        this.environment = environment;
    
        this.parser = parser; 
    
      }

    ?

    ?

    ?XMLConfigBuilderparse方法執行代碼如下:??

    public Configuration parse() {
    
        if (parsed) {
    
          throw new BuilderException("Each MapperConfigParser can only be used once.");
    
        }
    
        parsed = true;
    
        parseConfiguration(parser.evalNode("/configuration"));
    
        return configuration;
    
      }

    ?

    解析的內容主要是在parseConfiguration方法中,它主要完成的工作是讀取配置文件的各個節點,然后將這些數據映射到內存配置對象Configuration,我們看一下parseConfiguration方法內容:?

    private void parseConfiguration(XNode root) {
    
        try {
    
          typeAliasesElement(root.evalNode("typeAliases"));
    
          pluginElement(root.evalNode("plugins"));
    
          objectFactoryElement(root.evalNode("objectFactory"));
    
          objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
    
          propertiesElement(root.evalNode("properties"));
    
          settingsElement(root.evalNode("settings"));
    
          environmentsElement(root.evalNode("environments"));
    
          typeHandlerElement(root.evalNode("typeHandlers"));
    
          mapperElement(root.evalNode("mappers"));
    
        } catch (Exception e) {
    
          throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    
        }
    
      }

    最后的build方法其實是傳入配置對象進去,創建DefaultSqlSessionFactory實例出來. DefaultSqlSessionFactorySqlSessionFactory的默認實現.?
    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }

    ???

    ?最后我們看一下第四行代碼:?

    SqlSession session = ssf.openSession();

    ?

    通過調用DefaultSqlSessionFactoryopenSession方法返回一個SqlSession實例,我們看一下具體是怎么得到一個SqlSession實例的。首先調用openSessionFromDataSource方法。??

    public SqlSession openSession() {
        return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
    }

    ?

    ?下面我們看一下openSessionFromDataSource方法的邏輯:??

    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Connection connection = null;
    
    try {
    
    //獲取配置信息里面的環境信息,這些環境信息都是包括使用哪種數據庫,連接數據庫的信息,事務
    final Environment environment = configuration.getEnvironment();
    
    //根據環境信息關于數據庫的配置獲取數據源
    final DataSource dataSource = getDataSourceFromEnvironment(environment);
    
    //根據環境信息關于事務的配置獲取事務工廠
    TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    
          connection = dataSource.getConnection();
    
          if (level != null) {
    
            //設置連接的事務隔離級別
          connection.setTransactionIsolation(level.getLevel());
          }
    
          //對connection進行包裝,使連接具備日志功能,這里用的是代理。
          connection = wrapConnection(connection);
    
          //從事務工廠獲取一個事務實例
          Transaction tx = transactionFactory.newTransaction(connection, autoCommit);
    
          //從配置信息中獲取一個執行器實例
          Executor executor = configuration.newExecutor(tx, execType);
    
          //返回SqlSession的一個默認實例
          return new DefaultSqlSession(configuration, executor, autoCommit);
    
        } catch (Exception e) {
    
          closeConnection(connection);
    
          throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    
        } finally {
    
          ErrorContext.instance().reset();
    
        }
    
      }

    ?

    傳入參數說明:

    1ExecutorType:執行類型,ExecutorType主要有三種類型:SIMPLE, REUSE, BATCH,默認是SIMPLE,都在枚舉類ExecutorType里面。

    2TransactionIsolationLevel:事務隔離級別,都在枚舉類TransactionIsolationLevel中定義

    3autoCommit:是否自動提交,主要是事務提交的設置。

    ?

    ?DefaultSqlSessionSqlSession的實現類,該類主要提供操作數據庫的方法給開發人員使用。

    ??

    這里總結一下上面的過程,總共由三個步驟:

    步驟一:讀取Ibatis的主配置文件,并將文件讀成文件流形式(InputStream)

    ?

    步驟二:從主配置文件流中讀取文件的各個節點信息并存放到Configuration對象中。讀取mappers節點的引用文件,并將這些文件的各個節點信息存放到Configuration對象。

    ?

    步驟三:根據Configuration對象的信息獲取數據庫連接,并設置連接的事務隔離級別等信息,將經過包裝數據庫連接對象SqlSession接口返回,DefaultSqlSessionSqlSession的實現類,所以這里返回的是DefaultSqlSessionSqlSession接口里面就是對外提供的各種數據庫操作。






    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 99久热只有精品视频免费看| 一级人做人爰a全过程免费视频| 91精品免费高清在线| 国产亚洲美日韩AV中文字幕无码成人 | 5g影院5g天天爽永久免费影院| 亚洲五月综合缴情在线观看| 中文字幕成人免费高清在线视频| 国产亚洲精久久久久久无码77777 国产亚洲精品成人AA片新蒲金 | 一区二区三区在线观看免费| 久久久久亚洲精品天堂久久久久久| 成人a毛片视频免费看| 亚洲成AV人在线观看网址| 一级毛片大全免费播放下载| 国产亚洲大尺度无码无码专线| 国产羞羞的视频在线观看免费| 亚洲VA中文字幕不卡无码| 免费不卡在线观看AV| 亚洲一区二区三区免费观看| 免费毛片网站在线观看| 思思久久99热免费精品6| 亚洲国产精品无码久久一线| 色猫咪免费人成网站在线观看 | 夜色阁亚洲一区二区三区| 99re6在线视频精品免费| 亚洲码一区二区三区| 国产成人免费片在线视频观看| 一级成人a做片免费| 亚洲人成在线观看| 女人18毛片a级毛片免费视频| 日日狠狠久久偷偷色综合免费| 亚洲AV无码一区东京热久久 | 亚洲成av人影院| 毛片免费观看视频| 一级人做人a爰免费视频| 亚洲第一网站免费视频| 免费一级毛片在线播放| 久久99精品视免费看| 亚洲国产精品网站在线播放| 亚洲日韩国产成网在线观看| 1000部拍拍拍18勿入免费视频软件| 男男gay做爽爽免费视频|