MyBatis(三) mybatis-config.xml元素說明、型別處理器typeHandler的使用

z1340954953發表於2018-07-04

XML檔案的層次結構

注意這些元素的層次的順序是不能打亂,可以通過工具的提示來定義元素


properties元素

配置屬性的元素

MyBatis提供了3種配置方式

* property子元素

<properties>
		<property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
</properties>

可以在上下文中使用

 <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>

*  properties配置檔案

在源包下面定義一個jdbc.properties檔案

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root

在使用properties元素引入這個檔案,上下文中直接使用

<properties resource="jdbc.properties"></properties>
<dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>

* 作為構造引數傳遞

jdbc.properties檔案的內容和上面一樣,不過密碼是加密過的,需要在建立SqlSessionFactory中解密,就需要手動建立,

並作為引數傳遞。

factory = new SqlSessionFactoryBuilder().build(inputStream, properties)
最後,上面的幾種方式讀取屬性的優先順序是從低到到。

settings元素

配置MyBatis的各種行為,不配置,MyBatis也能按照它的預設值正常執行


typeAliases元素

typeAliases元素用來配置別名,配置後可以在上下文中使用,別名是不區分大小寫的,別名分為系統定義別名和自定義別名兩類

1. 系統定義別名

基本型別的資料:  下劃線+名稱 -> 基本型別

包裝型別/類型別: 名稱->類型別


2.自定義別名

用來定義建立的pojo物件的別名

 <typeAliases>
  	<typeAlias alias="student" type="cn.bing.pojo.Student"/>
  </typeAliases>

如果有多個建立的物件,可以使用package元素掃包會自動生成別名,同時在類上加上@Alias註解

@Alias("student")
public class Student {
 <typeAliases>
	<package name="cn.bing.pojo"/>
  </typeAliases>

如果類上不加上註解@Alias也能夠新增別名,按照首字母小寫的規則生成,要注意別名衝突,

建議使用全路徑+類名的方式定義別名

typeHandlers元素

MyBatis在和資料庫互動時候,不管是將資料庫裡面的資料對映為Java型別的資料,還是將Java型別的資料對映為

資料庫裡面對應的欄位型別,都會通過typeHandler進行處理。

typeHandler分為系統定義和使用者自定義兩種。

系統自定義的typeHandler在org.apache.ibatis.type包下面,可以自己指定對應的typeHandler並引入。



需要注意的是java.util.Date/java.sql.Timestamp型別的對映,資料庫裡面設定為timestamp是可以的。

* 數值型別的精度,資料庫int,bigdecimal這些型別和java的精度、長度都是不同。

* 如果日期精確到日,型別處理器選擇DateOnlyTypeHandler,如果精確到秒,處理器選擇SqlTimestampTypeHandler

如何指定型別處理器

<resultMap type="student" id="studentMap">
  	<result column="o_date" property="oDate" javaType="java.sql.Timestamp" jdbcType="TIMESTAMP"
  	typeHandler="org.apache.ibatis.type.SqlTimestampTypeHandler"/>
  </resultMap>

自定義型別處理器

1. 建立一個類,繼承BastTypeHandler或者實現TypeHandler介面

@MappedTypes(value={String.class}) //指定javatype
@MappedJdbcTypes(value={JdbcType.VARCHAR}) //指定jdbctype
public class MyStringTypeHandler extends BaseTypeHandler<String>{

2. 註冊它. 指定javatype和jdbctype

<typeHandlers>
	<typeHandler javaType="String" jdbcType="VARCHAR" handler="cn.bing.typeHandler.MyStringTypeHandler"/>
</typeHandlers>

3. 使用.指定javatype和jdbctype

<resultMap type="student" id="studentMap">
  	<result column="stu_name" property="stuName" javaType="string" jdbcType="VARCHAR"
  	typeHandler="cn.bing.typeHandler.MyStringTypeHandler"/>
 </resultMap>

列舉型別typeHandler

MyBatis提供了兩個轉化列舉型別的typeHandler

* org.apache.ibatis.type.EnumTypeHandler,是以列舉字串作為引數傳遞的

* org.apache.ibatis.type.EnumOridinalTypeHandler,是以列舉下標作為引數傳遞的

如何使用

1. 定義一個列舉類

public enum Sex {
	MALE(1,"男"),FEMALE(0,"女");
	private int i;
	private String name;
	private Sex(int i,String name){
		this.i = i;
		this.name = name;
	}
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public static Sex getSex(int i ){
		if(i==1){
			return MALE;
		}else if(i==0){
			return FEMALE;
		}else{
			return null;
		}
	}
}

2. 註冊(因為使用系統的typeHandler可以不註冊)

3.在mapper.xml中配置

* 如果是查詢,將資料庫中的資料對映為java物件,需要在resultMap中指定使用到的typeHandler

* 如果是向資料庫中插入資料,需要#{name,typeHandler=指定的類載入器的全路徑}

* 查詢使用了resultMap進行了對映,因而查詢的列,不用再使用別名,因為在resultMap已經進行了配置對映。

<?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="cn.bing.mapper.StudentMapper">
 <resultMap type="cn.bing.pojo.Student" id="studentMap">
  	<id column="stu_id" property="stuId"/>
  	<result column="stu_age" property="stuAge"/>
  	<result column="stu_sex" property="stuSex" 
  	jdbcType="TINYINT" 
  	javaType="cn.bing.pojo.Sex" 
  	typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
  	<result column="stu_name" property="stuName"/>
  </resultMap>
  <insert id="insertStudent" parameterType="student">
   insert into student_info (stu_age,stu_sex,stu_name) values 
   (#{stuAge},#{stuSex,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},#{stuName})
  </insert>
  <select id="queryStudentInfo" resultMap="studentMap" parameterType="_int">
    select  stu_id, stu_Age,stu_Sex, stu_Name 
    from student_info where stu_id = #{id}
  </select>
</mapper>

3. 呼叫方法測試

* insert方法

StudentMapper mapper = (StudentMapper) session.getMapper(StudentMapper.class);
Student stu = new Student();
stu.setStuAge(100);
stu.setStuName("張三丰");
stu.setStuSex(Sex.MALE);
mapper.insertStudent(stu);

插入到資料庫的是列舉陣列的下標索引,也就是性別欄位的值是0


EnumTypeHandler 的使用類似,不過資料庫中以字串進行存放列舉型別,需要修改resultMap中jdbcType


自定義列舉對映器

很多的情況,需要入庫的是列舉id,查詢出來的是列舉的name,此時系統的typeHandler無法滿足需求,自定義一個

@MappedJdbcTypes(value={JdbcType.TINYINT})
@MappedTypes(value={Sex.class})
public class MyEnumTypeHandler implements TypeHandler<Sex> {
	@Override
	public void setParameter(PreparedStatement paramPreparedStatement,
			int paramInt, Sex paramT, JdbcType paramJdbcType)
			throws SQLException {
		paramPreparedStatement.setInt(paramInt, paramT.getI());
	}
	@Override
	public Sex getResult(ResultSet paramResultSet, String paramString)
			throws SQLException {
		return Sex.getSex(paramResultSet.getInt(paramString));
	}
	@Override
	public Sex getResult(ResultSet paramResultSet, int paramInt)
			throws SQLException {
		return Sex.getSex(paramResultSet.getInt(paramInt));
	}
	@Override
	public Sex getResult(CallableStatement paramCallableStatement, int paramInt)
			throws SQLException {
		return Sex.getSex(paramCallableStatement.getInt(paramInt));
	}
}
ObjectFactory

當MyBatis在構建一個結果返回的時候,都會使用物件工程生產pojo物件,只需要使用預設的就行。

如果需要自定義只要繼承 org.apache.ibatis.reflection.factory.DefaultObjectFactory,並在mybatis-config中配置。

environment配置環境

配置環境配置多個資料來源,每個資料來源主要是事務和資料來源的連線資訊配置。

<environments default="development">
    <environment id="development">
      <!-- 採用JDBC的事務管理方式 -->
      <transactionManager type="JDBC">
      	<property name="autoCommit" value="false"/>
      </transactionManager>
      <!-- 配置資料庫的連結資訊 -->
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>

* environments 的default屬性表示 預設使用哪個資料來源

* environment 的 id屬性唯一標識一個資料來源

* 事務配置

1. jdbc 事務

2. MANAGED容器管理事務

3. 自定義事務

資料來源配置DataSource元素

type屬性配置為三種,POOLED(連線池資料庫),UNPOOLED(非連線池資料庫),JDNI(JNDI資料來源)

databaseIdProvider元素

表名資料庫的廠商標識

相關文章