mybatis基本使用以及加載配置文件學習總結

一:mybatis的使用

mybatis使用有2種方式:

1:老版本ibatis中直接使用sqlsession的api,具體如下

在這裏插入圖片描述
在這裏插入圖片描述
引入mybatis的pom座標

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

mybatis主要通過一個SqlSessionFactoryBulder,在解析mybatis的配置下,創建SqlSessionFactory,然後通過SqlSessionFactory創建SqlSqlssion來操作數據庫

獲取SqlSessionFactory(兩種方式:使用xml和使用代碼方式)

方式一:通過mybatisConfig.xml獲取

創建mybatisConfig.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 resource="mybatis/mybatis.properties"></properties>

    <!--mybatis運行時的一些配置-->
    <settings>
        <setting name="" value=""/>
    </settings>

    <!-- 針對單個別名定義type:類型的路徑 alias:別名 -->
    <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
    <!-- 批量別名定義 指定包名,mybatis自動掃描包中的po類,自動定義別名,別名就是類名(類名小寫)-->
    <!-- 別名定義 -->
    <typeAliases>
        <package name="com.test.model"/>
    </typeAliases>

    <environments default="${defaultActive}">
        <!--開發環境:事務處理器以及數據源-->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${dev_url}"/>
                <property name="username" value="${dev_username}"/>
                <property name="password" value="${dev_password}"/>
            </dataSource>
        </environment>

        <!--測試環境-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${test_url}"/>
                <property name="username" value="${test_username}"/>
                <property name="password" value="${test_password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入mapper.xml文件-->
    <mappers>
        <mapper resource="mybatis/mapper/testMapper.xml"/>
    </mappers>
</configuration>

testMapper.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="mybatis.mapper">
	<!--簡單查詢-->
	<select id="selectById"  resultType="com.test.model.User"
		parameterType="java.lang.String" >
	    select * from user where id = #{pid}
	</select>

</mapper>  

TestMybatis.java

        String resource = "mybatis/mybatisConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		String pid = "1";
		List<User> selectList = session.selectList("mybatis.mapper.selectById", pid);
		System.out.println(selectList.size());

2:面向接口編程,使用mapper

使用mapper接口,必須保證接口全類名和mapper.xml的namespace一樣,方法名和mapper.xml中對應sql的id相同。
在這裏插入圖片描述
在這裏插入圖片描述

二:配置解析

總的來說,mybatis的所有配置基本上都會解析到Configuration類中,本文只看解析過程,暫時不管應用。
在這裏插入圖片描述
很顯然,mybatis的配置解析代碼在SqlSessionFactoryBuilder的build方法。
在這裏插入圖片描述
重點顯然在解析配置到Configuration過程。
parseConfiguration(parser.evalNode("/configuration"));
在這裏插入圖片描述

1:properties:外部配置

在這裏插入圖片描述
在這裏插入圖片描述

2:typeAliases:類型別名配置

在這裏插入圖片描述
在這裏插入圖片描述
如何設置別名?
typeAliasRegistry.registerAlias(clazz);
在這裏插入圖片描述在這裏插入圖片描述
typeAliasRegistry在Configuiration中。內部包含默認的一些別名。

3:plugins:插件配置

在這裏插入圖片描述
插件配置解析,實例化
在這裏插入圖片描述

4:settings:全局運行參數

在這裏插入圖片描述
都是一些鍵值對,在Configuration類中有對應字段保存。能夠改變mybatis的運行行爲
在這裏插入圖片描述
下面是setting的各個配置項說明
參考:https://www.cnblogs.com/LingCoder/p/9063730.html

5:environments:數據源和事務處理器

<environments default="development">
    <environment id="development">
        <!-- 配置事務處理器 -->
        <transactionManager type="JDBC" />
        <!-- 配置數據庫連接信息 -->
        <dataSource type="POOLED">
            <property name="driver" value="${derby.driver}" />
            <property name="url" value="${derby.url}" />
            <property name="username" value="${derby.user}" />
            <property name="password" value="${derby.pwd}" />
        </dataSource>
    </environment>
</environments>

environment 的id唯一標識運行環境,environments的default指定默認運行環境。可以切換開發測試環境。
在這裏插入圖片描述

事務處理器怎麼創建的呢?
在這裏插入圖片描述
在Configuration的構造器中設置別名,都是事務工廠的實現:
在這裏插入圖片描述
在這裏插入圖片描述
數據源又是怎麼創建的呢?
在這裏插入圖片描述
在Configuration中的構造器設置的datasource別名,都是數據源工廠的實現:
在這裏插入圖片描述
在這裏插入圖片描述

6:mapper:映射器配置

<mappers>
     <!--<package name=""></package>-->
    <mapper resource="testMapper.xml"></mapper>
    <mapper resource="testMapper2.xml"></mapper>
</mappers>

有2種方式:

  1. 統一配置:package
  2. 單獨配置:mapper

那麼通過pakage配置,如何解析呢?
配置package的話,就是mapper接口所在的包名。並且對應的mapper.xml要和接口名同名,且在同一個包下。

加載後mapper存放在映射器註冊器中:MapperRegistry (在Configuration中初始化),然後解析對應的mapper.xml

在這裏插入圖片描述

1. mapper開啓二級緩存引用:cache-ref

在這裏插入圖片描述
配置完成後,在使用的時候,能根據Configuration中的namespace引用關係,拿到緩存引用的對象,進而引用其它映射器的緩存。

2.mapper開啓二級緩存:cache

在這裏插入圖片描述
緩存配置解析邏輯:

private void cacheElement(XNode context) throws Exception {
    if (context != null) {
       // 如果自定義緩存實現,就需要指定type字段,否則使用默認實現(Configuration中指定:typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);)
      String type = context.getStringAttribute("type", "PERPETUAL");
      Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
      // 確定緩存回收策略的實現
      String eviction = context.getStringAttribute("eviction", "LRU");
      Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
      Long flushInterval = context.getLongAttribute("flushInterval");
      Integer size = context.getIntAttribute("size");
      boolean readWrite = !context.getBooleanAttribute("readOnly", false);
      boolean blocking = context.getBooleanAttribute("blocking", false);
      //讀入額外的配置信息,易於第三方的緩存擴展,例:
//    <cache type="com.domain.something.MyCustomCache">
//      <property name="cacheFile" value="/tmp/my-custom-cache.tmp"/>
//    </cache>
      Properties props = context.getChildrenAsProperties();
      //調用builderAssistant.useNewCache
      builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);
    }
  }
  1. 確定緩存處理的實現類:
    默認使用:PERPETUAL (別名在Configuration配置)
    typeAliasRegistry.registerAlias(“PERPETUAL”, PerpetualCache.class);
  2. 後面分別確認cache的幾個屬性
  3. 關鍵部分:
    builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);

在這裏插入圖片描述

3. resultMap解析

這個元素很重要,此處簡單瞭解,留待後面重點分析。

<resultMap id="trrr" type="txd.test.model.Blog">
  <id column="id" javaType="string" property="id"></id>
    <result column="author_id" javaType="string" property="authorId"></result>
    <result column="title" javaType="string" property="title"></result>
</resultMap>

相應解析邏輯:
在這裏插入圖片描述
以id子節點爲例,看看如何解析?

 List<ResultFlag> flags = new ArrayList<ResultFlag>();
        if ("id".equals(resultChild.getName())) {
          flags.add(ResultFlag.ID);
        }
        //調5.1.1 buildResultMappingFromContext,得到ResultMapping
        resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));

跟進代碼,其實就是把id子節點的各個屬性解析出來。傳入 ,通過構造者模式得到ResultMapping。所有節點解析完就是一個List,然後構建ResultMap。最後加入到Configuration中 (key是resultmap的id)
protected final Map<String, ResultMap> resultMaps = new StrictMap(“Result Maps collection”);

4.sql片段解析和select節點解析

在這裏插入圖片描述
首先放入XMLMapperBuilder的 Map<String, XNode> sqlFragments;中,具體解析是在select|insert|update|delete的解析過程中使用

那麼select|insert|update|delete怎麼解析的呢?
看一個簡單例子:

<select id="selectById"  resultMap="trrr" >
    select * from BLOG where id = #{id}
</select>
  1. 首先是獲取select節點的各種屬性值,以下這些
    在這裏插入圖片描述
  2. 看一下緩存相關的
    boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
    boolean flushCache = context.getBooleanAttribute(“flushCache”, !isSelect);
    //是否要緩存select結果
    boolean useCache = context.getBooleanAttribute(“useCache”, isSelect);

如果是select語句,默認是不清理緩存的,除非flushCache指定true(默認false)
而且select默認是使用緩存的,除非(useCache指定爲false)

  1. sql片段應用
    參考一篇博客:https://my.oschina.net/zudajun/blog/687326

  2. sql解析
    最終解析成MappedStatement,此過程會用到SqlSource(動態sql解析),BoundSql
    具體參考網上的2篇博客:
    https://my.oschina.net/zudajun/blog/735553
    https://my.oschina.net/zudajun/blog/735731

三:參考博客

https://my.oschina.net/zudajun?tab=newest&catalogId=3532897

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章