MyBatis(三)MyBatis resultMap和注解


MyBatis 目錄

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 會將數據庫中的列數據復制到對象的相應屬性上,可用於復制查詢。

需要注意的是,resultMapresultType 不能同時使用。

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); 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM