MyBatis高級映射ResultMap解決屬性問題
ResultMap結果映射解決復雜屬性
之前我們提到了用resultMap解決數據表中字段名與bean屬性名不一致的問題,這是resultMap的一種簡單實現。下面我們來看如何利用ResultMap來解決更復雜的屬性問題
場景:當我們需要聯查兩張表的時候,通常會在sql層面對兩個表進行外鍵關聯。那么設置了外鍵的從表對應的實體Bean中就需要定義一個對應主表的實例對象。
多對一關系處理
按照查詢嵌套
示例:
// 學生表 從表 public class Student { private int id; private String name; private Teacher teacher; // 定義主表對應bean實例 // 教師表 主表 public class Teacher { private int id; private String name; //teacher接口中定義方法 @Select("select name from teacher where id = #{tid}") Teacher getTeacherById(@Param("tid") int id); // student接口中定義方法 List<Student> getStudent();
sql:
-- 可以直接利用多表聯查sql 但是最終無法正確輸出teacher類信息 select * from student s join teacher t on s.tid = t.id; -- 將上面的sql拆開成兩句 先查詢到學生信息 用學生的tid字段對應教師的id查詢教師 select * from student; select * from teacher where id = #{tid}
打印日志:
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@79da8dc5]
==> Preparing: select * from student;
==> Parameters:
<== Columns: id, name, tid
<== Row: 1, 小子三, 1
<== Row: 2, 小子四, 1
<== Row: 3, 小子五, 1
<== Row: 4, 小子六, 1
<== Row: 5, 小子七, 1
<== Row: 6, 小子八, 1
<== Total: 6
Student{id=1, name='小子三', teacher=null}
Student{id=2, name='小子四', teacher=null}
Student{id=3, name='小子五', teacher=null}
Student{id=4, name='小子六', teacher=null}
Student{id=5, name='小子七', teacher=null}
Student{id=6, name='小子八', teacher=null}
可以很清晰的看出sql一共只執(zhí)行了一條,而根據學生表tid字段查詢教師信息的sql根本就沒有運行
下面我們對select * from teacher where id = #{tid}
這句sql返回的結果配置,利用resultMap為其配置合理的結果集來接收查詢到的結果
resultMap及sql配置如下:
<resultMap id="studentTeacher" type="student"> <!-- 普通映射 --> <result column="id" property="id"/> <result column="name" property="name"/> <!-- 復雜映射 association對象 collection集合 --> <association property="teacher" column="tid" javaType="teacher" select="getTeacherById"/> <!-- student表中tid字段對應實體類student中的teacher屬性 對應程序中的teacher類型 執(zhí)行select語句 --> </resultMap>
最終打印結果如下:
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@79da8dc5]
// 執(zhí)行sql1
==> Preparing: select * from student;
==> Parameters:
<== Columns: id, name, tid
<== Row: 1, 小子三, 1
// 執(zhí)行sql1
====> Preparing: select * from teacher where id = ?
====> Parameters: 1(Integer)
<==== Columns: id, name
<==== Row: 1, 秦老師
<==== Total: 1
<== Row: 2, 小子四, 1
<== Row: 3, 小子五, 1
<== Row: 4, 小子六, 1
<== Row: 5, 小子七, 1
<== Row: 6, 小子八, 1
<== Total: 6
// 最終teacher也以對象的形式打印出來
Student{id=1, name='小子三', teacher=Teacher{id=1, name='秦老師'}}
Student{id=2, name='小子四', teacher=Teacher{id=1, name='秦老師'}}
Student{id=3, name='小子五', teacher=Teacher{id=1, name='秦老師'}}
Student{id=4, name='小子六', teacher=Teacher{id=1, name='秦老師'}}
Student{id=5, name='小子七', teacher=Teacher{id=1, name='秦老師'}}
Student{id=6, name='小子八', teacher=Teacher{id=1, name='秦老師'}}
按照結果嵌套
studentMapper.xml配置resultMap如下:
<!-- 按照結果嵌套 --> <select id="getStudent2" resultMap="studentTeacher2"> select s.id sid,s.name sname,t.id tid,t.name tname from student s join teacher t on s.tid = t.id; </select> <resultMap id="studentTeacher2" type="student"> <result column="sid" property="id"/> <result column="sname" property="name"/> <association property="teacher" javaType="teacher"> <result column="tid" property="id"/> <result property="name" column="tname"/> </association> </resultMap>
如果采用結果嵌套配置,此時不論bean類屬性是否是基本類型都需要用result進行映射,否則輸出結果就會采用默認值
一對多關系處理
一對多關系處理,依舊以上述老師和學生為例。但是實體類需要修改,如下:
public class Teacher { private int id; private String name; private List<Student> student; public class Student { private int id; private String name; private int tid;
一個老師下對應多個學生,所以我們定義一個集合用于存儲學生
下面嘗試獲取指定老師下的所有學生信息及該老師信息
按照結果嵌套
程序:
// TeacherMapper // 指定老師下面的所有學生 Teacher getTeaById(@Param("teaId") int id);
resultMap配置
<select id="getTeaById" resultMap="TeaStu"> select s.id sid, s.name sname, t.name tname, t.id tpid,s.tid from student s ,teacher t where t.id = s.tid and t.id = #{teaId}; </select> <resultMap id="TeaStu" type="Teacher"> <result column="tpid" property="id"/> <result column="tname" property="name"/> <collection property="student" ofType="student"> <result column="sid" property="id"/> <result column="sname" property="name"/> <result column="tid" property="tid" /> </collection> </resultMap>
因為復雜屬性的類型為集合,所以我們在配置resultMap結果集映射時不再使用association對象,換成collection集合。在配置collection與association不同的是將JavaType(Java類型)換成了OfType其他依舊不變
按照查詢嵌套
TeacherMapper.xml配置resultMap
<select id="getTeaById" resultMap="TeaStu2"> select id,name from teacher where id = #{teaId} </select> <resultMap id="TeaStu2" type="teacher"> <result column="id" property="id"/> <result column="name" property="name"/> <collection property="student" javaType="ArrayList" ofType="student" select="getStuList" column="id"/> </resultMap> <select id="getStuList" resultType="student"> select id,name,tid from student where tid = #{tid} </select>
小結:個人感覺,按照查詢嵌套雖然一定程度上簡化了sql語句的編寫,但是針對resultMap的配置極其復雜,如果使用次數多可能還好。建議使用按照結果嵌套,sql語句編寫雖然復雜一些但是只要基礎扎實都是有理可循的,而且sql的編寫你可以在數據庫中進行調試,選擇最優(yōu)sql,并且對于結果集的映射配置也比較簡單,容易理解。
也可能是初學所以覺得按照子查詢會有點難度,總之還是水平太低了
到此這篇關于MyBatis高級映射ResultMap解決屬性問題的文章就介紹到這了,更多相關MyBatis高級映射ResultMap內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Intellij IDEA的Facets和Artifacts
這篇文章主要介紹了Intellij IDEA的Facets和Artifacts的相關知識,本文通過實例給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-09-09