1、订单商品数据模型
1.1、数据模型分析思路
a、每张表记录的数据内容,重要的字段设置
b、数据库级别的表与表之间的关系,外键关系
c、表与表之间的业务关系:在分析表与表之间的业务关系时一定要建立在某个业务意义基础上去分析。
1.2、数据模型分析
2、一对一查询
2.1、需求:查询订单信息,关联查询创建订单的用户信息
2.2、ResultType
2.2.1、sql语句
2.2.2、创建pojo
将上边的sql查询到的结果映射到pojo中,pojo中必须包括所有查询列名。
原始的Orders.java不能映射全部字段,需要创建新的pojo,创建一个pojo继承包括查询字段较多的pojo类。
Orders.java
用来接收查询结果的OrdersCustom.java类
2.2.3、映射文件
<?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="lsq.study.dao.OrdersCustomDao">
<select id="findOrdersUser" resultType="ordersCustom">
select
orders.*,
user.username,
user.sex,
user.address
from
orders,
user
where orders.user_id = user.id
</select>
2.2.4、接口类方法
package lsq.study.dao;
import java.util.List;
import lsq.study.domain.OrdersCustom;
public interface OrdersCustomDao {
public List<OrdersCustom> findOrdersUser();
}
2.2.5测试方法
@Test
public void findOrdersUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersCustomDao ordersCustomDao = sqlSession.getMapper(OrdersCustomDao.class);
List<OrdersCustom> list = ordersCustomDao.findOrdersUser();
System.out.println(list);
}
2.2.6、测试结果
2.3、ResultMap
2.3.1、sql语句
同实现ResultType的sql
2.3.2、使用ResultMap映射的思路
使用ResultMap将查询结果中的订单信息映射到Orders对象中,在Orders类中添加User属性,将关联查询出来的用户信息映射到Orders对象中的user属性。
2.3.3、在Orders类中添加User属性
2.3.4、映射文件
2.3.4.1、定义ResultMap
<!--
查询订单关联查询用户的ResultMap
-->
<resultMap type="lsq.study.domain.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="lsq.study.domain.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
2.3.4.2、定义select
<!-- 查询订单关联查询用户信息,使用ResultMap -->
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
select
orders.*,
user.username,
user.sex,
user.address
from
orders,
user
where orders.user_id = user.id
</select>
2.3.4.3、接口方法定义
2.4、ResultType和ResultMap实现一对一查询小结
实现一对一查询:
ResultType:使用ResultType实现较为简单,如果pojo中没有包含查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果对查询结果没有特殊要求,建议使用ResultType。
ResultMap:需要单独定义ResultMap,实现比较麻烦。如果对查询结果有特殊的要求,使用ResultMap可以完成将关联查询映射到pojo的属性中。
ResultMap可以实现延迟加载,ResultType无法实现延迟加载。
3、一对多查询
3.1、需求:查询订单及订单明细的信息。
3.2、sql语句
确定主查询表:订单表
确定关联查询表:订单明细表
在一对一查询基础上添加订单明细表关联即可。
3.3、在Orders.java中添加订单明细集合
3.4、定义映射文件
<!--
查询订单关联查询用户的ResultMap
-->
<resultMap type="lsq.study.domain.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="lsq.study.domain.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
<collection property="orderDetailList" ofType="lsq.study.domain.OrderDetail">
<id column="orderdetail_id" property="id"/>
<result column="orders_id" property="ordersId"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
</collection>
</resultMap>
<select id="findOrdersAndOrderDetail" resultMap="OrdersUserResultMap">
select
orders.*,
user.username,
user.sex,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.orders_id,
orderdetail.items_num
from
orders,
user,
orderdetail
where orders.user_id = user.id and orders.id = orderdetail.orders_id
</select>
</mapper>
3.5、定义接口方法
3.6、小结
Mybatis使用ResultMap的collection对关联查询的多条记录映射到一个list集合属性中。
4、多对多查询
4.1、需求:查询用户及用户购买商品信息。
4.2、sql语句
查询主表:用户表
关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表有:orders、orderdetail、items
4.3、映射思路
将用户信息映射到user中。
在user类中添加订单列表属性List<Order> orderList,将用户创建的订单映射到orderList;
在Orders中添加订单明细列表属性List<OrderDetail> orderdetails,将订单的明细映射到orderdetails;
在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items
4.4、映射文件
<mapper namespace="lsq.study.dao.UserDao">
<resultMap type="lsq.study.domain.User" id="UserAndItemsResultMap">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<collection property="ordersList" ofType="lsq.study.domain.Orders">
<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"/>
<collection property="orderDetailList" ofType="lsq.study.domain.OrderDetail">
<id column="orderdetail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="orders_id" property="ordersId"/>
<result column="items_num" property="itemsNum"/>
<association property="items" javaType="lsq.study.domain.Items">
<id column="items_id" property="id"/>
<result column="items_name" property="name"/>
<result column="items_detail" property="detail"/>
<result column="items_price" property="price"/>
</association>
</collection>
</collection>
</resultMap>
<select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
select
orders.*,
user.username,
user.sex,
user.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.orders_id,
orderdetail.items_num,
items.name items_name,
items.detail items_detail,
items.price items_price
from
orders,
user,
orderdetail,
items
where orders.user_id = user.id and orders.id = orderdetail.orders_id and orderdetail.items_id = items.id
</select>
</mapper>
4.5、多对多查询总结
使用ResultMap是针对那些对查询结果映射有特殊要求的功能,比如要求映射成list中包括多个list。
5、延迟加载
@Test
public void findOrdersUserLazyLoading() {
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
List<Orders> list = ordersDao.findOrdersUserLazyLoading();
System.out.println(list);
}
结果:
测试代码2:
@Test
public void findOrdersUserLazyLoading() {
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class);
List<Orders> list = ordersDao.findOrdersUserLazyLoading();
// System.out.println(list);
}
测试结果: