mybatis如何使用注解實(shí)現(xiàn)一對(duì)多關(guān)聯(lián)查詢
mybatis 注解實(shí)現(xiàn)一對(duì)多關(guān)聯(lián)查詢
@Select("select id,mockexam_section as section,id as sectionId"
+ " from t_p_qb_mockexam_section"
+ " where mockexam_charpter_id = #{charpterId} and is_delete = 0"
+ " order by mockexam_section_idx asc")
@Results({
@Result(property = "questionList",column = "sectionId",many = @Many(select = "com.zikaoshu.baseinfo.mapper.BaseinfoQuestionMapper.listQuestionResDto"))})
List<SectionQuestionDto> listSectionQuestionDto(@Param("charpterId") Integer charpterId);
@Select("select id,type,discuss_title as discussTitle,stem1,material,a,b,c,d,e,answer,analysis,mockeaxm_section_id as sectionId"
+ " from t_p_qb_question_mockexam"
+ " where mockeaxm_section_id = #{id} and is_delete = 0"
+ " order by q_sequence,gmt_create asc")
List<QuestionResDto> listQuestionResDto(@Param("id") Integer id);
mybatis多對(duì)多查詢(xml方式和注解方式)
前面總結(jié)了一對(duì)一,多對(duì)一和一對(duì)多的多表查詢,今天總結(jié)一下多對(duì)多的mybatis多表查詢。同樣有xml方式和注解方式,步驟和前兩種查詢差不多,最主要的區(qū)別就在表和sql語(yǔ)句上了。
數(shù)據(jù)庫(kù)表及關(guān)系
這里采用用戶和角色的例子
一個(gè)用戶可以有多個(gè)角色
一個(gè)角色可以賦予多個(gè)用戶
在進(jìn)行多表查詢時(shí),我們需要一張中間表,中間表中包含各自的主鍵,在中間表中是外鍵。



多對(duì)多查詢(xml方式)
這次我們首先清理一下思路,我們先在數(shù)據(jù)庫(kù)里把我們需要的數(shù)據(jù)查出來(lái)再寫代碼。
我們查詢用戶時(shí)要同時(shí)查出其對(duì)應(yīng)的角色,借助中間表,根據(jù)UID查詢RID,再根據(jù)RID查詢角色表,中間表的數(shù)據(jù)我們不需要,所以不顯示。
這里我們可以用左外連接來(lái)進(jìn)行多表的查詢,查詢所有用戶,用戶有角色信息就連接到該用戶后面,沒(méi)有則為空。
select u.*,r.id as rid,r.ROLE_NAME,r.ROLE_DESC from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on ur.rid = r.id

當(dāng)我們查詢角色想要得到相應(yīng)的用戶時(shí)道理是一樣的,SQL語(yǔ)句也只要換一下連接順序。
select u.*,r.id as rid,r.ROLE_NAME,r.ROLE_DESC from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id

查詢出來(lái)結(jié)果后剩下的內(nèi)容就很簡(jiǎn)單。
在User和role里加入多對(duì)多實(shí)體映射
public class Role implements Serializable {
private String roleId;
private String roleName;
private String roleDesc;
//多對(duì)多映射關(guān)系,一個(gè)角色有多個(gè)用戶
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "role{" +
"roleId='" + roleId + '\'' +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
public class User implements Serializable{
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
//多對(duì)多映射關(guān)系,一個(gè)用戶具備多個(gè)角色
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
然后配置xml,配置映射封裝和sql語(yǔ)句
<!--定義resultMap-->
<resultMap id="userWithRole" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置角色映射-->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<!--查詢所有用戶信息-->
<select id="findAll" resultMap="userWithRole">
select u.*,r.id as rid,r.ROLE_NAME,r.ROLE_DESC from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on ur.rid = r.id
</select>
<resultMap id="roleUserMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="users" ofType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</collection>
</resultMap>
<!--查詢所有角色信息-->
<select id="findAll" resultMap="roleUserMap">
select u.*,r.id as rid,r.ROLE_NAME,r.ROLE_DESC from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id
</select>
測(cè)試結(jié)果


注解方式
思路是一樣的,但我們使用注解時(shí),不能像xml方式一樣只使用一條sql語(yǔ)句完成直接封裝,所以這里要按上面說(shuō)的思路完成分步查詢。
public interface IUserDao {
/**
* 查詢所有操作,并攜帶賬戶信息
* @return
*/
@Select("select * from user")
@Results(id = "userRoleMap",value = {
//id表示主鍵
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
@Result(property = "roles",column = "id",many = @Many(select = "com.itcc.dao.IRoleDao.findByUid",fetchType = FetchType.LAZY))
})
List<User> findAll();
/**
* 根據(jù)id查詢一個(gè)用戶
* @param rid
*/
@Select("select * from user where id in(select uid from user_role where rid = #{rid})")
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday")
})
List<User> findByRId(Integer rid);
}
public interface IRoleDao {
/**
* 查詢所有角色信息
* @return
*/
@Select("select * from role")
@Results({
@Result(id = true,column = "id",property = "roleId"),
@Result(column = "role_name",property = "roleName"),
@Result(column = "role_desc",property = "roleDesc"),
@Result(property = "users",column = "id",many = @Many(select = "com.itcc.dao.IUserDao.findByRId",fetchType = FetchType.LAZY))
})
List<Role> findAll();
@Select("select * from role where ID in(select rid from user_role where uid = #{uid})")
@Results({
@Result(id = true,column = "id",property = "roleId"),
@Result(column = "role_name",property = "roleName"),
@Result(column = "role_desc",property = "roleDesc")
})
List<Role> findByUid(String uid);
}
最終的測(cè)試結(jié)果和上面一樣。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 關(guān)于QueryWrapper,實(shí)現(xiàn)MybatisPlus多表關(guān)聯(lián)查詢方式
- Mybatis多表關(guān)聯(lián)查詢的實(shí)現(xiàn)(DEMO)
- Mybatis 一對(duì)多和多對(duì)一關(guān)聯(lián)查詢問(wèn)題
- mybatis-plus多表關(guān)聯(lián)查詢功能的實(shí)現(xiàn)
- MyBatis實(shí)踐之動(dòng)態(tài)SQL及關(guān)聯(lián)查詢
- MyBatis 三表外關(guān)聯(lián)查詢的實(shí)現(xiàn)(用戶、角色、權(quán)限)
- Mybatis關(guān)聯(lián)查詢之一對(duì)多和多對(duì)一XML配置詳解
- Mybatis實(shí)現(xiàn)一對(duì)一、一對(duì)多關(guān)聯(lián)查詢的方法(示例詳解)
- Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析
- MyBatis的關(guān)聯(lián)查詢實(shí)現(xiàn)(一對(duì)一、一對(duì)多、多對(duì)多)
相關(guān)文章
Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細(xì)解讀
這篇文章主要介紹了Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細(xì)解讀,UDP協(xié)議全稱是用戶數(shù)據(jù)報(bào)協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無(wú)連接的協(xié)議,在OSI模型中,在第四層——傳輸層,處于IP協(xié)議的上一層,需要的朋友可以參考下2023-12-12
Java中的包(Package)與導(dǎo)入(Import)示例詳解
這篇文章主要詳細(xì)介紹了Java中的包(Package)和導(dǎo)入(Import)概念,包括包的定義、作用、JDK中主要的包、導(dǎo)入的目的與用法、特殊情況的導(dǎo)入、靜態(tài)導(dǎo)入、包的訪問(wèn)權(quán)限和命名規(guī)范,文章通過(guò)豐富的解釋和代碼示例,幫助讀者深入理解這些概念的實(shí)際應(yīng)用,需要的朋友可以參考下2024-11-11
將SpringBoot的Jar注冊(cè)成Windows服務(wù)的實(shí)現(xiàn)方法
當(dāng)前項(xiàng)目有個(gè)地圖編輯器,后端用的是SpringBoot框架,外網(wǎng)剛好有一臺(tái)空閑的Windows服務(wù)器就直接拿來(lái)用了,將Java程序部署成Windows服務(wù)可以用WinSW (Windows Service Wrapper)來(lái)實(shí)現(xiàn),文中有詳細(xì)的操作步驟,需要的朋友可以參考下2023-11-11
mybatis動(dòng)態(tài)sql之新增與更新方式
這篇文章主要介紹了mybatis動(dòng)態(tài)sql之新增與更新方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
關(guān)于Mybatis和JDBC的使用及區(qū)別
這篇文章主要介紹了關(guān)于Mybatis和JDBC的使用及區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
MyEclipse 2016 CI 4新增BootStrap模板
MyEclipse2016是一款全球使用最為廣泛的企業(yè)級(jí)開發(fā)環(huán)境程序,這篇文章主要介紹了MyEclipse 2016 CI 4新增BootStrap模板的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
深入了解Maven Settings.xml文件的結(jié)構(gòu)和功能
這篇文章主要為大家介紹了Maven Settings.xml文件基本結(jié)構(gòu)和功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
深入了解Java中循環(huán)結(jié)構(gòu)的使用
Java中有三種主要的循環(huán)結(jié)構(gòu):while 循環(huán)、do…while 循環(huán)和for 循環(huán)。本文將來(lái)和大家一起講講Java中這三個(gè)循環(huán)的使用,需要的可以參考一下2022-08-08
mybatis插入數(shù)據(jù)后返回自增主鍵ID的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了mybatis插入數(shù)據(jù)后返回自增主鍵ID的兩種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

