• 【java框架】MyBatis(6)--Mapper映射关联(多表查询补充)


    1.MyBatis多表查询

            之前的博客在MyBatis第三章节中介绍了多表查询多对一、一对多的情况,这里再对一对一、多堆多的情况做一下说明,也算是将MyBatis这部分的知识做一个补充和完整收尾的工作。

    1.1.一对一查询

    这里基于一个简单的用户购买商品订单表的案例来进行说明一对一查询的模型:

    用户表user和订单表的关系为:一个用户有多个订单,一个订单只从属于一个用户。

    一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户:

    对应数据库中表的设计:

    orders订单表:

    user用户表:

    对应创建实体类:

    Order类:

    public class Order {
        private int id;
    
        private String orderTime;
    
        private int total;
    
        private User user; //一个订单从属于一个用户,针对于订单与用户这里是一对一的关系
    }

    User类:

    public class User {
        private int id;
        private String username;
        private String password;
        private Date birthday;
    }

    对应OrderMapper接口及xml中查询sql封装,需要注意的是使用Date_Format函数进行格式封装输出到对应实体order类,

    可以将Date类型的ordertime进行标准格式化输出:

    public interface OrderMapper {
        //查询出所有订单,并一并查询出订单对应的用户
        List<Order> findAll();
    }
        <resultMap id="orderMap" type="order">
            <id column="oid" property="id"></id>
            <result column="ordertime" property="orderTime"></result>
            <result column="total" property="total"></result>
            <result column="uid" property="user.id"></result>
            <result column="username" property="user.username"></result>
            <result column="password" property="user.password"></result>
            <result column="birthday" property="user.birthday"></result>
        </resultMap>
    
        <select id="findAll" resultMap="orderMap">
            SELECT
                o.id oid,
                DATE_FORMAT(o.ordertime, '%Y-%m-%d %H:%i:%S') ordertime,
                o.total,
                u.id uid,
                u.username,
                u.password,
                u.birthday
            FROM
              orders o
            JOIN USER u ON o.uid = u.id
        </select>

    其中<resultMap>还可以配置成如下,使用<association>进行User类的单独封装映射,注意这里使用了别名简化配置,这里就不再累述:

      <resultMap id="orderMap" type="order">
            <id column="oid" property="id"></id>
            <result column="ordertime" property="orderTime"></result>
            <result column="total" property="total"></result>
            <association property="user" javaType="user">
                <id column="uid" property="id"></id>
                <result column="username" property="username"></result>
                <result column="password" property="password"></result>
                <result column="birthday" property="birthday"></result>
            </association>
        </resultMap>

    1.2.多对多查询

    多对多查询一般设立中间表来关联两张主表,常见的模型是用户User和对应的角色Role。

    用户表User和角色表Role的关系为,一个用户有多个角色,一个角色被多个用户使用。

    多对多基于查询需求来实现:查询用户表的同时查询出该用户对应的所有角色

    数据库表的简单设计如下:

    sys_user表(用户表):

    sys_role表(角色表):

    sys_user_role表(中间表)

    对应实体类创建,主要是在用户domain中设计出多方角色的List<Role>属性:

    User类:

    public class User {
        private int id;
        private String username;
        private String password;
        private Date birthday;
        /**
         * 查询用户同时查询出它所有的角色
         */
        private List<Role> roleList;
    }

    Role类:

    public class Role {
        private int id;
        private String roleName;
        private String roleDesc;
    }

    对应Mapper接口和xml中的sql封装如下:

    public interface UserMapper {
        /**
         * 查询出所有用户及其对应的角色
         * @return
         */
        List<User> findAllUserRole();
    }
    <?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.fengye.mapper.UserMapper">
        <resultMap id="userRoleMap" type="user">
            <id column="id" property="id"></id>
            <result column="username" property="username"></result>
            <result column="password" property="password"></result>
            <result column="birthday" property="birthday"></result>
            <!--用户对应多个角色List使用collection:
                property是实体类对应的属性,
                ofType是List中每个元素的类型
                注意:使用ofType时,下面封装的property中不能使用role.属性;
                      注意区分一对一中type属性的封装刚好相反-->
            <collection property="roleList" ofType="role">
                <id column="roleId" property="id"></id>
                <result column="roleName" property="roleName"></result>
                <result column="roleDesc" property="roleDesc"></result>
            </collection>
        </resultMap>
    
        <select id="findAllUserRole" resultMap="userRoleMap">
          select
            *
          from
            sys_user u
          join sys_user_role ur on u.id = ur.userId
          join sys_role r on r.id = ur.roleId
        </select>
    </mapper>

    其实基本上对应sql连接写好了,封装注意一下表与表连接的逻辑关系、从属性,连接标签条件的使用,基本上就是熟能生巧的问题了。

    本节代码示例已上传至github地址:

    https://github.com/devyf/MyBatisReview/tree/master/fengye_mybatis_multi

  • 相关阅读:
    原型,构造函数,实例,__proto__
    To me
    那么再会吧!OI!(HNOI2019退役记)
    中山纪念中学培训杂题(难的都不在这里面qwq)
    关于菜鸡我
    树链剖分讲解
    [luogu] P4823 [TJOI2013]拯救小矮人(贪心)
    [luogu] P4551 最长异或路径(贪心)
    [luogu] P4364 [九省联考2018]IIIDX(贪心)
    [luogu] P4155 [SCOI2015]国旗计划(贪心)
  • 原文地址:https://www.cnblogs.com/yif0118/p/14422680.html
Copyright © 2020-2023  润新知