您的位置:首页 > 其它

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

2017-08-21 18:59 585 查看
参考代码【下载

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

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无法实现延迟加载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息