【Mybatis从0到1-010】一对一查询(resultType和resultMap)

参考代码【下载

本章主要实现一对一查询订单信息,关联查询创建订单的用户信息。

resultType

1.1 SQL语句

确定查询的主表:订单表(orders)
确定查询的关联表:用户表(user)
关联查询使用内链接?还是外链接?
由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接(此处使用隐式内连接)。
SELECT 
  orders.*,
  USER.username,
  USER.sex,
  USER.address 
FROM
  orders,
  USER 
WHERE orders.user_id = user.id

1.2 创建pojo类

将上边sql查询的结果映射到pojo中,pojo中必须包括所有查询列名
原始的Orders.java不能映射全部字段,需要新创建的pojo,创建一个pojo继承包括查询字段较多的po类。(当然了,后面mybatis与Spring结合之后,这些都不需要自己创建了,会自动生成----逆向工程)
新建OrderCustom.java文件,路径为:、src\main\java\po\OrderCustom.java,当然在此之前需要先在同目录下创建Order.java文件(类似User.java类)。
Order.java代码如下:
public class Orders {

    private Integer id;

    private Integer user_id;

    private String number;
    private Date createtime;
   private String note;
   //setter/getter/tostring略 
OrderCustom.java代码如下:
public class OrderCustom extends Orders {
    //添加用户属性
    //USER.username,
    //USER.sex,
    //USER.address

    private String username;
    private String sex;
    private String address;

1.3 定义statement

这里我们新建一个mapper.xml文件,名字为:OrdersMapperCustom.xml,路径为:src\main\resources\mapper,拷贝UserMapper.xml文件内容,到OrdersMapperCustom.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">
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址-->
<mapper namespace="mapper.OrderMapperCustom">
    <!-- 需求:查询订单信息,关联查询创建订单的用户信息 -->
    <!-- 通过 select执行数据库查询
    id:标识 映射文件中的sql,将sql语句封装到mappedStatement对象中,所以将id称为statement的id
    parameterType:指定输入参数的类型,这里指定int型【此时,与接口中输入参数类型一致】
    #{}表示一个占位符号,#{id}:其中的id表示【接收输入】的参数,参数名称就是id,如果输入参数是简单类型,#{}中的参数名
    可以任意,可以value或其它名称
    resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。-->
    <select id ="findOrderUser" resultType="po.OrderCustom">
        SELECT
      orders.*,
      USER.username,
      USER.sex,
      USER.address
      FROM
      orders,
      USER
      WHERE orders.user_id = user.id
    </select>
</mapper>

1.4 接口文件

OrderMapperCustom.java代码如下:

public interface OrderMapperCustom {
    List<OrderCustom> findOrderUser() throws Exception;
}

1.5 测试文件

OrderMapperCustomTest.java代码如下:
public class OrderMapperCustomTest {
    private SqlSessionFactory sqlSessionFactory;
// 创建sqlSessionFactory
// 此方法是在执行testFindUserById之前执行 @Before public void setUp() throws Exception { // mybatis配置文件 String resource = "SqlMapConfig.xml"; // 得到配置文件流 InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂,传入mybatis的配置文件信息 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void findOrderUser() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); // 创建代理对象 OrderMapperCustom orderMapperCustom = sqlSession .getMapper(OrderMapperCustom.class); // 调用maper的方法 List<OrderCustom> list = orderMapperCustom.findOrderUser(); System.out.println(list);//在此处打断点,调试!!!!!!! sqlSession.close(); }}

1.6 查看结果


【注意】使用resultType的要求,在之前的文章中已经提及过【详情】,这里再重申一遍:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。

resultMap

使用resultMap而进行查询的SQL与使用resultType进行查询完全一样,二者的本质区别在于查询出来的列名和pojo的属性名是否一致。使用resultMap将查询结果中的订单信息映射到Orders对象中,在Orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。(其实这种做法并不规范,后期和spring集合后,这些属性类是自动生成的,建议不要做任何修改)

2.1 添加user属性

public class Orders {

    private Integer id;
    //private Integer user_id;这种写法是不规范的,后面使用resultMap后,可以重新命名并进行新名字和数据库字段映射
    private Integer userId ;
    private String number;
    //private Date createtime;
    private Date createTime;
    private  String note;
    //用户信息
    private User user;

2.2 定义resultMap

在映射文件OrderMapperCustom.xml中定义resultMap,代码如下:
<!-- 订单查询关联用户的resultMap,将整个查询的结果映射到po.Orders中 -->
<resultMap type="po.Orders" id="OrdersUserResultMap">
    <!-- 配置映射的订单信息 -->
    <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
        column:订单信息的唯 一标识 列
        property:订单信息的唯 一标识 列所映射到Orders中哪个属性
      -->
    <id column="id" property="id"/>
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createime"/>
    <result column="note" property="note"/>
    <!-- 配置映射的关联的用户信息 -->
    <!-- association:用于映射关联查询单个对象的信息
    property:要将关联查询的用户信息映射到Orders中哪个属性 -->
    <association property="user"  javaType="po.User">
        <!-- id:关联查询用户的唯 一标识
        column:指定唯 一标识用户信息的列
        javaType:映射到user的哪个属性
         -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
    </association>
</resultMap>

2.3 statement定义

这里的statement与使用resultType时,有着相同的MySQL,因此,这里只需修改id和resultMap即可。
<select id ="findOrderUserResultMap" resultMap="po.Order">
    SELECT
    orders.*,
    USER.username,
    USER.sex,
    USER.address
    FROM
    orders,
    USER
    WHERE orders.user_id = user.id
</select>

2.4 接口文件

在接口文件OrderMapperCustom.xml中加入如下代码:
List<Orders> findOrderUserResultMap() throws Exception;

2.5 测试文件

在原有测试文件OrderMapperCustomTest.java基础上添加就OK。添加如下代码:
@Test
public void findOrderUserResultMap() throws Exception{
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 创建代理对象
    OrderMapperCustom ordersMapperCustom = sqlSession
            .getMapper(OrderMapperCustom.class);
    // 调用maper的方法
    List<Orders> list = ordersMapperCustom.findOrderUserResultMap();

    System.out.println(list);

    sqlSession.close();
}

2.6 运行查看


【小结】

实现一对一查询:
   resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType
   resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。resultMap可以实现延迟加载,resultType无法实现延迟加载。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值