本节内容:
- 商品订单数据模型
- 一对一查询
- 一对多查询
一、商品订单数据模型
二、一对一查询
需求:查询所有订单信息,关联查询下单用户信息。
【注意】:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。
sql语句:
SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `orders` o LEFT JOIN `user` u ON o.user_id = u.id
1. 方法一:使用resultType
使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息。这样返回对象的时候,mybatis自动把用户信息也注入进来了。
(1)改造pojo类
新建一个OrderUser类继承Order类,这样OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可,如下:
package com.wisedu.mybatis.pojo; /** * Created by jkzhao on 12/27/17. */ public class OrderUser extends Orders { private String username; private String address; }
(2)Mapper接口
在OrderMapper.java添加方法如下:
List<OrderUser> queryOrderUser();
(3)OrderMapper.xml
<!-- 查询订单,同时包含用户数据 --> <select id="queryOrderUser" resultType="orderUser"> SELECT o.id, o.user_id userId, o.number, o.createtime, o.note, u.username, u.address FROM `orders` o LEFT JOIN `user` u ON o.user_id = u.id </select>
(4)测试方法
@Test public void fun2() throws Exception { //加载核心配置文件 String resource = "sqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); //创建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); // 获取sqlSession,和spring整合后由spring管理 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSEssion会帮我生成一个实现类 (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口) OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<OrderUser> list = orderMapper.queryOrderUser(); for (OrderUser o: list){ System.out.println(o); } // 和spring整合后由spring管理 sqlSession.close(); }
测试时打个断点,截图如下:
【小结】:定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。
2. 方法二:使用resultMap
使用resultMap,定义专门的resultMap用于映射一对一查询结果。
(1) 改造pojo类
在Orders类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。
改造Orders如下:
public class Orders implements Serializable{
private static final long serialVersionUID = 1L;
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//附加对象 用户对象
private User user;
(2)Mapper接口
在UserMapper.java添加方法如下:
//关联查询:一对一 (以订单为中心关联用户) List<Orders> queryOrders();
(3)Mapper.xml
这里resultMap指定orderUserResultMap,如下:
<!-- ====================== 关联查询:一对一 =================== --> <resultMap type="orders" id="orderUserResultMap"><!-- 关联查询时,属性和列名一样的也得写出来--> <id property="id" column="id" /> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> <!-- association :配置一对一属性 --> <!-- property:order里面的User属性名 --> <!-- javaType:属性类型 --> <association property="user" javaType="user"> <!--user对象映射,想要拿到哪些属性值就要在下面写出来--> <!-- id:声明主键,表示user_id是关联查询对象的唯一标识--> <id property="id" column="user_id" /> <result property="username" column="username" /> <result property="address" column="address" /> </association> </resultMap>
(4)测试方法
@Test public void fun1() throws Exception { //加载核心配置文件 String resource = "sqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); //创建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); // 获取sqlSession,和spring整合后由spring管理 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSEssion会帮我生成一个实现类 (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口) OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<Orders> order_list = orderMapper.queryOrders(); for (Orders order: order_list){ System.out.println(order); } // 和spring整合后由spring管理 sqlSession.close(); }
执行测试方法,查看日志:
DEBUG [main] - ==> Preparing: SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.address FROM `orders` o LEFT JOIN `user` u ON o.user_id = u.id DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 3 Orders{id=3, userId=1, number='1000010', createtime=Wed Feb 04 13:22:35 CST 2015, note='null', user=User [id=1, username=王五, sex=null, birthday=null, address=null]} Orders{id=4, userId=1, number='1000011', createtime=Tue Feb 03 13:22:41 CST 2015, note='null', user=User [id=1, username=王五, sex=null, birthday=null, address=null]} Orders{id=5, userId=10, number='1000012', createtime=Thu Feb 12 16:13:23 CST 2015, note='null', user=User [id=10, username=张三, sex=null, birthday=null, address=北京市]}
三、一对多查询
案例:查询所有用户信息及用户关联的订单信息。
用户信息和订单信息为一对多关系。
sql语句:
SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `orders` o ON u.id = o.user_id
1. 修改pojo类
在User类中加入List<Order> orders属性,如下图:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
//附加对象 List<Orders>
private List<Orders> ordersList;
...
2. Mapper接口
在OrderMapper.java接口中添加方法,如下:(在UserMapper.java接口中定义该方法也可以)
//一对多关联查询 List<User> queryUserOrder();
3. Mapper.xml文件
在OrderMapper.xml中编写sql语句,如下:
<!-- ====================== 关联查询:一对多 =================== --> <resultMap type="user" id="userOrderResultMap"> <id property="id" column="id" /> <result property="username" column="username" /> <result property="birthday" column="birthday" /> <result property="sex" column="sex" /> <result property="address" column="address" /> <!-- 配置一对多的关系 --> <collection property="ordersList" javaType="list" ofType="orders"> <!--ordersList是附加在User.java文件中的属性名。ofType指定list集合每一个元素的类型--> <!-- 配置主键,是关联Order的唯一标识 --> <id property="id" column="oid" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> </collection> </resultMap> <!-- 一对多关联,查询订单同时查询该用户下的订单 --> <select id="queryUserOrder" resultMap="userOrderResultMap"> SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `orders` o ON u.id = o.user_id </select>
4. 测试方法
@Test public void fun3() throws Exception { //加载核心配置文件 String resource = "sqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); //创建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); // 获取sqlSession,和spring整合后由spring管理 SqlSession sqlSession = sqlSessionFactory.openSession(); //SqlSEssion会帮我生成一个实现类 (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口) OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class); List<User> list = orderMapper.queryUserOrder(); for (User u: list){ System.out.println(u); } // 和spring整合后由spring管理 sqlSession.close(); }
在 System.out.println(u); 处打个断点,debug运行该方法,结果如下: