mybatis高级查询-单向查询

目录

一、需求

二、分析

三、设计

四、Mapper层

五、测试代码

六、思考


一、需求

查询某个用户的详细信息,除了 用户的基本信息 外,还包括 用户所在部门 以及 用户拥有的角色

二、分析

用户与部门:

1、一个用户 只能属于 一个部门, 一个部门 有多个 用户,所以用户与部门关系是 一 对 多

2、通过 用户查询部门,只需要 多的那边 记住 一,所以使用 一 对 多单向数据

用户与角色:

1、一个用户 有多个角色,一个角色可以分配 给多个用户, 所以用户与角色的关系是 多对多

2、通过用户查询角色

三、设计

实体设计

@Data
public class User {

    private Integer id;
    private String userName;
    private String password;
    private Date birthday;

    private Dept dept;
    private List<Role> roles;

}

@Data
public class Role {

    private Integer id;
    private String name;
    private String comment;

}

@Data
public class Dept {

    private Integer id;
    private String name;

}

数据库表设计

CREATE TABLE `dept` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `comment` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(20) DEFAULT NULL,
  `password` varchar(20) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `dept_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

表数据

INSERT INTO `dept` (`id`,`name`) VALUES (1, '研发部'),(2, '销售部'),(3, '售后部');
INSERT INTO `role` (`id`,`name`,`comment`) VALUES (1, '总经理', '总管大局'),(2, '销售经理', '负责销售'),(3, '部长', '管理部门角色');
INSERT INTO `user` (`id`,`user_name`,`password`,`birthday`,`dept_id`) VALUES (1, '张三丰', 'aaabbb', '2019-11-12', 1),(2, 'tom', '66888999', '2019-11-10', 2),(3, 'kitty', 'aaaabbb', '2018-08-12', 3);
INSERT INTO `user_role` (`id`,`user_id`,`role_id`) VALUES (1, 1, 1),(2, 1, 3),(3, 2, 1),(4, 2, 2);

四、Mapper层

接口:

public interface UserMapper {

    User selectUserById(Integer id);

}

mapper映射描述文件:

    <resultMap id="user" type="com.lcy.pojo.User">
        <result property="id"        column="u_id"/>
        <result property="userName"  column="u_user_name"/>
        <result property="password"  column="u_password"/>
        <result property="birthday"  column="u_birthday" javaType="java.util.Date"/>

        <association property="dept" javaType="Dept">
            <id property="id" column="d_id"/>
            <result property="name" column="d_name" />
        </association>

        <collection property="roles" ofType="Role">
            <id property="id" column="r_id"/>
            <result property="name" column="r_name" />
            <result property="comment" column="r_comment" />
        </collection>
    </resultMap>

    <!--select * from user where id = #{id}-->
    <select id="selectUserById" resultMap="user">
      SELECT
            u.id AS u_id,
            u.user_name AS u_user_name,
            u.`password` AS u_password,
            u.birthday AS u_birthday,
            d.id AS d_id,
            d.`name` AS d_name,
            r.id AS r_id,
            r.`name` AS r_name,
            r.COMMENT AS r_comment
        FROM
            `user` u
            LEFT JOIN dept d ON u.dept_id = d.id
            LEFT JOIN user_role ur ON u.id = ur.user_id
            LEFT JOIN role r ON ur.role_id = r.id
        where u.id = #{id}
    </select>

五、测试代码

    UserMapper mapper;
    SqlSession session;

    @Before
    public void init() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
        mapper = session.getMapper(UserMapper.class);
    }

    @After
    public void destory() {
        session.commit();
        session.close();
    }

    @Test
    public void selectUserById() {
        User user = mapper.selectUserById(2);
        System.out.println(user);
    }

六、思考

新增需求:

在之前是通过用户来查询部门,那么是不是也可以查询 该用户所在部门的所有用户?

即:在部门类中添加 List<User> user; 属性, 首先通过 用户 ID, 查询到用户所在的部门, 然后在获取该部门下的所有用户?

伪代码:

mapper.selectUserById(1).getDept().getUsers()  // 获取用户 id为1的所有同事

分析:

这个问题, 我之前在学 hibernate的时候也遇到过, 这里做一下简单描述

类设计:

User类中 : 有Dept属性

Dept类中: 有User集合

那么我们在 使用 user.getDept()获取部门, 但如果做了双向数据绑定, 那么获取到的部门中由于含有User集合, 然后Hibernate又会去查询User, 查询到 User,但 User中又有 Dept,这样 会造成死循环!!!

总结:

无论是一对一 或是 一对多, 都不要做双向数据绑定, 否则会造成查询中的死循环问题!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值