Mybatis 多表联查

表关系: 一对一,一对多,多对多

  • 1vs1 丈夫表 --> 妻子表

  • 1 vs n 用户 --> 车辆/房产

  • n vs n 老师/商品 --> 学生/订单

多表联查的SQL

  • 内连接

    • select * from 表1 inner join 表2 on 表1.字段 = 表2.字段

    • select * from 表1, 表2 where 表1.字段 = 表2.字段

  • 外连接

    • select * from 表1 left join 表2 on 表1.字段 = 表2.字段

  • 子查询

1 OneToOne

需求: 实现一对一查询,查询订单以及对应的用户信息

数据: tb_user表, tb_order表

关系:

用户 ---> 订单 (1 VS N)     一个用户有多个订单
订单  ---> 用户 (1 VS 1)    一个订单只会属于一个人
public class OrderVO extends Order {
    private User user;
    // set get
}

OrderMapper.java接口文件

public interface OrderMapper {
    OrderVO findOrderWithUserByOid(int oid);
}

OrderMapper.xml映射文件

    <resultMap id="orderWithUserResultMap" type="OrderVO">
        <!-- 封装查询主体Order: -->
        <id column="oid" property="oid"/>
        <result column="order_time" property="orderTime"/>
        <result column="order_desc" property="orderDesc"/>
        <result column="uid" property="uid"/>
        <!-- 一对一映射,需要封装关联的User对象 -->
        <!-- 一对一映射,需要特殊标签 association-->
        <!-- property="user" 是OrderVO类中的属性,javaType是user属性的类型 -->
        <association property="user" javaType="com.qf.model.User">
            <!-- 下面正常的列和属性 一一映射 -->
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
            <result column="phone" property="phone"/>
            <result column="money" property="money"/>
            <result column="create_time" property="createTime"/>
            <result column="sex" property="sex"/>
        </association>
    </resultMap>
​
    <!-- 多表联查,直接返回resultType无法封装关联的那个对象,就需要使用     
     resultMap手动映射 -->
    <select id="findOrderWithUserById" resultMap="orderWithUserResultMap">
        SELECT
            o.*,
            u.*
        FROM
            tb_order o,
            tb_user u
        WHERE
            o.uid = u.id
        AND o.oid = #{oid}
    </select>

2 OneToMore

需求: 一对多,查询用户关联查询出所有的订单

SELECT
    * 
FROM
    tb_user u
LEFT JOIN tb_order o ON u.id = o.uid 
WHERE
    u.id = 1

目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List<Order>

User扩展实体类

public class UserVO extends User{
​
    private List<Order> orderList;
    // set get
}

UserMapper.java接口

public interface UserMapper {
    UserVO findUserWithOrdersById(int id);
}

UserMapper.xml映射文件

    <!-- 一对多 -->
    <resultMap id="userWithOrdersResultMap" type="UserVO">
        <!-- 封装User对象 -->
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="phone" property="phone"/>
        <result column="create_time" property="createTime"/>
        <result column="money" property="money"/>
        <result column="sex" property="sex"/>
        <!-- 一对多关联映射使用collection标签 -->
        <!-- property是UserVO类中关联的属性 -->
        <!-- 不是javaType,是ofType,是指定集合中存储的数据类型 -->
        <collection property="orderList" ofType="com.qf.model.Order">
            <id column="oid" property="oid"/>
            <result column="order_time" property="orderTime"/>
            <result column="order_desc" property="orderDesc"/>
            <result column="uid" property="uid"/>
        </collection>
    </resultMap>
​
    <!-- 多表联查,另外的属性不会自动封装,需要使用resultMap -->
    <select id="findUserWithOrdersById" resultMap="userWithOrdersResultMap">
        SELECT
            *
        FROM
            tb_user u
        LEFT JOIN tb_order o ON u.id = o.uid
        WHERE
            u.id = #{id}
    </select>

3 关联查询总结

  • 实体类要设置扩展类以用于封装多表的数据

    • 一对一,类中套类

    • 一对多,类中套集合

  • 正常封装使用resultMap

    • 一对一封装使用association

    • 一对多封装使用collection

猜你喜欢

转载自blog.csdn.net/hang_sa_mu/article/details/141945713