mybatis如何使用註解實現一對多關聯查詢
mybatis 註解實現一對多關聯查詢
@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方式和註解方式)
前面總結瞭一對一,多對一和一對多的多表查詢,今天總結一下多對多的mybatis多表查詢。同樣有xml方式和註解方式,步驟和前兩種查詢差不多,最主要的區別就在表和sql語句上瞭。
數據庫表及關系
這裡采用用戶和角色的例子
一個用戶可以有多個角色
一個角色可以賦予多個用戶
在進行多表查詢時,我們需要一張中間表,中間表中包含各自的主鍵,在中間表中是外鍵。
多對多查詢(xml方式)
這次我們首先清理一下思路,我們先在數據庫裡把我們需要的數據查出來再寫代碼。
我們查詢用戶時要同時查出其對應的角色,借助中間表,根據UID查詢RID,再根據RID查詢角色表,中間表的數據我們不需要,所以不顯示。
這裡我們可以用左外連接來進行多表的查詢,查詢所有用戶,用戶有角色信息就連接到該用戶後面,沒有則為空。
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
查詢出來結果後剩下的內容就很簡單。
在User和role裡加入多對多實體映射
public class Role implements Serializable { private String roleId; private String roleName; private String roleDesc; //多對多映射關系,一個角色有多個用戶 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; //多對多映射關系,一個用戶具備多個角色 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>
測試結果
註解方式
思路是一樣的,但我們使用註解時,不能像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(); /** * 根據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); }
最終的測試結果和上面一樣。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- MyBatis多表操作查詢功能
- Java Mybatis框架多表操作與註解開發詳解分析
- mybatis多表查詢的實現(xml方式)
- Mybatis中resultMap的Colum和property屬性詳解
- Oracle多表查詢中間表的創建實例教程