参考代码【下载】
本章主要实现一对一查询订单信息,关联查询创建订单的用户信息。
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
确定查询的关联表:用户表(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结合之后,这些都不需要自己创建了,会自动生成----逆向工程)
原始的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无法实现延迟加载。
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。如果没有查询结果的特殊要求建议使用resultType。
resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。resultMap可以实现延迟加载,resultType无法实现延迟加载。