首頁  >  文章  >  資料庫  >  mybatis屬性詳解

mybatis屬性詳解

jacklove
jacklove原創
2018-06-11 23:17:362442瀏覽

前言

MyBatis是基於「資料庫結構不可控」的想法建立的,也就是我們希望資料庫遵循第三範式或BCNF,但實際事與願違,那麼結果集映射就是MyBatis為我們提供這種理想與現實間轉換的手段了,而resultMap就是結果集映射的配置標籤了。 
在深入ResultMap標籤前,我們需要了解從SQL查詢結果集到JavaBean或POJO實體的過程。

從SQL查詢結果到領域模型實體 

  1. #透過JDBC查詢得到ResultSet物件

  2. #遍歷ResultSet物件並將每行資料暫存到HashMap實例中,以結果集的欄位名稱或欄位別名為鍵,以欄位值為值

  3. 根據ResultMap標籤的type屬性透過反射實例化領域模型

  4. 根據ResultMap標籤的type屬性和id、result等標籤資訊將HashMap中的鍵值對,填入領域模型實例並傳回

一、resultMap

1、屬性說明

  • id屬性,resultMap標籤的識別。

  • type屬性 ,傳回值的全限定類別名,或型別別名。

  • autoMapping屬性,值範圍true(預設值)|false, 設定是否啟動自動映射功能,自動映射功能就是自動查找與字段名小寫同名的屬性名,並調用setter方法。而設定為false後,則需要在resultMap內明確註明映射關係才會呼叫對應的setter方法。

2、基本功能:建立SQL查詢結果欄位與實體屬性的對應關係 
範例1:透過setter建構領域模型

public class EStudent{  private long id;  private String name;  private int age;  // getter,setter方法  /**
   * 必须提供一个无参数的构造函数
   */  public EStudent(){}
}
<select id="getStudent" resultMap="getStudentRM">
  SELECT ID, Name, Age
    FROM TStudent
</select>
<resultMap id="getStudentRM" type="EStudnet">
  <id property="id" column="ID"/>
  <result property="studentName" column="Name"/>
  <result property="studentAge" column="Age"/>
</resultMap>

子元素說明:

  • id元素,用於設定主鍵欄位與領域模型屬性的對應關係

  • result元素,用於設定普通欄位與領域模型屬性的映射關係

id、result語句屬性配置細節:

屬性 描述
#property 需要對應到JavaBean 的屬性名稱。
column 資料表的列名或標籤別名。
javaType 一個完整的類別名,或是一個型別別名。如果你配對的是一個JavaBean,那麼MyBatis 通常會自行偵測到。然後,如果你是要對應到一個HashMap,那你需要指定javaType 要達到的目的。
jdbcType 資料表支援的類型清單。這個屬性只在insert,update 或delete 的時候針對允許空的欄位有用。 JDBC 需要這項,但MyBatis 不需要。如果你是直接針對JDBC 編碼,且有允許空的列,而你要指定這項。
typeHandler 使用這個屬性可以覆寫類型處理器。這個值可以是一個完整的類別名,也可以是一個型別別名。

示例2:通过构造函数构造领域模型

<select id="getStudent" resultMap="getStudentRM">
  SELECT ID, Name, Age
    FROM TStudent</select><resultMap id="getStudentRM" type="EStudnet">  <constructor>    <idArg column="ID" javaType="_long"/>    <arg column="Name" javaType="String"/>    <arg column="Age" javaType="_int"/>  </constructor></resultMap>

子元素说明:

  • constructor元素 ,指定使用指定参数列表的构造函数来实例化领域模型。注意:其子元素顺序必须与参数列表顺序对应

  • idArg子元素 ,标记该入参为主键

  • arg子元素 ,标记该入参为普通字段(主键使用该子元素设置也是可以的)

3、一对一关系、一对多关系查询

 注意:在采用嵌套结果的方式查询一对一、一对多关系时,必须要通过resultMap下的id或result标签来显式设置属性/字段映射关系,否则在查询多条记录时会仅仅返回最后一条记录的情况。

association联合

联合元素用来处理“一对一”的关系。需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)。对应的数据库表的列名称。如果想覆写的话返回结果的值,需要指定typeHandler。 
不同情况需要告诉MyBatis 如何加载一个联合。MyBatis 可以用两种方式加载:

  • select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;

  • resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。

例如,一个班级对应一个班主任。 
首先定义好班级中的班主任 private TeacherEntity teacherEntity;

使用select实现联合 
例:班级实体类中有班主任的属性,通过联合在得到一个班级实体时,同时映射出班主任实体。 
这样可以直接复用在TeacherMapper.xml文件中定义好的查询teacher根据其ID的select语句。而且不需要修改写好的SQL语句,只需要直接修改resultMap即可。

ClassMapper.xml文件部分内容:

<resultMap type="ClassEntity" id="classResultMap">  
    <id property="classID" column="CLASS_ID" />  
    <result property="className" column="CLASS_NAME" />  
    <result property="classYear" column="CLASS_YEAR" />  
    <association property="teacherEntity" column="TEACHER_ID" select="getTeacher"/>  
</resultMap>  
<select id="getClassByID" parameterType="String" resultMap="classResultMap">  
    SELECT * FROM CLASS_TBL CT  
    WHERE CT.CLASS_ID = #{classID};  
</select>

TeacherMapper.xml文件部分内容:

<resultMap type="TeacherEntity" id="teacherResultMap">  
    <id property="teacherID" column="TEACHER_ID" />  
    <result property="teacherName" column="TEACHER_NAME" />  
    <result property="teacherSex" column="TEACHER_SEX" />  
    <result property="teacherBirthday" column="TEACHER_BIRTHDAY"/>  
    <result property="workDate" column="WORK_DATE"/>  
    <result property="professional" column="PROFESSIONAL"/>  
</resultMap>  
<select id="getTeacher" parameterType="String"  resultMap="teacherResultMap">  
    SELECT *  
      FROM TEACHER_TBL TT  
     WHERE TT.TEACHER_ID = #{teacherID}  
</select>

使用resultMap实现联合 
与上面同样的功能,查询班级,同时查询器班主任。需在association中添加resultMap(在teacher的xml文件中定义好的),新写sql(查询班级表left join教师表),不需要teacher的select。

修改ClassMapper.xml文件部分内容:

<resultMap type="ClassEntity" id="classResultMap">  
    <id property="classID" column="CLASS_ID" />  
    <result property="className" column="CLASS_NAME" />  
    <result property="classYear" column="CLASS_YEAR" />  
    <association property="teacherEntity" column="TEACHER_ID"  resultMap="teacherResultMap"/>  
</resultMap>  
<select id="getClassAndTeacher" parameterType="String" resultMap="classResultMap">  
    SELECT *  
      FROM CLASS_TBL CT LEFT JOIN TEACHER_TBL TT ON CT.TEACHER_ID = TT.TEACHER_ID  
     WHERE CT.CLASS_ID = #{classID};  
</select>

其中的teacherResultMap请见上面TeacherMapper.xml文件部分内容中。

collection聚集

聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);列表中对象的类型ofType(Java实体类);对应的数据库表的列名称; 
不同情况需要告诉MyBatis 如何加载一个聚集。MyBatis 可以用两种方式加载: 
1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活; 
2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。

例如,一个班级有多个学生。 
首先定义班级中的学生列表属性:private List<StudentEntity> studentList;

使用select实现聚集 
用法和联合很类似,区别在于,这是一对多,所以一般映射过来的都是列表。所以这里需要定义javaType为ArrayList,还需要定义列表中对象的类型ofType,以及必须设置的select的语句名称(需要注意的是,这里的查询student的select语句条件必须是外键classID)。

ClassMapper.xml文件部分内容:

<resultMap type="ClassEntity" id="classResultMap">  
    <id property="classID" column="CLASS_ID" />  
    <result property="className" column="CLASS_NAME" />  
    <result property="classYear" column="CLASS_YEAR" />  
    <association property="teacherEntity" column="TEACHER_ID"  select="getTeacher"/>  
    <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" select="getStudentByClassID"/>  
</resultMap>  
<select id="getClassByID" parameterType="String" resultMap="classResultMap">  
    SELECT * FROM CLASS_TBL CT  
    WHERE CT.CLASS_ID = #{classID};  
</select>

StudentMapper.xml文件部分内容:

<!-- java属性,数据库表字段之间的映射定义 -->  
<resultMap type="StudentEntity" id="studentResultMap">  
    <id property="studentID" column="STUDENT_ID" />  
    <result property="studentName" column="STUDENT_NAME" />  
    <result property="studentSex" column="STUDENT_SEX" />  
    <result property="studentBirthday" column="STUDENT_BIRTHDAY" />  
</resultMap>  
<!-- 查询学生list,根据班级id -->  
<select id="getStudentByClassID" parameterType="String" resultMap="studentResultMap">  
    <include refid="selectStudentAll" />  
    WHERE ST.CLASS_ID = #{classID}  
</select>

使用resultMap实现聚集 
使用resultMap,就需要重写一个sql,left join学生表。

<resultMap type="ClassEntity" id="classResultMap">  
    <id property="classID" column="CLASS_ID" />  
    <result property="className" column="CLASS_NAME" />  
    <result property="classYear" column="CLASS_YEAR" />  
    <association property="teacherEntity" column="TEACHER_ID"  resultMap="teacherResultMap"/>  
    <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" resultMap="studentResultMap"/>  
</resultMap>  
<select id="getClassAndTeacherStudent" parameterType="String" resultMap="classResultMap">  
    SELECT *  
      FROM CLASS_TBL CT  
           LEFT JOIN STUDENT_TBL ST  
              ON CT.CLASS_ID = ST.CLASS_ID  
           LEFT JOIN TEACHER_TBL TT  
              ON CT.TEACHER_ID = TT.TEACHER_ID  
      WHERE CT.CLASS_ID = #{classID};  
</select>

其中的teacherResultMap请见上面TeacherMapper.xml文件部分内容中。studentResultMap请见上面StudentMapper.xml文件部分内容中。

4. 动态映射关系 
通过 discriminator子元素 (鉴别器)可以实现动态映射关系信息的设置。具体示例如下:

public class EStudent{  private long id;  private String name;  private String juniorHighSchool;  private String seniorHighSchool;  private int during; // 在本校就读时间  // getter,setter方法  /**
   * 必须提供一个无参数的构造函数
   */  public EStudent(){}
}

情景:查询学生信息的seniorHighSchool信息,若就读时间during字段值为4、5、6时,则以juniorHighSchool字段作所为seniorHighSchool信息。

<select id="getStundent" resultMap="rm">
  SELECT ID, Name, JuniorHighSchool, SeniorHighSchool, during
    FROM TStudent</select><resultMap id="rm" type="EStudent">
  // 若不加这句,则当将juniorHighSchool赋予给seniorHighSchool属性时,juniorHighSchool属性将为null  <result column="juniorHighSchool" property="juniorHighSchool"/>  <discriminator column="during" javaType="_int">
    // 形式1:通过resultType设置动态映射信息    <case value="4" resultType="EStudent">      <result column="juniorHighSchool" property="seniorHighSchool"/>    </case>
   // 形式2: 通过resultMap设置动态映射信息   <case value="5" resultMap="dynamicRM"/>   <case value="6" resultMap="dynamicRM"/>  </discriminator></resultMap><resultMap id="dynamicRM" type="EStudent">  <result column="juniorHighSchool" property="seniorHighSchool"/></resultMap>

注意:上面关于 discriminator子元素 的 case元素 的 resultType属性 和 resultMap元素 的 type属性 ,均不是直指返回的领域模型类型,而是指定根据判断条件后得到映射关系,可通过 id子元素 和 result子元素 重写映射关系。

5. id元素,result元素,idArg元素,arg元素,discriminator元素的共同属性

  • javaType属性 :Java类的全限定名,或别名

  • jdbcType属性 :JDBC类型, JDBC类型为CUD操作时列可能为空时进行处理

  • typeHandler属性 :指定类型处理器的全限定类名或类型别名

  • column属性 :指定SQL查询结果的字段名或字段别名。将用于JDBC的 resultSet.getString(columnName)

  • 本文說明了mybatis屬性詳解,更多相關內容請關注php中文網。

  • 相關推薦:

  • MySQL資料庫多表操作

  • MySQL資料庫單表查詢

  • #Oracle資料庫輸出輸入

#####Oracle資料庫輸出輸入############## #

以上是mybatis屬性詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn