MyBatis注解開發(fā)之實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢
一、使用注解實(shí)現(xiàn)自定義映射關(guān)系
當(dāng)POJO屬性名與數(shù)據(jù)庫列名不一致時(shí),需要自定義實(shí)體類和結(jié)果集的映射關(guān)系,在MyBatis注解開發(fā)中,使用 @Results 定義并使用自定義映射,使用 @ResultMap 使用自定義映射,用法如下:
前戲:為了體驗(yàn)這個效果,我們可以修改一下User實(shí)體類代碼,如下
package com.example.pojo;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String username1;
private String sex1;
private String address1;
public User(String programmer, String man, String shangHai) {
this.username1 = programmer;
this.sex1 = man;
this.address1 = shangHai;
}
public User(int i, String programmer_1, String woman, String shenzhen) {
this.id = i;
this.username1 = programmer_1;
this.sex1 = woman;
this.address1 = shenzhen;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername1() {
return username1;
}
public void setUsername1(String username1) {
this.username1 = username1;
}
public String getSex1() {
return sex1;
}
public void setSex1(String sex1) {
this.sex1 = sex1;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
@Override
public String toString() {
return "User[ " +
"id=" + id +
", username1='" + username1 + '\'' +
", sex1='" + sex1 + '\'' +
", address1='" + address1 + '\'' +
" ]";
}
}1. 編寫注解方法
// 查詢所有用戶
@Results(id="userDiyMapper",value = {
@Result(id = true,property = "id",column = "id"),
@Result(property = "username1",column = "username"),
@Result(property = "sex1",column = "sex"),
@Result(property = "address1",column = "address")
})
@Select("select * from user")
List<User> findAll1();
// 根據(jù)id查詢
@ResultMap("userDiyMapper")
@Select("select * from user where id = #{id}")
User findById(int id);注意?。哼@里property對應(yīng)的是實(shí)體類屬性名,column對應(yīng)的就是數(shù)據(jù)庫表的列名
2. 編寫測試方法
@Test
public void testFindAll1(){
List<User> all = userMapper.findAll1();
all.forEach(System.out::println);
System.out.println("---------------------");
System.out.println(userMapper.findById(5));
}看看能否查詢出所有用戶和id為5的用戶,并且留意對應(yīng)的屬性名
3. 查看運(yùn)行結(jié)果

OK,看來都是符合我們的預(yù)期的。
二、使用注解實(shí)現(xiàn)一對一關(guān)聯(lián)查詢
在MyBatis的注解開發(fā)中對于多表查詢只支持分解查詢,不支持連接查詢。
這里我們采用學(xué)生表和班級表做對比,所以我們先新建Student實(shí)體類和Classes實(shí)體類
Classes實(shí)體類
package com.example.pojo;
import java.util.List;
public class Classes {
private int cid;
private String className;
private List<Student> studentList;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public String toString() {
return "Classes[ " +
"cid=" + cid +
", className='" + className + '\'' +
", studentList=" + studentList +
" ]";
}
}Student實(shí)體類
package com.example.pojo;
public class Student {
private int sid;
private String name;
private int age;
private String sex;
private Classes classes;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
@Override
public String toString() {
return "Student[ " +
"sid=" + sid +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", classes=" + classes +
" ]";
}
}1. 編寫注解方法
StudentMapper添加查詢所有用戶
package com.example.mapper;
import com.example.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface StudentMapper {
@Select("select * from student")
// 自定義映射關(guān)系
@Results(id = "studentMapper",value = {
@Result(id = true,property = "sid",column = "sid"),
@Result(property = "name",column = "name"),
@Result(property = "age",column = "age"),
@Result(property = "sex",column = "sex"),
/**
* property:屬性名
* column:調(diào)用從表方法時(shí)傳入的參數(shù)列
* one:表示該屬性是一個對象
* select:調(diào)用的是從表方法
* fetchType:加載方式
*/
@Result(property = "classes",column = "classId",
one = @One(select = "com.example.mapper.ClassesMapper.findByCid",
fetchType = FetchType.EAGER)
)
})
List<Student> findAll();
}ClassesMapper添加根據(jù)id查詢班級
package com.example.mapper;
import com.example.pojo.Classes;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface ClassesMapper {
// 根據(jù)id查詢班級
@Select("select * from classes where cid = #{cid}")
Classes findByCid(Integer id);
}2. 編寫測試方法
// 測試一對一查詢
@Test
public void testFindAllStudent(){
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List<Student> all = studentMapper.findAll();
all.forEach(System.out::println);
}看看能否查詢出學(xué)生對應(yīng)的班級,如果可以則查詢成功
3. 查看運(yùn)行結(jié)果

OK,看圖我們是已經(jīng)成功查詢出每個學(xué)生對應(yīng)的班級的
三、使用注解實(shí)現(xiàn)一對多關(guān)聯(lián)查詢
在這里我們主要實(shí)現(xiàn)查詢所有班級的時(shí)候把對應(yīng)的學(xué)生列表也查詢出來。
1. 編寫注解方法
StudentMapper添加根據(jù)班級id查詢學(xué)生
// 根據(jù)班級Id查詢學(xué)生
@Select("select * from student where ClassId = #{classId}")
List<Student> findByClassId(int classId);Classes添加查詢所有班級
// 查詢所有班級
@Select("select * from classes")
@Results(id = "classMapper",value = {
@Result(id = true,property = "cid",column = "cid"),
@Result(property = "className",column = "className"),
// many:表示該屬性是一個集合
@Result(property = "studentList",column = "cid",
many = @Many(select = "com.example.mapper.StudentMapper.findByClassId",
fetchType = FetchType.LAZY))
})
List<Classes> findAll();2. 編寫測試方法
// 測試一對多查詢
@Test
public void findAllClasses(){
ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
List<Classes> all = classesMapper.findAll();
all.forEach(System.out::println);
}觀察能否查詢出班級對應(yīng)的學(xué)生列表
3. 查看運(yùn)行結(jié)果

OK,確實(shí)也是可以查詢出來了的。
四、注解文件和映射文件開發(fā)對比
注解開發(fā)更快,映射文件更方便。
MyBatis中更推薦使用映射文件開發(fā),Spring、SpringBoot更推薦注解方式。具體使用要視項(xiàng)目情況而定。它們的優(yōu)點(diǎn)對比如下:
映射文件:
- 代碼與Sql語句是解耦的,修改時(shí)只需修改配置文件,無需修改源碼。
- Sql語句集中,利于快速了解和維護(hù)項(xiàng)目。
- 級聯(lián)查詢支持連接查詢和分解查詢兩種方式,注解開發(fā)只支持分解查詢。
注解:
- 配置簡單,開發(fā)效率高。
- 類型安全,在編譯期即可進(jìn)行校驗(yàn),不用等到運(yùn)行時(shí)才發(fā)現(xiàn)錯誤。
我個人也是比較喜歡映射文件開發(fā),主要更喜歡方便維護(hù)和了解。
到此這篇關(guān)于MyBatis注解開發(fā)之實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢的文章就介紹到這了,更多相關(guān)MyBatis自定義映射和關(guān)聯(lián)查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別
這篇文章主要給大家介紹了關(guān)于Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Java數(shù)據(jù)結(jié)構(gòu)之簡單鏈表的定義與實(shí)現(xiàn)方法示例
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之簡單鏈表的定義與實(shí)現(xiàn)方法,簡單描述了鏈接的概念、原理,并結(jié)合實(shí)例形式分析了java定義與使用鏈表的相關(guān)步驟與操作技巧,需要的朋友可以參考下2017-10-10
Springboot中使用Redisson+AOP+自定義注解實(shí)現(xiàn)訪問限流與黑名單攔截
本文主要介紹了Springboot中使用Redisson+AOP+自定義注解實(shí)現(xiàn)訪問限流與黑名單攔截,包含針對用戶IP限流,整個接口的訪問限流,以及對某個參數(shù)字段的限流,并且支持請求限流后處理回調(diào),感興趣的可以了解一下2024-02-02
Java實(shí)現(xiàn)查找文件和替換文件內(nèi)容
這篇文章主要為大家詳細(xì)介紹了Java語言如何實(shí)現(xiàn)查找文件和替換文件內(nèi)容功能,文中的示例代碼講解詳細(xì),感興趣的可以跟隨小編一起學(xué)習(xí)一下2022-08-08
Java劍指offer之刪除鏈表的節(jié)點(diǎn)
這篇文章主要介紹了Java劍指offer之刪除鏈表的節(jié)點(diǎn),給定單向鏈表的頭指針和一個要刪除的節(jié)點(diǎn)的值,定義一個函數(shù)刪除該節(jié)點(diǎn)。返回刪除后的鏈表的頭節(jié)點(diǎn),下文更多相關(guān)內(nèi)容介紹,需要的小伙伴可以參考一下2022-04-04
使用遞歸算法結(jié)合數(shù)據(jù)庫解析成Java樹形結(jié)構(gòu)的代碼解析
這篇文章主要介紹了使用遞歸算法結(jié)合數(shù)據(jù)庫解析成Java樹形結(jié)構(gòu)的代碼解析的相關(guān)資料,需要的朋友可以參考下2017-09-09

