• Mybatis-多表联查


    在数据库查询中,很多时候不只是查询一张表,而是需要将多张表结合起来才能获得需要的数据,下面介绍在mybatis中怎么实现多表联查(前提是所有的依赖均已配置完成)

    一、步骤一:创建pojo实体类

    将需要用到的表全部创建成java的实体类,导入lombok依赖(自动生成get、set等方法)
    User 用户表 Order 订单表

    @Data
    public class User {
        private Integer ID;
        private String username;
        private String PASSWORD;
        private String sex;
        private Date brithday;
        private String address;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    二、步骤二:明确两个实体类之间的关系

    一个用户可以有多条订单,而一条订单只属于一个用户
    所以;:用户对订单是1对多的关系
     
    在设计数据库时(黄色部分):在多的一方(tb_order)中添加一个外键,与tb_user的主键对应(图中为uid)
     
    在设计java对象时(红色部分): 需要根据题目进行pojo类的编写(具体看步骤三)

    在这里插入图片描述


    三、步骤三:修改pojo实体类

    先分析清楚题目 如:

    ①:根据id查询订单以及订单的所属用户信息
    => 返回的数据是tb_order表中的数据+tb_user表中的数据,需要修改的实体类是Order,因为是根据order的id查询的

    
    //需要在Order的实体类中引入User对象
    public class Order {
        private Integer id;
        private Integer userid;
        private Date createtime;
        private String state;
    
    //    多对一
        private User user = new User();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ②:根据用户id查询她的各类订单
    =>返回的数据是tb_user+tb_order表中的数据,但是不同与上面的是:由于订单有多条所以订单需要用集合来装,而查询出的数据是要根据用户的id查询所有需要修改User类

    // 需要在User表中的实体类中引入数据类型为Order的集合
    public class User implements Serializable {
        private Integer ID;
        private String username;
        private String PASSWORD;
        private String sex;
        private Date brithday;
        private String address;
    
    //    一对多
        private List<Order> orders = new ArrayList<>();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    四、步骤四:编写Mapper接口

    public interface UserMapper {
    //    通过订单id查询订单详情以及所属用户
        Order selectOrderAndInfoById(@Param("oid") int id);
    //    通过用户id查询该用户的所有订单
        User selectByUserIdForOrder(@Param("uid") int id);
    //    根据id查询用户
        User selectUserByid(@Param("uid") int id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五、步骤五:编写Mapper映射文件

    需要指定该映射文件是步骤四的Mapper,在namespace中指定

    重点来了:

    题目1:通过订单id查询订单详情以及所属用户

    需要知道的是我们关联的是两张表,如果直接用下面的sql语句则只能查出订单的信息而订单所属用户则为空,这是因为在执行过程中Order会自动映射到tb_order的内容,但是在Order表中定义的User对象则无法自动映射到tb_user表中的内容

    SELECT  u.ID ,u.username,u.PASSWORD,u.sex,u.brithday,u.address,o.id oid,o.userid,o.createtime,o.state
    FROM tb_user u JOIN tb_order o
    ON u.ID  = o.userid
    WHERE u.id= #{uid}
    
    • 1
    • 2
    • 3
    • 4

    所以我们得手动映射User类,需要使用到resultMap
    总体代码如下:

     <!--  todo  根据id查询订单以及对应的用户 -->
        <sql id="selectById">
            u.ID ,u.username,u.PASSWORD,u.sex,u.brithday,u.address,
            o.id oid,o.userid,o.createtime,o.state
        </sql>
        <resultMap id="selectParent" type="Order">
            <id property="id" column="oid"/>
            <result property="userid" column="userid"/>
            <result property="createtime" column="createtime"/>
            <result property="state" column="state"/>
        </resultMap>
        <resultMap id="selectChildren" type="Order" extends="selectParent">
            <association property="user" javaType="User" select="selectUserByid" column="userid"/>
        </resultMap>
        <select id="selectOrderAndInfoById" resultMap="selectChildren">
            SELECT
            <include refid="selectById"/>
            FROM tb_user u JOIN tb_order o
            ON u.ID = o.userid
            WHERE o.id = #{oid}
        </select>
    
        <!--    根据id查询用户-->
        <select id="selectUserByid" resultType="User">
            SELECT * FROM tb_user WHERE ID = #{uid}
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    selectParent为手动映射的Order类的Map,selectChildren为手动映射的User类的Map,由于需要返回的订单类的数据所有type中填写Order类,children继承了parent那么children中也会有parent的映射,所有selectChildren的map中就有了Order+User的映射
    在这里插入图片描述
    这个时候再