MyBatis -- 结果集映射
一。字段映射
比如有張數據表結構如下:
在后臺的JavaBean中,如果遵守規范的話,屬性名和列名一致,那么我們就不需要手動做字段映射,MyBatis會自動幫我們把值填充到Bean中。但現在情況不一樣,Bean的屬性名和數據庫列名對應不上。
import java.util.ArrayList;
?
import java.util.List;
?
public class Grade {
?
? ? private String gradeId; ? ? ? ?// 班級ID
? ? private String gName; ? ? ? ?// 班級名
? ? private List<Student> stuList = new ArrayList<Student>(); // 班級中的學生
?
? ? public String getGradeId() {
? ? ? ? ? ? return gradeId;
? ? }
?
?
? ? public void setGradeId(String gradeId) {
? ? ? ? ? ? this.gradeId = gradeId;
? ? }
?
?
? ? public String getgName() {
? ? ? ? ? ? return gName;
? ? }
?
?
? ? public void setgName(String gName) {
? ? ? ? ? ? this.gName = gName;
? ? }
?
?
? ? public List<Student> getStuList() {
? ? ? ? ? ? return stuList;
? ? }
?
?
? ? public void setStuList(List<Student> stuList) {
? ? ? ? ? ? this.stuList = stuList;
? ? }
?
? ? @Override
? ? public String toString() {
? ? ? ? ? ? return "Grade [gradeId=" + gradeId + ", gName=" + gName + ", stuList="
? ? ? ? ? ? ? ? ? ? ? ? ? ? + stuList + "]";
? ? }
}
gradeId和GID明顯對應不上,但是修改列或者屬性名是不可取的,原因不多說。我們可以通過MyBatis的字段映射在不修改代碼的情況下完成這個需求,給它倆建立一種映射關系:
字段映射,當數據庫的列名和類的屬性名不一致時,需要通過建立映射關系使得它倆對應上。
返回的結果都是grade(自己取的typeAliases),只是多了一層映射關系。
<resultMap type="grade" id="mappingGid">
? ? ? ? <!-- 主鍵列用id標簽 -->
? ? ? ? <id property="gradeId" column="GID"/>
<!-- ? ? ? ? ? ? ? ??
? ? ? ? 非主鍵就用result: ? ? ? ? ? ? ? ?
? ? ? ? <result property="gName" column="gname"/> ? ? ? ? -
->
</resultMap>
<select id="queryAll" resultType="grade" resultMap="mappingGid">
? ? ? ? select * from grade
</select>
?restltMap屬性指向上邊定義的resultMap的id即可。resultMap標簽還有個autoMapping屬性,意思是自動映射,默認值是true,改成false的話就要手動指定需要建立映射關系的列以及屬性了。
二。多對一(many?to?one)?映射
表關系:?
grade表:GID、GNAME
student表:SID、SNAME、GID
GID是關聯grade表的外鍵。
多對一的視角:student?-->?grade。多個學生對應一個grade,一個學生只能有一個grade。
在設計Bean的時候,應該是這樣的:
public class Student {
?
?
? ? private String sId;
? ? private String sName;
? ? private Grade grade;
?
?
? ? public String getsId() {
? ? ? ? ? ? return sId;
? ? }
?
?
? ? public void setsId(String sId) {
? ? ? ? ? ? this.sId = sId;
? ? }
?
?
? ? public String getsName() {
? ? ? ? ? ? return sName;
? ? }
?
?
? ? public void setsName(String sName) {
? ? ? ? ? ? this.sName = sName;
? ? }
?
? ? public Grade getGrade() {
? ? ? ? ? ? return grade;
? ? }
?
?
? ? public void setGrade(Grade grade) {
?
? ? ? ? ? ? this.grade = grade;
?
? ? }
?
?
? ? @Override
? ? public String toString() {
? ? ? ? ? ? return "Student [sId=" + sId + ", sName=" + sName + ", grade=" + grade
? ? ? ? ? ? ? ? ? ? ? ? ? ? + "]";
? ? }
?
}
包含一個grade屬性,在查詢到學生信息的同時把對應的班級查出來并填充進去。當然用Java代碼編寫邏輯也是完全能夠實現的,但是有了MyBatis的結果集映射,我們并不需要編寫這樣的邏輯。確定好是一對多關系后,在映射文件中聲明映射關系。下面就把這個例子的代碼都貼上來吧:
Student映射接口:
import java.util.List;
import cn.et.lesson03.entity.Student;
public interface StudentMapper {
? ? <!-- 映射多對一關系 -->
?
? ? <resultMap type="student" id="mappingGrade">
?
? ? ? ? ? ? <association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
?
? ? </resultMap>
/* 根據ID查詢學生 */ public Student queryStuById(String sId); /*根據班級ID查詢學生*/ public List<Student> queryStusByGId(String gId);}
現在要調用queryStuById,返回一個student的同時,把這個student的grade屬性填充進去,也就是說還需要一個?select?*?from?grade?where?gid?=?x?這么一條SQL語句,定義在grade類對應的映射文件中:
? ? <select id="queryGradeByGid" resultType="grade">
?
? ? ? ? ? ? select * from grade where GID = #{gid}
?
? ? </select>
然后在Student類的映射文件中建立映射關系:
? ? <!-- 映射多對一關系 -->
?
? ? <resultMap type="student" id="mappingGrade">
?
? ? ? ? ? ? <association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
?
? ? </resultMap>
?type?=?查詢返回結果
?id?=?映射命名
association?=?聲明是多對一映射。
property="grade"?需要填充的屬性
column="gid"?外鍵列
select=?獲取對應的grade數據行的SQL語句,上上邊那個,語法格式:命名空間.聲明。
?映射接口中方法的SQL語句:
? ? <select id="queryStuById" resultType="student" resultMap="mappingGrade">
?
? ? ? ? ? ? select * from student where SID = #{0}
?
? ? </select>
?測試方法:
@Test
?
? ? public void mappingGrade() throws IOException{
?
? ? ? ? ? ? SqlSession session = getSession();
? ? ? ? ? ? StudentMapper mapper = session.getMapper(StudentMapper.class);
? ? ? ? ? ? Student student = mapper.queryStuById("1");
? ? ? ? ? ? System.out.println(student.getGrade());
}
結果:
流程:
????調用方法?-->?執行接口映射方法之前先執行resultMap?-->?
????通過association中的column外鍵,執行association對應的SQL語句獲取結果集,填充到
????property?-->?resultMap結束?-->?執行方法對應的SQL語句返回最終結果。
三。一對多映射(one?to?many)?
一對多映射很簡單,一個班級對應多個學生,查詢一個班級的同時獲取班級中的所有學生,填充到stuList屬性中:
把上面的例子反過來想就OK了。班級和學生在數據庫中的關系是主外鍵關聯,通過grade表的主鍵到student表查詢,需要一個這個的語句:select?*?from?student?where?GID?=?#{gid}。
這個語句在Student的映射文件中定義:
? ? <select id="queryStusByGId" resultType="student">
?
? ? ? ? ? ? select * from student where GID = #{gid}
?
? ? </select>
然后在Grade的映射文件中,定義結果集映射:
? ? <resultMap type="grade" id="mappingStuList">
?
? ? ? ? ? ? <collection property="stuList" javaType="arraylist" column="gid" select="cn.et.lesson03.xml.StudentMapper.queryStusByGId"></collection>
?
? ? </resultMap>
一對多關系用collection表示。
property?=?要填充的屬性
javaType?=?該屬性的數據類型
column?=?主鍵,studen表的外鍵
select?=?student映射文件中的語句:?select?*?from?student?where?GID?=?#{gid}
測試方法:
? ? @Testpublic void queryStu() throws IOException {
?
? ? ? ? ? ? SqlSession session = getSession();
?
? ? ? ? ? ? GradeMapper mapper = session.getMapper(GradeMapper.class);
?
? ? ? ? ? ? Grade grade = mapper.queryGradeById("1");
?
? ? ? ? ? ??
?
? ? ? ? ? ? List<Student> list = grade.getStuList();
?
? ? ? ? ? ? for (Student student : list) {
?
? ? ? ? ? ? ? ? ? ? System.out.println(student.getsId() + "---" + student.getsName());
?
? ? ? ? ? ? }
?
? ? }
運行結果:
四。基于注解實現的結果集映射
字段映射:
? ? @Results({
?
? ? @Result(column="SID" , property = "stuId" , id = true)})
?
? ? @Select("select * from student where sid = #{sId}")
?
? ? public Student queryStuById(String sId);
多對一映射:
? ? @Results({
?
? ? ? ? ? ? ? ? ? ? @Result(column = "SID", property = "stuId", id = true),
?
? ? ? ? ? ? ? ? ? ? @Result(property = "grade", column = "GID",?
?
? ? ? ? ? ? ? ? ? ? one = @One(select = "cn.et.lesson03.anno.GradeMapper.queryGradeById")) })
?
? ? @Select("select * from student where sid = #{sId}")
?
? ? public Student queryStuById(@Param("sId") String sId);
one表示多對一映射,多個學生屬于一個grade,指向的方法也是一個grade:
?@Select("select * from grade where GID = #{0}")
?
? ? public Grade queryGradeById(String gId);
一對多映射:
指向的方法返回值是個list,所以還要在映射聲明中指定一下javaType。
???
@Results({?
? ? @Result(column = "GID", property = "stuList", javaType = ArrayList.class,?
? ? ?many = @Many(select = "cn.et.lesson03.anno.StudentMapper.queryStusByGId")) })
?
? ? @Select("select * from grade where GID = #{0}")
?
? ? public Grade queryGradeById(String gId);
一對多用many表示,因為查詢結果是多條,指向方法:
? ? @Results({
?
? ? @Result(column = "SID" , property = "stuId")})
?
? ? @Select("select * from student where GID = #{param1}")
?
? ? public List<Student> queryStusByGId(String gId);
?
總結
以上是生活随笔為你收集整理的MyBatis -- 结果集映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 被5月GitHub Top20榜单惊呆了
- 下一篇: JSP JavaBean