Mybatis入门笔记(9)——多表操作之多对多

多对多

需求:

用户和角色

​ 一个用户可以有多个角色

​ 一个角色可以赋予多个用户

分析:

  1. User表和Role表具有多对多关系,需要使用中间表,中间表中包含各自的主键,在中间表中是外键;
  2. 建立两个实体类:用户实体类中包含对角色的集合引用,角色实体类中包含对用户的集合引用;
  3. 建立两个配置文件:用户的配置文件和角色的配置文件;
  4. 实现功能:
    1. 查询用户时,同时得到用户所包含的角色信息;
    2. 查询角色时,同时得到角色对应的用户信息;

先建立单表查询Role表的所有信息,步骤如下:

  1. 往数据库中插入两张表:role表和user_role表

    DROP TABLE IF EXISTS `role`;
    
    CREATE TABLE `role` (
      `ID` int(11) NOT NULL COMMENT '编号',
      `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
      `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
      PRIMARY KEY  (`ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');
    
    DROP TABLE IF EXISTS `user_role`;
    
    CREATE TABLE `user_role` (
      `UID` int(11) NOT NULL COMMENT '用户编号',
      `RID` int(11) NOT NULL COMMENT '角色编号',
      PRIMARY KEY  (`UID`,`RID`),
      KEY `FK_Reference_10` (`RID`),
      CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
      CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    insert  into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
    
    
  2. 创建Role的实体类;

    public class Role implements Serializable {
    
        private int roleId;
        private String roleName;
        private String roleDesc;
    
        public int getRoleId() {
            return roleId;
        }
    
        public void setRoleId(int 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 + '\'' +
                    '}';
        }
    }
    
  3. 创建Dao接口

    public interface IRoleDao {
       //查询所有用户
       List<Role> findAll(); 
    }
    
  4. 编写映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ben.dao.IRoleDao">
        <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
        <resultMap id="roleMap" type="role">
            <!--id唯一标识,type:对应的对象-->
            <!-- 主键字段的对应 -->
            <id property="roleId" column="id"></id>
            <!--非主键字段的对应-->
            <result property="roleName" column="role_name"></result>
            <result property="roleDesc" column="role_desc"></result>
        </resultMap>
    
        <!-- 查询所有 -->
        <select id="findAll" resultMap="roleMap">
            select * from role;
        </select>
    </mapper>
    
  5. 编写测试类

    //查询用户
    @Test
    public void testFindAll() throws IOException {
        List<Role> list = roleDao.findAll();
        for (Role role : list) {
            System.out.println(role);
        }
    }
    

角色到用户多对多查询

  1. 编辑查询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
    

    运行结果如下:

  2. 在实体类中加入多对多的关系映射

    //多对多的关系映射:一个角色可以赋予多个用户
    private List<User> users;
    
    public List<User> getUsers() {
        return users;
    }
    
    public void setUsers(List<User> users) {
        this.users = users;
    }
    
  3. 编写映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ben.dao.IRoleDao">
        <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
        <resultMap id="roleMap" type="role">
            <!--id唯一标识,type:对应的对象-->
            <!-- 主键字段的对应 -->
            <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 column="useId" property="id"></id>
                <result column="username" property="userName"></result>
                <result column="address" property="userAddress"></result>
                <result column="sex" property="userSex"></result>
                <result column="birthday" property="userBirthday"></result>
            </collection>
        </resultMap>
    
        <!-- 查询所有 -->
        <select id="findAll" resultMap="roleMap">
            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
        </select>
    
    </mapper>
    
  4. 测试类编写

    //查询用户
    @Test
    public void testFindAll() throws IOException {
        List<Role> list = roleDao.findAll();
        for (Role role : list) {
            System.out.println("---每个用户的角色----");
            System.out.println(role);
            System.out.println(role.getUsers());
        }
    }
    

用户到角色的多对多查询

  1. 编写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
    

    如图所示:

  2. 在User实体类中加入多对多的关系映射;

    // 配置多对多关系映射:
    private List<Role> roles;
    
    public List<Role> getRoles() {
        return roles;
    }
    
    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
    
  3. 配置映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ben.dao.IUserDao">
        <!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
        <resultMap id="userMap" type="uSer">
            <!-- 主键字段的对应 -->
            <id property="userId" column="id"></id>
            <!--非主键字段的对应-->
            <result property="userName" column="username"></result>
            <result property="userAddress" column="address"></result>
            <result property="userSex" column="sex"></result>
            <result property="userBirthday" 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="userMap">
            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
        </select>
    
    </mapper>
    
  4. 编写测试类

    //查询用户
    @Test
    public void testFindAll() throws IOException {
        List<User> list = userdao.findAll();
        for (User user : list) {
            System.out.println("----每个用户对应的角色----");
            System.out.println(user);
            System.out.println(user.getRoles());
        }
    }
    

posted @ 2019-07-20 15:15  伊万夫斯基  阅读(320)  评论(0编辑  收藏  举报