【MyBatis框架点滴】——MyBatis一对一查询

时间:2022-06-10
本文章向大家介绍【MyBatis框架点滴】——MyBatis一对一查询,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/51578010

  前面介绍的都是对单表进行查询,但实际业务中肯定会涉及到多张表,下面开始总结在MyBatis中的一对一、一对多、多对多的高级查询。

  就根据最常见的订单业务来分析这几种情况:

  如上图订单和用户的关系,一个用户可以对应多个订单,但是一个订单只能属于一个用户,所以对于订单来说,它跟用户之间的关系就是一对一,也就是根据一个订单只能查询出一个对应的用户来。下面说一下MyBatis中的一对一查询。

用resultMap返回指定类型


  代码如下:

  User.java

public class User implements Serializable {
    private int id;//用户id
    private String username;//用户名
    private int sex;//性别
    private Date birthday;//出生日期
    private String address;//地址
    //getter、setter
}

  Orders.java

public class User implements Serializable {
    private Integer id;//订单id
    private Integer userId;//所属用户id
    private String number;//订单号
    private Date createtime;//创建时间
    private String note;//订单备注
    private User user;//所属用户
    //getter、setter
}

  OrdersMapper.xml

<?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.danny.mybatis.mapper.OrdersMapper" >

<!-- 订单关联用户的resultMap-->
    <resultMap type="com.danny.mybatis.po.Orders" id="OrdersUserResultMap">
        <!-- 配置映射的订单信息 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>

        <!-- 配置映射的用户信息 -->
        <association property="user" javaType="com.danny.mybatis.po.User">
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>

    <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap" >
        select
            orders.*,
            user.username,
            user.sex,
            user.address
        from orders,user
        where orders.user_id=user.id
    </select>
</mapper>

  resultMap的配置是这种方式查询的关键部分。resultMap的type表示查询的主体,比如这里要查询的主体是订单(顺便把关联的用户信息也查出来)。association表示用于映射单个关联对象的信息,它的property属性值表示要将关联查询的实体(用户)映射到主体(订单)中哪个属性。

  mapper接口:

public interface OrdersMapper{
    List<Orders> findOrdersUserResultMap() throws Exception;
}

  测试:

@Test
public void findOrdersUserResultMap(){

    SqlSession sqlSession=sqlSessionFactory.openSession();
    OrdersMapper ordersMapper=sqlSession.getMapper(OrdersMapper.class);
    try {
        List<Orders> list=ordersCustomMapper.findOrdersUserResultMap();
        if (list!=null) {
            System.out.println(list.size());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

用resultType返回指定类型


  用resultType返回指定类型,需要添加一个组合实体OrdersCustom.java,它要包含查询出的用户和订单的所有字段。为了减少代码重复,可以让它继承User.java或者Orders.java中字段较多的一个实体,这里让它继承Orders,如下:

public class OrdersCustom extends Orders{
    //添加User的属性
    private String username;
    private int sex;
    private String address;
    //getter、setter
}

  映射文件:

<select id="findOrdersUser" resultType="com.danny.mybatis.po.OrdersCustom" >
    select
        orders.*,
        user.username,
        user.sex,
        user.address
    from orders,user
    where orders.user_id=user.id
</select>

  mapper接口:

public interface OrdersMapperCustom {
    List<OrdersCustom> findOrdersUser() throws Exception;
}

  测试:

@Test
public void findOrdersUser(){

    SqlSession sqlSession=sqlSessionFactory.openSession();
    OrdersMapperCustom ordersCustomMapper=sqlSession.getMapper(OrdersMapperCustom.class);
    try {
        List<OrdersCustom> list=ordersCustomMapper.findOrdersUser();
        if (list!=null) {
            System.out.println(list.size());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

总结


  上面两种方法中,个人认为使用resultType定义输出映射比较简单,只需要添加一个po即可,补充多出的属性,即可完成映射。

  相对于第二种方法,使用resultMap麻烦一些,需要定义配置resultMap来映射与之关联的实体机器属性。虽然麻烦,但它的好处就是可以实现延迟加载~当然,如果没有特殊要求,可以使用第二种方法~


【 转载请注明出处——胡玉洋《【MyBatis框架点滴】——MyBatis一对一查询》】