MyBatis拾遺(二)——一些配置的簡單梳理

一些配置屬性

下面從MyBatis的配置文件中梳理一下MyBatis的一些配置標籤

configuration標籤

這個是MyBatis配置文件中的一級配置屬性,其實對應MyBatis源碼中一個Configuration的類。打開這個類的源碼,可以看到很多屬性,這些與配置文件中的屬性都能對上。

properties標籤

可以配置一些數據庫連接信息的屬性

settings標籤

配置mybatis的核心屬性,其下還有很多重要的屬性配置

<!--一個完整的setting的配置如下-->
<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="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

關於這些屬性在mybatis的官網上有詳細的介紹,mybatis settings

typeAliases標籤

mybatis中,有時候指定類型的時候,需要全限定名稱,可以通過別名來減少這樣的麻煩。

<typeAliases>
    <typeAlias alias="blog" type="com.learn.entity.Blog" />
</typeAliases>

mybatis同時提供了一個自定義的別名類——TypeAliasRegistry,具體源碼如下圖所示,可以看到一些基本的數據類型Mybatis都爲我們定義了別名。

在這裏插入圖片描述

typeHandlers標籤

這個是一個比較重要的標籤,主要完成Java類型與Jdbc類型的轉換的問題。Java類型與數據庫類型並不是一一對應的,比如Java的String類型,在數據庫中對應varchar類型。因此我們將Java對象的值轉換成數據庫的值需要經過一個轉換。這兩個方向的轉換需要用到TypeHandler。

但是我們實際開發過程中,Java的String爲啥會自動轉換成varchar呢?因爲MyBatis爲我們自定義了一些基本的轉換器,可以在TypeHandlerRegistry中看到MyBatis爲我們內置的一些類型的轉換。這些Handler就完成了這個工作。
在這裏插入圖片描述

實例:

1、先自定義實現一個類型轉換器,具體代碼如下

/**
 * autor:liman
 * createtime:2020/5/3
 * comment:
 */
public class MyTypeHanler extends BaseTypeHandler<String> {
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
            throws SQLException {
        // 設置 String 類型的參數的時候調用,Java類型到JDBC類型
        // 注意只有在字段上添加typeHandler屬性纔會生效
        // insertBlog name字段
        System.out.println("---------------setNonNullParameter1:"+parameter);
        ps.setString(i, parameter);
    }

    //通過類名獲取指定的值
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根據列名獲取 String 類型的參數的時候調用,JDBC類型到java類型
        // 注意只有在字段上添加typeHandler屬性纔會生效
        System.out.println("---------------getNullableResult1:"+columnName);
        return rs.getString(columnName);
    }

    //通過索引獲取指定的值
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根據下標獲取 String 類型的參數的時候調用
        System.out.println("---------------getNullableResult2:"+columnIndex);
        return rs.getString(columnIndex);
    }

    //通過CallableStatement+索引獲取指定的值
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        System.out.println("---------------getNullableResult3:");
        return cs.getString(columnIndex);
    }
}

這個轉換器在查詢或插入數據的時候都會用到

1、自定義一個轉換器

/**
 * autor:liman
 * createtime:2020/5/3
 * comment:
 */
public class MyTypeHanler extends BaseTypeHandler<String> {
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
            throws SQLException {
        // 設置 String 類型的參數的時候調用,Java類型到JDBC類型
        // 注意只有在字段上添加typeHandler屬性纔會生效
        // insertBlog name字段
        System.out.println("---------------setNonNullParameter1:"+parameter);
        ps.setString(i, parameter);
    }

    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 根據列名獲取 String 類型的參數的時候調用,JDBC類型到java類型
        // 注意只有在字段上添加typeHandler屬性纔會生效
        System.out.println("---------------getNullableResult1:"+columnName);
        return rs.getString(columnName);
    }

    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        // 根據下標獲取 String 類型的參數的時候調用
        System.out.println("---------------getNullableResult2:"+columnIndex);
        return rs.getString(columnIndex);
    }

    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        System.out.println("---------------getNullableResult3:");
        return cs.getString(columnIndex);
    }
}

查詢時指定轉換器如下:

<resultMap id="BaseResultMap" type="blog">
    <id column="bid" property="bid" jdbcType="INTEGER"/>
    <!--指定轉換器-->
    <result column="name" property="name" jdbcType="VARCHAR" typeHandler="com.learn.type.MyTypeHanler"/>
    <result column="author_id" property="authorId" jdbcType="INTEGER"/>
</resultMap>

查詢執行結果:

在這裏插入圖片描述

插入時指定轉換器

<insert id="insertBlog" parameterType="blog">
    insert into blog (bid, name, author_id)
    values (#{bid,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR,typeHandler=com.learn.type.MyTypeHanler}, #{authorId,jdbcType=CHAR})
</insert>

插入時執行的結果

在這裏插入圖片描述

objectFactory標籤

當MyBatis從數據庫獲取到數據的時候,在將數據轉換成指定的實體的時候,需要創建相應的對象,單純通過獲取到的數據,無法知道所要創建的對象的目標類型是什麼,因此不能用new去創建,因此MyBatis就提供了一個ObjectFactory的接口,專門用來創建對象。其源碼入下

/**
 * MyBatis uses an ObjectFactory to create all needed new Objects.
 *
 * @author Clinton Begin
 */
public interface ObjectFactory {

  /**
   * Sets configuration properties.
   * @param properties configuration properties
   * TODO:在設置參數的時候調用
   */
  void setProperties(Properties properties);

  /**
   * Creates a new object with default constructor.
   * @param type Object type
   * @return
   * TODO:創建對象調用對象的無參構造函數
   */
  <T> T create(Class<T> type);

  /**
   * Creates a new object with the specified constructor and params.
   * @param type Object type
   * @param constructorArgTypes Constructor argument types
   * @param constructorArgs Constructor argument values
   * @return
   * TODO:創建對象,調用帶有參數的構造函數
   */
  <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);

  /**
   * Returns true if this object can have a set of other objects.
   * It's main purpose is to support non-java.util.Collection objects like Scala collections.
   *
   * @param type Object type
   * @return whether it is a collection or not
   * @since 3.1.0
   * TODO:判斷是否是集合
   */
  <T> boolean isCollection(Class<T> type);

}

ObjectFactory有一個默認的實現——DefaultObjectFactory

只是在我們需要創建新的對象的時候,可以通過ObjectFactory來完成,關於他的解釋可以參看官網 MyBatis ObjectFactory

environments標籤

用於區分不同的環境使用的數據庫,其每一個environment標籤就代表一個數據庫環境。

transactionManager標籤

屬於environment標籤的一個子標籤,用於配置MyBatis的事務管理方式。

如果transactionManager指定爲JDBC,則會採用JDBC原生的commit,rollback,close等方式管理事務。

如果配置成MANAGED,則會將事務的控制交給容器來做,比如JBOSS,WebLogic等。

如果與spring等框架集成則無需設置該值,因爲spring的配置會覆蓋掉mybatis的配置。

mappers標籤

配置了需要掃描的Mapper.xml文件

Mapper.xml的配置

Mapper.xml文件中一共有8個標籤

1、cache——給定命名空間的緩存配置(是否開啓二級緩存)

2、cache-ref——其他命名空間緩存配置的引用。

3、resultMap——最複雜的一個標籤,用來描述如何從數據庫結果集中來加載對象

4、sql——可被其他語句引用的可重用語句塊

5、insert——插入標籤

6、update——映射更新標籤

7、delete——映射刪除標籤

8、select——映射查詢標籤

這些屬性可以參考MyBatis的使用博客

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