mybatis多對多查詢的實(shí)現(xiàn)(xml方式和注解方式)
前言
前面總結(jié)了一對一,多對一和一對多的多表查詢,今天總結(jié)一下多對多的mybatis多表查詢。同樣有xml方式和注解方式,步驟和前兩種查詢差不多,最主要的區(qū)別就在表和sql語句上了。
數(shù)據(jù)庫表及關(guān)系
這里采用用戶和角色的例子
一個(gè)用戶可以有多個(gè)角色
一個(gè)角色可以賦予多個(gè)用戶
在進(jìn)行多表查詢時(shí),我們需要一張中間表,中間表中包含各自的主鍵,在中間表中是外鍵。
多對多查詢(xml方式)
這次我們首先清理一下思路,我們先在數(shù)據(jù)庫里把我們需要的數(shù)據(jù)查出來再寫代碼。
我們查詢用戶時(shí)要同時(shí)查出其對應(yīng)的角色,借助中間表,根據(jù)UID查詢RID,再根據(jù)RID查詢角色表,中間表的數(shù)據(jù)我們不需要,所以不顯示。
這里我們可以用左外連接來進(jìn)行多表的查詢,查詢所有用戶,用戶有角色信息就連接到該用戶后面,沒有則為空。
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語句也只要換一下連接順序。
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里加入多對多實(shí)體映射
public class Role implements Serializable { private String roleId; private String roleName; private String roleDesc; //多對多映射關(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; //多對多映射關(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語句
<!--定義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é)果
注解方式
思路是一樣的,但我們使用注解時(shí),不能像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查詢一個(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); }
最終的測試結(jié)果和上面一樣。
到此這篇關(guān)于mybatis多對多查詢的實(shí)現(xiàn)(xml方式和注解方式)的文章就介紹到這了,更多相關(guān)mybatis多對多查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea 訪問html頁面端口號(hào)顯示的是63342而不是8080
這篇文章主要介紹了idea 訪問html頁面端口號(hào)顯示的是63342而不是8080,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08java實(shí)現(xiàn)遺傳算法實(shí)例分享(打印城市信息)
本文介紹java實(shí)現(xiàn)遺傳算法的實(shí)例,代碼中使用城市名做為數(shù)據(jù),可以打印當(dāng)前代數(shù)的所有城市序列,以及其相關(guān)的參數(shù),大家參考使用吧2014-01-01hadoop的hdfs文件操作實(shí)現(xiàn)上傳文件到hdfs
這篇文章主要介紹了使用hadoop的API對HDFS上的文件訪問,其中包括上傳文件到HDFS上、從HDFS上下載文件和刪除HDFS上的文件,需要的朋友可以參考下2014-03-03基于Spring@Autowired注解與自動(dòng)裝配詳談
下面小編就為大家?guī)硪黄赟pring@Autowired注解與自動(dòng)裝配詳談。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10