mybatis如何使用注解實現(xiàn)一對多關(guān)聯(lián)查詢
mybatis 注解實現(xiàn)一對多關(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多對多查詢(xml方式和注解方式)
前面總結(jié)了一對一,多對一和一對多的多表查詢,今天總結(jié)一下多對多的mybatis多表查詢。同樣有xml方式和注解方式,步驟和前兩種查詢差不多,最主要的區(qū)別就在表和sql語句上了。
數(shù)據(jù)庫表及關(guān)系
這里采用用戶和角色的例子
一個用戶可以有多個角色
一個角色可以賦予多個用戶
在進行多表查詢時,我們需要一張中間表,中間表中包含各自的主鍵,在中間表中是外鍵。



多對多查詢(xml方式)
這次我們首先清理一下思路,我們先在數(shù)據(jù)庫里把我們需要的數(shù)據(jù)查出來再寫代碼。
我們查詢用戶時要同時查出其對應的角色,借助中間表,根據(jù)UID查詢RID,再根據(jù)RID查詢角色表,中間表的數(shù)據(jù)我們不需要,所以不顯示。
這里我們可以用左外連接來進行多表的查詢,查詢所有用戶,用戶有角色信息就連接到該用戶后面,沒有則為空。
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

當我們查詢角色想要得到相應的用戶時道理是一樣的,SQL語句也只要換一下連接順序。
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

查詢出來結(jié)果后剩下的內(nèi)容就很簡單。
在User和role里加入多對多實體映射
public class Role implements Serializable {
private String roleId;
private String roleName;
private String roleDesc;
//多對多映射關(guān)系,一個角色有多個用戶
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;
//多對多映射關(guān)系,一個用戶具備多個角色
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語句
<!--定義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>
測試結(jié)果


注解方式
思路是一樣的,但我們使用注解時,不能像xml方式一樣只使用一條sql語句完成直接封裝,所以這里要按上面說的思路完成分步查詢。
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查詢一個用戶
* @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);
}
最終的測試結(jié)果和上面一樣。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- 關(guān)于QueryWrapper,實現(xiàn)MybatisPlus多表關(guān)聯(lián)查詢方式
- Mybatis多表關(guān)聯(lián)查詢的實現(xiàn)(DEMO)
- Mybatis 一對多和多對一關(guān)聯(lián)查詢問題
- mybatis-plus多表關(guān)聯(lián)查詢功能的實現(xiàn)
- MyBatis實踐之動態(tài)SQL及關(guān)聯(lián)查詢
- MyBatis 三表外關(guān)聯(lián)查詢的實現(xiàn)(用戶、角色、權(quán)限)
- Mybatis關(guān)聯(lián)查詢之一對多和多對一XML配置詳解
- Mybatis實現(xiàn)一對一、一對多關(guān)聯(lián)查詢的方法(示例詳解)
- Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析
- MyBatis的關(guān)聯(lián)查詢實現(xiàn)(一對一、一對多、多對多)
相關(guān)文章
Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細解讀
這篇文章主要介紹了Java網(wǎng)絡(luò)編程之UDP協(xié)議詳細解讀,UDP協(xié)議全稱是用戶數(shù)據(jù)報協(xié)議,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無連接的協(xié)議,在OSI模型中,在第四層——傳輸層,處于IP協(xié)議的上一層,需要的朋友可以參考下2023-12-12
Java中的包(Package)與導入(Import)示例詳解
這篇文章主要詳細介紹了Java中的包(Package)和導入(Import)概念,包括包的定義、作用、JDK中主要的包、導入的目的與用法、特殊情況的導入、靜態(tài)導入、包的訪問權(quán)限和命名規(guī)范,文章通過豐富的解釋和代碼示例,幫助讀者深入理解這些概念的實際應用,需要的朋友可以參考下2024-11-11
將SpringBoot的Jar注冊成Windows服務的實現(xiàn)方法
當前項目有個地圖編輯器,后端用的是SpringBoot框架,外網(wǎng)剛好有一臺空閑的Windows服務器就直接拿來用了,將Java程序部署成Windows服務可以用WinSW (Windows Service Wrapper)來實現(xiàn),文中有詳細的操作步驟,需要的朋友可以參考下2023-11-11
關(guān)于Mybatis和JDBC的使用及區(qū)別
這篇文章主要介紹了關(guān)于Mybatis和JDBC的使用及區(qū)別,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
MyEclipse 2016 CI 4新增BootStrap模板
MyEclipse2016是一款全球使用最為廣泛的企業(yè)級開發(fā)環(huán)境程序,這篇文章主要介紹了MyEclipse 2016 CI 4新增BootStrap模板的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06
深入了解Maven Settings.xml文件的結(jié)構(gòu)和功能
這篇文章主要為大家介紹了Maven Settings.xml文件基本結(jié)構(gòu)和功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪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)。本文將來和大家一起講講Java中這三個循環(huán)的使用,需要的可以參考一下2022-08-08
mybatis插入數(shù)據(jù)后返回自增主鍵ID的兩種實現(xiàn)方式
這篇文章主要介紹了mybatis插入數(shù)據(jù)后返回自增主鍵ID的兩種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05

