首頁>技術>

mybatis中的多表查詢:	示例:使用者和角色		一個使用者可以有多個角色		一個角色可以賦予多個使用者	步驟:		1、建立兩張表:使用者表,角色表			讓使用者表和角色表具有多對多的關係。需要使用中間表,中間表中包含各自的主鍵,在中間表中是外來鍵。		2、建立兩個實體類:使用者實體類和角色實體類			讓使用者和角色的實體類能體現出來多對多的關係			各自包含對方一個集合引用		3、建立兩個配置檔案			使用者的配置檔案			角色的配置檔案		4、實現配置:			當我們查詢使用者時,可以同時得到使用者所包含的角色資訊			當我們查詢角色時,可以同時得到角色的所賦予的使用者資訊1234567891011121314151617
專案目錄結構實現 Role 到 User 多對多

多對多關係其實我們看成是雙向的一對多關係。

業務要求

需求:當我們查詢角色時,可以同時得到角色的所賦予的使用者資訊。分析:查詢角色我們需要用到Role表,但角色分配的使用者的資訊我們並不能直接找到使用者資訊,而是要透過中間表(USER_ROLE 表)才能關聯到使用者資訊。

使用者與角色的關係模型

使用者與角色的多對多關係模型如下:

角色表:

使用者表:

使用者角色中間表:

編寫角色實體類

Role:

package com.keafmd.domain;import java.io.Serializable;import java.util.List;/** * Keafmd * * @ClassName: Role * @Description: 角色實體類 * @author: 牛哄哄的柯南 * @date: 2021-02-12 16:45 */public class Role implements Serializable {    private Integer 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 Integer getRoleId() {        return roleId;    }    public void setRoleId(Integer 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 + '\'' +                '}';    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
編寫 Role 持久層介面

IRoleDao:

package com.keafmd.dao;import com.keafmd.domain.Role;import java.util.List;/** * Keafmd * * @ClassName: IRoleDao * @Description: * @author: 牛哄哄的柯南 * @date: 2021-02-12 19:01 */public interface IRoleDao {    /**     * 查詢所有角色     * @return     */    List<Role> findAll();}12345678910111213141516171819202122
實現的 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 u.id=ur.uid 123

執行結果:

注意:sql語句換行的時候最好在每行的末尾或開頭新增空格,這樣可以防止合併成一行時發生錯誤。

編寫對映檔案

IRoleDao.xml:

package com.keafmd.test;import com.keafmd.dao.IRoleDao;import com.keafmd.dao.IUserDao;import com.keafmd.domain.Role;import com.keafmd.domain.User;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.io.InputStream;import java.util.List;/** * Keafmd * * @ClassName: MybatisTest * @Description: 測試類,測試crud操作 * @author: 牛哄哄的柯南 * @date: 2021-02-08 15:24 */public class RoleTest {    private InputStream in;    private SqlSession sqlsession;    private IRoleDao roleDao;    @Before // 用於在測試方法執行前執行    public void init()throws Exception{        //1.讀取配置檔案,生成位元組輸入流        in = Resources.getResourceAsStream("SqlMapConfig.xml");        //2.建立SqlSessionFactory工廠        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();        SqlSessionFactory factory = builder.build(in);        //3.使用工廠生產SqlSession物件        sqlsession = factory.openSession(); //裡面寫個true,下面每次就不用了寫 sqlsession.commit(); 了        //4.使用SqlSession建立Dao介面的代理物件        roleDao = sqlsession.getMapper(IRoleDao.class);    }    @After // 用於在測試方法執行後執行    public void destory() throws Exception{        //提交事務        sqlsession.commit();        //6.釋放資源        sqlsession.close();        in.close();    }    /**     * 查詢所有     * @throws Exception     */    @Test    public void testFindAll() {        List<Role> roles = roleDao.findAll();        for (Role role : roles) {            System.out.println("--------每個角色的資訊---------");            System.out.println(role);            System.out.println(role.getUsers());                   }    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071

執行結果:

2021-02-13 00:05:47,481 349    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Opening JDBC Connection2021-02-13 00:05:47,784 652    [           main] DEBUG source.pooled.PooledDataSource  - Created connection 1027007693.2021-02-13 00:05:47,784 652    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:05:47,791 659    [           main] DEBUG om.keafmd.dao.IRoleDao.findAll  - ==>  Preparing: 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 u.id=ur.uid2021-02-13 00:05:47,842 710    [           main] DEBUG om.keafmd.dao.IRoleDao.findAll  - ==> Parameters: 2021-02-13 00:05:47,869 737    [           main] DEBUG om.keafmd.dao.IRoleDao.findAll  - <==      Total: 4--------每個角色的資訊---------Role{roleId=1, roleName='院長', roleDesc='管理整個學院'}[User{id=41, username='老王', sex='男', address='北京', birthday=Tue Feb 27 17:47:08 CST 2018}, User{id=45, username='新一', sex='男', address='北京', birthday=Sun Mar 04 12:04:06 CST 2018}]--------每個角色的資訊---------Role{roleId=2, roleName='總裁', roleDesc='管理整個公司'}[User{id=41, username='老王', sex='男', address='北京', birthday=Tue Feb 27 17:47:08 CST 2018}]--------每個角色的資訊---------Role{roleId=3, roleName='校長', roleDesc='管理整個學校'}[]2021-02-13 00:05:47,871 739    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:05:47,872 740    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:05:47,872 740    [           main] DEBUG source.pooled.PooledDataSource  - Returned connection 1027007693 to pool.Process finished with exit code 01234567891011121314151617181920
實現 User 到 Role 的多對多業務要求

需求:當我們查詢使用者時,可以同時得到使用者所包含的角色資訊。分析:相比上面的實現 Role 到 User 多對多,主要變化就是sql語句的變化。

編寫使用者實體類

User:

package com.keafmd.domain;import java.io.Serializable;import java.util.Date;import java.util.List;/** * Keafmd * * @ClassName: User * @Description: * @author: 牛哄哄的柯南 * @date: 2021-02-08 15:16 */public class User implements Serializable {    private Integer id;    private String username;    private String sex;    private String address;    private Date birthday;    //多對多的關係對映,一個使用者可以具備多個角色    private List<Role> roles;    public List<Role> getRoles() {        return roles;    }    public void setRoles(List<Role> roles) {        this.roles = roles;    }    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 getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }    public Date getBirthday() {        return birthday;    }    public void setBirthday(Date birthday) {        this.birthday = birthday;    }    @Override    public String toString() {        return "User{" +                "id=" + id +                ", username='" + username + '\'' +                ", sex='" + sex + '\'' +                ", address='" + address + '\'' +                ", birthday=" + birthday +                '}';    }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
編寫 User持久層介面

IUserDao:

package com.keafmd.dao;import com.keafmd.domain.User;import java.util.List;/** * Keafmd * * @ClassName: IUserDao * @Description: 使用者的持久層介面 * @author: 牛哄哄的柯南 * @date: 2021-02-06 19:29 */public interface IUserDao {    /**     * 查詢所有使用者,同時獲取到使用者下所有賬戶的資訊     * @return     */    List<User> findAll();}1234567891011121314151617181920212223
實現的 SQL 語句
   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 r.id=ur.rid 123

執行結果:

編寫對映檔案

IUserDao.xml:

package com.keafmd.test;import com.keafmd.dao.IUserDao;import com.keafmd.domain.User;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.io.InputStream;import java.util.List;/** * Keafmd * * @ClassName: MybatisTest * @Description: 測試類,測試crud操作 * @author: 牛哄哄的柯南 * @date: 2021-02-08 15:24 */public class UserTest {    private InputStream in;    private SqlSession sqlsession;    private IUserDao userDao;    @Before // 用於在測試方法執行前執行    public void init()throws Exception{        //1.讀取配置檔案,生成位元組輸入流        in = Resources.getResourceAsStream("SqlMapConfig.xml");        //2.建立SqlSessionFactory工廠        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();        SqlSessionFactory factory = builder.build(in);        //3.使用工廠生產SqlSession物件        sqlsession = factory.openSession(); //裡面寫個true,下面每次就不用了寫 sqlsession.commit(); 了        //4.使用SqlSession建立Dao介面的代理物件        userDao = sqlsession.getMapper(IUserDao.class);    }    @After // 用於在測試方法執行後執行    public void destory() throws Exception{        //提交事務        sqlsession.commit();        //6.釋放資源        sqlsession.close();        in.close();    }    /**     * 查詢所有     * @throws Exception     */    @Test    public void testFindAll() {        List<User> users = userDao.findAll();        for (User user : users) {            System.out.println("--------每個使用者的資訊---------");            System.out.println(user);            System.out.println(user.getRoles());        }    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

執行結果:

2021-02-13 00:17:32,971 422    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Opening JDBC Connection2021-02-13 00:17:33,275 726    [           main] DEBUG source.pooled.PooledDataSource  - Created connection 1027007693.2021-02-13 00:17:33,275 726    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:17:33,280 731    [           main] DEBUG om.keafmd.dao.IUserDao.findAll  - ==>  Preparing: 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 r.id=ur.rid2021-02-13 00:17:33,319 770    [           main] DEBUG om.keafmd.dao.IUserDao.findAll  - ==> Parameters: 2021-02-13 00:17:33,343 794    [           main] DEBUG om.keafmd.dao.IUserDao.findAll  - <==      Total: 10--------每個使用者的資訊---------User{id=41, username='老王', sex='男', address='北京', birthday=Tue Feb 27 17:47:08 CST 2018}[Role{roleId=1, roleName='院長', roleDesc='管理整個學院'}, Role{roleId=2, roleName='總裁', roleDesc='管理整個公司'}]--------每個使用者的資訊---------User{id=42, username='update', sex='男', address='XXXXXXX', birthday=Mon Feb 08 19:37:31 CST 2021}[]--------每個使用者的資訊---------User{id=43, username='小二王', sex='女', address='北京', birthday=Sun Mar 04 11:34:34 CST 2018}[]--------每個使用者的資訊---------User{id=45, username='新一', sex='男', address='北京', birthday=Sun Mar 04 12:04:06 CST 2018}[Role{roleId=1, roleName='院長', roleDesc='管理整個學院'}]--------每個使用者的資訊---------User{id=50, username='Keafmd', sex='男', address='XXXXXXX', birthday=Mon Feb 08 15:44:01 CST 2021}[]--------每個使用者的資訊---------User{id=51, username='update DAO', sex='男', address='XXXXXXX', birthday=Tue Feb 09 11:31:38 CST 2021}[]--------每個使用者的資訊---------User{id=52, username='Keafmd DAO', sex='男', address='XXXXXXX', birthday=Tue Feb 09 11:29:41 CST 2021}[]--------每個使用者的資訊---------User{id=53, username='Keafmd laset insertid 1', sex='男', address='XXXXXXX', birthday=Fri Feb 12 20:53:46 CST 2021}[]--------每個使用者的資訊---------User{id=54, username='Keafmd laset insertid 2 auto', sex='男', address='XXXXXXX', birthday=Fri Feb 12 21:02:12 CST 2021}[]2021-02-13 00:17:33,345 796    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:17:33,346 797    [           main] DEBUG ansaction.jdbc.JdbcTransaction  - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3d36e4cd]2021-02-13 00:17:33,346 797    [           main] DEBUG source.pooled.PooledDataSource  - Returned connection 1027007693 to pool.Process finished with exit code 01234567891011121314151617181920212223242526272829303132333435363738

以上就是Mybatis的多表關聯查詢(多對多)的全部內容。

14
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Matlab函式的基本使用