欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis配置文件解析與MyBatis實(shí)例演示

 更新時(shí)間:2022年04月07日 08:36:24   投稿:wdc  
這篇文章主要介紹了MyBatis配置文件解析與MyBatis實(shí)例演示以及怎樣編譯安裝MyBatis,需要的朋友可以參考下

MyBatis介紹

MyBatis是一個(gè)持久層的ORM框架,使用簡(jiǎn)單,學(xué)習(xí)成本較低??梢詧?zhí)行自己手寫(xiě)的SQL語(yǔ)句,比較靈活。但是MyBatis的自動(dòng)化程度不高,移植性也不高,有時(shí)從一個(gè)數(shù)據(jù)庫(kù)遷移到另外一個(gè)數(shù)據(jù)庫(kù)的時(shí)候需要自己修改配置,所以稱只為半自動(dòng)ORM框架

傳統(tǒng)JDBC和Mybatis相比的弊病

傳統(tǒng)JDBC

@Test
public  void test() throws SQLException {
    Connection conn=null;
    PreparedStatement pstmt=null;
    try {
        // 1.加載驅(qū)動(dòng)
        Class.forName("com.mysql.jdbc.Driver");

        // 2.創(chuàng)建連接
        conn= DriverManager.
                getConnection("jdbc:mysql://localhost:3306/mybatis_example", "root", "123456");


        // SQL語(yǔ)句
        String sql="select id,user_name,create_time from t_user where id=?";

        // 獲得sql執(zhí)行者
        pstmt=conn.prepareStatement(sql);
        pstmt.setInt(1,1);

        // 執(zhí)行查詢
        //ResultSet rs= pstmt.executeQuery();
        pstmt.execute();
        ResultSet rs= pstmt.getResultSet();

        rs.next();
        User user =new User();
        user.setId(rs.getLong("id"));
        user.setUserName(rs.getString("user_name"));
        user.setCreateTime(rs.getDate("create_time"));
        System.out.println(user.toString());
    } catch (Exception e) {
        e.printStackTrace();
    }
    finally{
        // 關(guān)閉資源
        try {
            if(conn!=null){
                conn.close();
            }
            if(pstmt!=null){
                pstmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

傳統(tǒng)JDBC的問(wèn)題如下:

1.數(shù)據(jù)庫(kù)連接創(chuàng)建,釋放頻繁造成西戎資源的浪費(fèi),從而影響系統(tǒng)性能,使用數(shù)據(jù)庫(kù)連接池可以解決問(wèn)題。
2.sql語(yǔ)句在代碼中硬編碼,造成代碼的不已維護(hù),實(shí)際應(yīng)用中sql的變化可能較大,sql代碼和java代碼沒(méi)有分離開(kāi)來(lái)維護(hù)不方便。
3.使用preparedStatement向有占位符傳遞參數(shù)存在硬編碼問(wèn)題因?yàn)閟ql中的where子句的條件不確定,同樣是修改不方便/
4.對(duì)結(jié)果集中解析存在硬編碼問(wèn)題,sql的變化導(dǎo)致解析代碼的變化,系統(tǒng)維護(hù)不方便。

mybatis對(duì)傳統(tǒng)的JDBC的解決方案

1、數(shù)據(jù)庫(kù)連接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫(kù)連接池可解決此問(wèn)題。
解決:在SqlMapConfig.xml中配置數(shù)據(jù)連接池,使用連接池管理數(shù)據(jù)庫(kù)鏈接。

2、Sql語(yǔ)句寫(xiě)在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。
解決:將Sql語(yǔ)句配置在XXXXmapper.xml文件中與java代碼分離。

3、向sql語(yǔ)句傳參數(shù)麻煩,因?yàn)閟ql語(yǔ)句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對(duì)應(yīng)。
解決:Mybatis自動(dòng)將java對(duì)象映射至sql語(yǔ)句,通過(guò)statement中的parameterType定義輸入?yún)?shù)的類型。

4、對(duì)結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫(kù)記錄封裝成pojo對(duì)象解析比較方便。
解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對(duì)象,通過(guò)statement中的resultType定義輸出結(jié)果的類型。

Mybaits整體體系圖

在這里插入圖片描述

 

在這里插入圖片描述

一個(gè)Mybatis最簡(jiǎn)單的使用例子如下:

public class App {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        Reader reader;
        try {
            //將XML配置文件構(gòu)建為Configuration配置類
            reader = Resources.getResourceAsReader(resource);
            // 通過(guò)加載配置文件流構(gòu)建一個(gè)SqlSessionFactory  DefaultSqlSessionFactory
            SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
            // 數(shù)據(jù)源 執(zhí)行器  DefaultSqlSession
            SqlSession session = sqlMapper.openSession();
            try {
                // 執(zhí)行查詢 底層執(zhí)行jdbc
                //User user = (User)session.selectOne("com.tuling.mapper.selectById", 1);

                UserMapper mapper = session.getMapper(UserMapper.class);
                System.out.println(mapper.getClass());
                User user = mapper.selectById(1L);
                System.out.println(user.getUserName());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                session.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--properties 掃描屬性文件.properties  -->
    <properties resource="db.properties"></properties>


    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

   <plugins>
       <plugin interceptor="com.tuling.plugins.ExamplePlugin" ></plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
           <transactionManager type="JDBC"/>
            <!--//  mybatis內(nèi)置了JNDI、POOLED、UNPOOLED三種類型的數(shù)據(jù)源,其中POOLED對(duì)應(yīng)的實(shí)現(xiàn)為org.apache.ibatis.datasource.pooled.PooledDataSource,它是mybatis自帶實(shí)現(xiàn)的一個(gè)同步、線程安全的數(shù)據(jù)庫(kù)連接池 一般在生產(chǎn)中,我們會(huì)使用c3p0或者druid連接池-->
            <dataSource type="POOLED">
            <property name="driver" value="${mysql.driverClass}"/>
            <property name="url" value="${mysql.jdbcUrl}"/>
            <property name="username" value="${mysql.user}"/>
            <property name="password" value="${mysql.password}"/>
        </dataSource>
        </environment>
    </environments>



    <mappers>
        <!--1.必須保證接口名(例如IUserDao)和xml名(IUserDao.xml)相同,還必須在同一個(gè)包中-->
        <package name="com.tuling.mapper"/>

        <!--2.不用保證同接口同包同名
         <mapper resource="com/mybatis/mappers/EmployeeMapper.xml"/>

        3.保證接口名(例如IUserDao)和xml名(IUserDao.xml)相同,還必須在同一個(gè)包中
        <mapper class="com.mybatis.dao.EmployeeMapper"/>

        4.不推薦:引用網(wǎng)路路徑或者磁盤路徑下的sql映射文件 file:///var/mappers/AuthorMapper.xml
         <mapper url="file:E:/Study/myeclipse/_03_Test/src/cn/sdut/pojo/PersonMapper.xml"/>-->

    </mappers>
</configuration>

總結(jié)下就是分為下面四個(gè)步驟:

  • 從配置文件(通常是XML文件)得到SessionFactory;
  • 從SessionFactory得到SqlSession;
  • 通過(guò)SqlSession進(jìn)行CRUD和事務(wù)的操作;
  • 執(zhí)行完相關(guān)操作之后關(guān)閉Session。

MyBatis 源碼編譯

1.下載mybatis源碼

下載地址:https://github.com/mybatis/mybatis-3

這里寫(xiě)圖片描述

我下載的最新的 mybatis-3-mybatis-3.4.6,下載完后解壓。打開(kāi)pom.xml

 <parent>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-parent</artifactId>
    <version>30</version>
    <relativePath />
  </parent>

發(fā)現(xiàn)mybatis源碼依賴mybatis-parent 所以編譯前要先下載mybatis-parent

2.下載mybatis-parent源碼

下載地址:https://github.com/mybatis/parent

這里寫(xiě)圖片描述

下載的mybatis-parent版本要和mybatis源文件pom.xml 版本一致。

3.編譯mybatis-parent源碼

切換到你下載的mybatis-parent目錄:

mvn clean install

3.編譯mybatis源碼

切換到你下載的mybatis源碼目錄:

mvn clean 

mvn install -Dmaven.test.skip=true

如果出現(xiàn)如下錯(cuò)誤:

這里寫(xiě)圖片描述

打開(kāi)pom.xml 文件注釋掉 maven-pdf-plugin 插件

  <!--
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pdf-plugin</artifactId>
      </plugin>
      -->

然后重新編譯

4.導(dǎo)入IDEA

導(dǎo)入方式就不多說(shuō),按maven項(xiàng)目導(dǎo)入即可!導(dǎo)入成功后:

這里寫(xiě)圖片描述

如果希望在spring源碼中引入你自己的這份源碼,可以做如下操作

1.修改你mybatis源碼的pom的 這樣可以和官方的區(qū)分開(kāi)來(lái)

<version>3.5.3-xsls</version>

2.這樣你在spring源碼中就可以引入這份mybatis源碼了.

  • 如果引入mybatis-spring 同樣需要做1、3步驟
compile("org.mybatis:mybatis-spring:2.0.3-xsls")  
compile("org.mybatis:mybatis:3.5.3-xsls")

3.當(dāng)然,如果你想在spring這邊看到你mybatis源碼相關(guān)的注釋,還得在mybatis源碼的pom里面加入plugin,使它生成 jar 的同時(shí) 生成 sources 包

<plugin>
  <artifactId>maven-source-plugin</artifactId>
  <version>3.0.1</version>
  <configuration>
    <attach>true</attach>
  </configuration>
  <executions>
    <execution>
      <phase>compile</phase>
      <goals>
        <goal>jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Mybatis啟動(dòng)流程分析

String resource = "mybatis-config.xml";
//將XML配置文件構(gòu)建為Configuration配置類
reader = Resources.getResourceAsReader(resource);
// 通過(guò)加載配置文件流構(gòu)建一個(gè)SqlSessionFactory  DefaultSqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);

通過(guò)上面代碼發(fā)現(xiàn),創(chuàng)建SqlSessionFactory的代碼在SqlSessionFactoryBuilder中,進(jìn)去一探究竟:

//整個(gè)過(guò)程就是將配置文件解析成Configration對(duì)象,然后創(chuàng)建SqlSessionFactory的過(guò)程
//Configuration是SqlSessionFactory的一個(gè)內(nèi)部屬性
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }
    
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

下面我們看下解析配置文件過(guò)程中的一些細(xì)節(jié)。
先給出一個(gè)配置文件的例子:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--SqlSessionFactoryBuilder中配置的配置文件的優(yōu)先級(jí)最高;config.properties配置文件的優(yōu)先級(jí)次之;properties標(biāo)簽中的配置優(yōu)先級(jí)最低 -->
    <properties resource="org/mybatis/example/config.properties">
      <property name="username" value="dev_user"/>
      <property name="password" value="F2Fa3!33TYyg"/>
    </properties>

    <!--一些重要的全局配置-->
    <settings>
    <setting name="cacheEnabled" value="true"/>
    <!--<setting name="lazyLoadingEnabled" value="true"/>-->
    <!--<setting name="multipleResultSetsEnabled" value="true"/>-->
    <!--<setting name="useColumnLabel" value="true"/>-->
    <!--<setting name="useGeneratedKeys" value="false"/>-->
    <!--<setting name="autoMappingBehavior" value="PARTIAL"/>-->
    <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>-->
    <!--<setting name="defaultExecutorType" value="SIMPLE"/>-->
    <!--<setting name="defaultStatementTimeout" value="25"/>-->
    <!--<setting name="defaultFetchSize" value="100"/>-->
    <!--<setting name="safeRowBoundsEnabled" value="false"/>-->
    <!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
    <!--<setting name="localCacheScope" value="STATEMENT"/>-->
    <!--<setting name="jdbcTypeForNull" value="OTHER"/>-->
    <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
    <!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
    </settings>

    <typeAliases>

    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--默認(rèn)值為 false,當(dāng)該參數(shù)設(shè)置為 true 時(shí),如果 pageSize=0 或者 RowBounds.limit = 0 就會(huì)查詢出全部的結(jié)果-->
            <!--如果某些查詢數(shù)據(jù)量非常大,不應(yīng)該允許查出所有數(shù)據(jù)-->
            <property name="pageSizeZero" value="true"/>
        </plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://10.59.97.10:3308/windty"/>
                <property name="username" value="windty_opr"/>
                <property name="password" value="windty!234"/>
            </dataSource>
        </environment>
    </environments>

    <databaseIdProvider type="DB_VENDOR">
        <property name="MySQL" value="mysql" />
        <property name="Oracle" value="oracle" />
    </databaseIdProvider>

    <mappers>
        <!--這邊可以使用package和resource兩種方式加載mapper-->
        <!--<package name="包名"/>-->
        <!--<mapper resource="./mappers/SysUserMapper.xml"/>-->
        <mapper resource="./mappers/CbondissuerMapper.xml"/>
    </mappers>

</configuration>

下面是解析配置文件的核心方法:

private void parseConfiguration(XNode root) {
    try {
      //issue #117 read properties first
      //解析properties標(biāo)簽,并set到Configration對(duì)象中
      //在properties配置屬性后,在Mybatis的配置文件中就可以使用${key}的形式使用了。
      propertiesElement(root.evalNode("properties"));
      
      //解析setting標(biāo)簽的配置
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      //添加vfs的自定義實(shí)現(xiàn),這個(gè)功能不怎么用
      loadCustomVfs(settings);
        
      //配置類的別名,配置后就可以用別名來(lái)替代全限定名
      //mybatis默認(rèn)設(shè)置了很多別名,參考附錄部分
      typeAliasesElement(root.evalNode("typeAliases"));
        
      //解析攔截器和攔截器的屬性,set到Configration的interceptorChain中
      //MyBatis 允許你在已映射語(yǔ)句執(zhí)行過(guò)程中的某一點(diǎn)進(jìn)行攔截調(diào)用。默認(rèn)情況下,MyBatis 允許使用插件來(lái)攔截的方法調(diào)用包括:
      //Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
        //ParameterHandler (getParameterObject, setParameters)
        //ResultSetHandler (handleResultSets, handleOutputParameters)
        //StatementHandler (prepare, parameterize, batch, update, query)
      pluginElement(root.evalNode("plugins"));
      
      //Mybatis創(chuàng)建對(duì)象是會(huì)使用objectFactory來(lái)創(chuàng)建對(duì)象,一般情況下不會(huì)自己配置這個(gè)objectFactory,使用系統(tǒng)默認(rèn)的objectFactory就好了
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
       
      //設(shè)置在setting標(biāo)簽中配置的配置
      settingsElement(settings);
   
      //解析環(huán)境信息,包括事物管理器和數(shù)據(jù)源,SqlSessionFactoryBuilder在解析時(shí)需要指定環(huán)境id,如果不指定的話,會(huì)選擇默認(rèn)的環(huán)境;
      //最后將這些信息set到Configration的Environment屬性里面
      environmentsElement(root.evalNode("environments"));
        
      //
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        
      //無(wú)論是 MyBatis 在預(yù)處理語(yǔ)句(PreparedStatement)中設(shè)置一個(gè)參數(shù)時(shí),還是從結(jié)果集中取出一個(gè)值時(shí), 都會(huì)用類型處理器將獲取的值以合適的方式轉(zhuǎn)換成 Java 類型。解析typeHandler。
      typeHandlerElement(root.evalNode("typeHandlers"));
      //解析Mapper
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
}

在這里插入圖片描述

上面解析流程結(jié)束后會(huì)生成一個(gè)Configration對(duì)象,包含所有配置信息,然后會(huì)創(chuàng)建一個(gè)SqlSessionFactory對(duì)象,這個(gè)對(duì)象包含了Configration對(duì)象。

簡(jiǎn)單總結(jié)

對(duì)于MyBatis啟動(dòng)的流程(獲取SqlSession的過(guò)程)這邊簡(jiǎn)單總結(jié)下:

  • SqlSessionFactoryBuilder解析配置文件,包括屬性配置、別名配置、攔截器配置、環(huán)境(數(shù)據(jù)源和事務(wù)管理器)、Mapper配置等;解析完這些配置后會(huì)生成一個(gè)Configration對(duì)象,這個(gè)對(duì)象中包含了MyBatis需要的所有配置,然后會(huì)用這個(gè)Configration對(duì)象創(chuàng)建一個(gè)SqlSessionFactory對(duì)象,這個(gè)對(duì)象中包含了Configration對(duì)象;

這里解析的東西比較多,大致概況:會(huì)把所有的信息都解析到Configration對(duì)象中,比較簡(jiǎn)單不多介紹。

更多關(guān)于MyBatis配置文件解析MyBatis實(shí)例演示以及怎樣編譯安裝MyBatis請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

  • SpringBoot集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息

    SpringBoot集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息

    在一次項(xiàng)目開(kāi)發(fā)中,使用到了Netty網(wǎng)絡(luò)應(yīng)用框架,以及MQTT進(jìn)行消息數(shù)據(jù)的收發(fā),這其中需要后臺(tái)來(lái)將獲取到的消息主動(dòng)推送給前端,所以本文記錄了SpringBoot集成WebSocket實(shí)現(xiàn)后臺(tái)向前端推送信息的操作,需要的朋友可以參考下
    2024-02-02
  • java中線程掛起的幾種方式詳解

    java中線程掛起的幾種方式詳解

    這篇文章主要介紹了java中線程掛起的幾種方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Java正則之貪婪匹配、惰性匹配

    Java正則之貪婪匹配、惰性匹配

    這篇文章主要介紹了Java正則之貪婪匹配、惰性匹配的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • @RequestParam 參數(shù)偶爾丟失的解決

    @RequestParam 參數(shù)偶爾丟失的解決

    這篇文章主要介紹了@RequestParam 參數(shù)偶爾丟失的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • JAVA十大排序算法之桶排序詳解

    JAVA十大排序算法之桶排序詳解

    這篇文章主要介紹了java中的桶排序,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • java中幾種常見(jiàn)的排序算法總結(jié)

    java中幾種常見(jiàn)的排序算法總結(jié)

    大家好,本篇文章主要講的是java中幾種常見(jiàn)的排序算法總結(jié),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • 詳解java自定義類

    詳解java自定義類

    這篇文章主要介紹了java自定義類的概念以及用法,文中講解非常詳細(xì),實(shí)例代碼幫助大家更好的理解,感興趣的朋友可以參考下
    2020-06-06
  • JPA 加鎖機(jī)制及@Version版本控制方式

    JPA 加鎖機(jī)制及@Version版本控制方式

    這篇文章主要介紹了JPA 加鎖機(jī)制及@Version版本控制方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • springboot 多環(huán)境切換的方法

    springboot 多環(huán)境切換的方法

    這篇文章主要介紹了springboot 多環(huán)境切換的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java實(shí)現(xiàn)多用戶注冊(cè)登錄的幸運(yùn)抽獎(jiǎng)

    Java實(shí)現(xiàn)多用戶注冊(cè)登錄的幸運(yùn)抽獎(jiǎng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)多用戶注冊(cè)登錄的幸運(yùn)抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評(píng)論