Mybatis collection 一对多查询

3,499 阅读2分钟

Mybatis collection

需求

查询所有用户信息及用户关联的订单信息。

主信息:用户信息  

从信息:订单信息

分析

在一对多关联查询时,只能使用resultMap进行结果映射。 1、一对多关联查询时,sql查询结果有多条,而映射对象是一个。 2、resultType完成结果映射的方式的一条记录映射一个对象。 3、resultMap完成结果映射的方式是以[主信息]为主对象,[从信息]映射为集合或者对象,然后封装到主对象中。

po类

PO 用户订单列表

@Data
public class UserOrderList {


    /**
     * 用户ID
     */
    private int id;

    /**
     * 用户名称
     */
    private String username;

    /**
     * 生日
     */
    private Date birthday;

    /**
     * 性别
     */
    private String sex;

    /**
     * 地址
     */
    private String address;

    /**
     * 创建时间
     */
    private Long createTime;

    /**
     * 订单列表
     */
    private List<Order> orders;
}

注:PO类不能使用extends赋值不进去

UserMapper

public interface UserMapper {

    /**
     * 获取用户订单列表
     * @param userId string 用户ID
     * @return
     */
    UserOrderList getUserOrderList(int userId);

    /**
     * 获取用户订单列表
     * @param userId string 用户ID
     * @return
     */
    UserOrderList getOrderListByUserId(int userId);

}

UserMapper.xml

分布查询

resultMap
<!-- 一对多 分布查询 -->
<resultMap id="selectOrderByUser" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
    <!-- 用户信息映射 -->
    <!-- column 数据库字段 | property 映射po类的字段名 -->
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="birthday" property="birthday"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
    <result column="create_time" property="createTime"/>

    <!-- 一对多 订单关联属性映射:使用select引用方式 -->
    <!-- collection定义关联集合类型的属性的封装规则 -->
    <!-- property: 对应po类关联的集合字段 orders -->
    <!-- column: 关联字段 与sql查询结果的字段对应 -->
    <!-- ofType: 指定的是映射到list集合属性中的pojo类型 -->
    <!-- fetchType: 加载类型:lazy(延迟加载)eager(立即加载)如果使用,它将取代全局配置参数lazyLoadingEnable -->
    <!-- select 分布查询引用 引用的方法 -->
    <collection property="orders" column="id" ofType="com.xxx.www.mybatis.phase04.po.Order" select="com.xxx.www.mybatis.phase04.mapper.OrderMapper.selectOderByUserId" fetchType="lazy">
    </collection>

</resultMap>
查询sql
 <!-- 查询用户订单列表 一对多 -->
<select id="getUserOrderList" resultMap="selectOrderByUser" parameterType="int">
      SELECT
        id, username, birthday, sex, address, create_time
    FROM
        `user` u
    <if test="userId != null ">
        where
        u.id = #{userId}
    </if>
</select>

连表单词查询

resultMap
<!-- 一对多 链表查询 -->
<resultMap id="selectOrderListByUserId" type="com.xxx.www.mybatis.phase04.po.UserOrderList">
    <!-- 用户信息映射 -->
    <id column="user_id" property="id"/>
    <result column="username" property="username"/>
    <result column="birthday" property="birthday"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
    <!-- 一对多 订单信息映射 -->
    <collection property="orders" ofType="com.xxx.www.mybatis.phase04.po.Order">
        <id column="order_id" property="orderId"/>
        <result column="order_number" property="orderNumber"/>
        <result column="user_id" property="userId"/>
        <result column="prepayment_amount" property="prepaymentAmount"/>
        <result column="actually_paid_amount" property="actuallyPaidAmount"/>
        <result column="create_time" property="createTime"/>
        <result column="goods_kind" property="goodsKind"/>
        <result column="goods_quantity" property="goodsQuantity"/>
        <result column="payment_method" property="paymentMethod"/>
        <result column="trade_on" property="tradeOn"/>
        <result column="price_after_discount" property="priceAfterDiscount"/>
    </collection>
</resultMap>
查询sql
<!-- 查询用户订单列表 一对多 -->
<select id="getOrderListByUserId" resultMap="selectOrderListByUserId">
    SELECT
        u.id AS user_id, u.username, u.birthday, u.sex, u.address, o.id AS order_id, o.user_id, u.create_time, o.order_number, o.create_time, o.prepayment_amount, o.actually_paid_amount, o.goods_kind, o.goods_quantity, o.payment_method, o.trade_on, o.price_after_discount
    FROM
        `user` AS u
    JOIN
        `order` AS o
    where
        u.id = o.user_id
    and
        u.id = #{userId}
</select>

注: 如果两表联查,主表和明细表的主键都是id的话,明细表的多条只能查询出来第一条。 u.id AS user_id 和 o.id AS order_id,直接都用 id 查询多条,得到结果为一条

测试
public class Phase04Test {

    /**
     * mybatis mysql连接器
     */
    private SqlSessionFactory sqlSessionFactory;

    private SqlSession sqlSession;

    @Before
    public void init() throws Exception {
        // 加载全局配置文件(同时把映射文件也加载了)
        String resource = "phase04/SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // sqlsessionFactory需要通过sqlsessionFactoryBuilder读取全局配置文件信息之后
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //创建UserMapper对象
        sqlSession = sqlSessionFactory.openSession();
    }

    @Test
    public void testFindOrderById() {
        // 获取代理对象
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        List<OrderExt> orderExtList = mapper.selectOrderAndUserInfo();
        System.out.println(orderExtList);
    }

    @Test
    public void getOrderByUserId() {
        // 获取代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        UserOrderList orderList  = mapper.getUserOrderList(1);
        System.out.println(orderList);
        for (Order order: orderList.getOrders()){
            System.out.println(order.toString());
        }
    }

    @Test
    public void getOrderListByUserId() {
        // 获取代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        UserOrderList orderList  = mapper.getOrderListByUserId(1);
        System.out.println(orderList);
        for (Order order: orderList.getOrders()){
            System.out.println(order.toString());
        }
    }

    @Test
    public void insertOrder() {
        // 获取代理对象
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);

        Order order = insertOrderInfo();
        int rows = mapper.insertOrder(order);
        sqlSession.commit();
        System.out.println(rows);
        System.out.println(order.getOrderNumber());
    }

    /**
     * 添加用户信息
     *
     * @return User
     */
    private Order insertOrderInfo() {
        Order order = new Order();
        // 订单号
       String orderNumber = OrderNumberFactory.getOrderCode(1L);
        order.setOrderNumber(orderNumber);
        // 用户ID
        order.setUserId(1);
        // 预付金额
        order.setPrepaymentAmount(10L);
        // 实付金额
        order.setActuallyPaidAmount(10L);
        // 创建时间
        order.setCreateTime(System.currentTimeMillis());
        // 商品种类
        order.setGoodsKind(1);
        // 商品数量
        order.setGoodsQuantity(1);
        // 支付方式
        order.setPaymentMethod("微信");
        // 交易流水号
        order.setTradeOn("12311");
        // 优惠后价格
        order.setPriceAfterDiscount(10L);
        return order;
    }

    @After
    public void closeSession(){
        if (sqlSession != null){
            sqlSession.close();
        }
    }

}