MyBatis 目錄
- MyBatis(一)MyBatis初識 - 青杉 - 博客園 (cnblogs.com)
- MyBatis(二)MyBatis標簽 - 青杉 - 博客園 (cnblogs.com)
- MyBatis(三)MyBatis resultMap和注解 - 青杉 - 博客園 (cnblogs.com)
- MyBatis(四)MyBatis關聯(級聯)查詢 - 青杉 - 博客園 (cnblogs.com)
- MyBatis(五)MyBatis動態SQL - 青杉 - 博客園 (cnblogs.com)
MyBatis resultMap元素
resultMap 是 MyBatis 中最復雜的元素,主要用於解決實體類屬性名與數據庫表中字段名不一致的情況,可以將查詢結果映射成實體對象。下面我們先從最簡單的功能開始介紹。
resultMap元素的構成
resultMap 元素還可以包含以下子元素,代碼如下。
<resultMap id="" type="">
<constructor><!-- 類再實例化時用來注入結果到構造方法 -->
<idArg/><!-- ID參數,結果為ID -->
<arg/><!-- 注入到構造方法的一個普通結果 -->
</constructor>
<id/><!-- 用於表示哪個列是主鍵 -->
<result/><!-- 注入到字段或JavaBean屬性的普通結果 -->
<association property=""/><!-- 用於一對一關聯 -->
<collection property=""/><!-- 用於一對多、多對多關聯 -->
<discriminator javaType=""><!-- 使用結果值來決定使用哪個結果映射 -->
<case value=""/><!-- 基於某些值的結果映射 -->
</discriminator>
</resultMap>
其中:
-
元素的 type 屬性表示需要的 POJO,id 屬性是 resultMap 的唯一標識。 - 子元素
用於配置構造方法。當一個 POJO 沒有無參數構造方法時使用。 - 子元素
用於表示哪個列是主鍵。允許多個主鍵,多個主鍵稱為聯合主鍵。 - 子元素
用於表示 POJO 和 SQL 列名的映射關系。 - 子元素
、 和 用在級聯的情況下。關於級聯的問題比較復雜,在《 MyBatis一對一關聯查詢》和《 MyBatis一對多關聯查詢》一節詳細講解。
id 和 result 元素都有以下屬性。
元素 | 說明 |
---|---|
property | 映射到列結果的字段或屬性。如果 POJO 的屬性和 SQL 列名(column元素)是相同的,那么 MyBatis 就會映射到 POJO 上 |
column | 對應 SQL 列 |
javaType | 配置 Java 類型。可以是特定的類完全限定名或 MyBatis 上下文的別名 |
jdbcType | 配置數據庫類型。這是 JDBC 類型,MyBatis 已經為我們做了限定,基本支持所有常用數據庫類型 |
typeHandler | 類型處理器。允許你用特定的處理器來覆蓋 MyBatis 默認的處理器。需要指定 jdbcType 和 javaType 相互轉化的規則 |
一條 SQL 查詢語句執行后會返回結果集,結果集有兩種存儲方式,即使用 Map 存儲和使用 POJO 存儲。
使用Map存儲結果集
任何 select 語句都可以使用 Map 存儲,代碼如下。
<!-- 查詢所有信息存到Map中 -->
<select id="selectAllBlog" resultType="map">
select * from blog
</select>
使用POJO存儲結果集
因為 MyBatis 提供了自動映射,所以使用 POJO 存儲結果集是最常用的方式。但有時候需要更加復雜的映射或級聯,這時就需要使用 select
元素的resultMap
屬性配置映射集合。
<resultMap id="blogMap" type="org.mybatis.example.Blog">
<!-- property 是 org.mybatis.example.Blog 類中的屬性 -->
<!-- column是查詢結果的列名,可以來自不同的表 -->
<id property="id" column="id" />
<result property="blogTitle" column="blog_title" />
<result property="desc" column="desc" />
</resultMap>
resultMap
元素的屬性 id
代表這個 resultMap
的標識,type
標識需要映射的 POJO
。我們可以使用MyBatis
定義好的類的別名或自定義類的全限定名。
這里使用 property
元素指定 Blog的屬性名稱 blogTitle,column 表示數據庫中 blog表的 SQL 列名 blog_title,將 POJO 和 SQL 的查詢結果一 一對應。
Blog
類中的blogTitle
屬性和blog
表中的blog_title
列對應
<select id="selectAllBlog" resultMap="blogMap">
select id,blog_title,desc from blog
</select>
resultType和resultMap的區別
MyBatis
的每一個查詢映射的返回類型都是 resultMap
,只是當我們提供的返回類型是 resultType
時,MyBatis 會自動把對應的值賦給 resultType 所指定對象的屬性,而當我們提供的返回類型是 resultMap
時,MyBatis 會將數據庫中的列數據復制到對象的相應屬性上,可用於復制查詢。
需要注意的是,resultMap
和 resultType
不能同時使用。
MyBatis注解(3種類型)
為了簡化 XML 的配置,MyBatis 提供了注解。
1. SQL 語句映射
@Insert:實現新增功能
@Insert("insert into user(id,name) values(#{id},#{name})")
public int insert(User user);
@Select:實現查詢功能
@Select("Select * from user")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "name", property = "name"),
@Result(column = "sex", property = "sex"),
@Result(column = "age", property = "age")
})
List<User> queryAllUser();
@SelectKey:插入后,獲取id的值
以 MySQL 為例,MySQL 在插入一條數據后,使用select last_insert_id()
可以獲取到自增 id 的值。
@Insert("insert into user(id,name) values(#{id},#{name})")
@SelectKey(statement = "select last_insert_id()", keyProperty = "id", keyColumn = "id", resultType = int,before = false)
public int insert(User user);
@SelectKey
各個屬性含義如下。
statement
:表示要運行的 SQL 語句;keyProperty
:可選項,表示將查詢結果賦值給代碼中的哪個對象;keyColumn
:可選項,表示將查詢結果賦值給數據表中的哪一列;resultType
:指定 SQL 語句的返回值;before
:默認值為 true,在執行插入語句之前,執行select last_insert_id()
。值為flase
,則在執行插入語句之后,執行select last_insert_id()
。
@Insert:實現插入功能
@Insert("insert into user(name,sex,age) values(#{name},#{sex},#{age}")
int saveUser(User user);
5)@Update:實現更新功能
@Update("update user set name= #{name},sex = #{sex},age =#{age} where id = #{id}")
void updateUserById(User user);
6)@Delete:實現刪除功能
@Delete("delete from user where id =#{id}")
void deleteById(Integer id);
7)@Param:映射多個參數
@Param 用於在 Mapper 接口中映射多個參數。
int saveUser(@Param(value="user") User user,@Param("name") String name,@Param("age") Int age);
@Param 中的 value 屬性可省略,用於指定參數的別名。
2. 結果集映射
@Result、@Results、@ResultMap 是結果集映射的三大注解。
聲明結果集映射關系代碼:
Select({"select id, name, class_id from student"})
@Results(id="studentMap", value={
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="name", property="name", jdbcType=JdbcType.VARCHAR),
@Result(column="class_id ", property="classId", jdbcType=JdbcType.INTEGER)
})
List<Student> selectAll();
下面為 @Results 各個屬性的含義。
- id:表示當前結果集聲明的唯一標識;
- value:表示結果集映射關系;
- @Result:代表一個字段的映射關系。其中,column 指定數據庫字段的名稱,property 指定實體類屬性的名稱,jdbcType 數據庫字段類型,id 為 true 表示主鍵,默認 false。
可使用 @ResultMap 來引用映射結果集,其中 value 可省略。
@Select({"select id, name, class_id from student where id = #{id}"})
@ResultMap(value="studentMap")
Student selectById(Integer id);
這樣不需要每次聲明結果集映射時都復制冗余代碼,簡化開發,提高了代碼的復用性。
3. 關系映射
@one:用於一對一關系映射
@Select("select * from student")
@Results({
@Result(id=true,property="id",column="id"),
@Result(property="name",column="name"),
@Result(property="age",column="age"),
@Result(property="address",column="address_id",one=@One(select="net.biancheng.mapper.AddressMapper.getAddress"))
})
public List<Student> getAllStudents();
@many:用於一對多關系映射
@Select("select * from t_class where id=#{id}")
@Results({
@Result(id=true,column="id",property="id"),
@Result(column="class_name",property="className"),
@Result(property="students", column="id", many=@Many(select="net.biancheng.mapper.StudentMapper.getStudentsByClassId"))
})
public Class getClass(int id);