Mybatis学习总结(六).Mybatis高级查询及延迟加载
来源:互联网 发布:sql镜像服务器 编辑:程序博客网 时间:2024/05/16 08:14
Mybatis作为一个ORM框架,也对SQL的高级查询做了支持,下面我们学习Mybatis下的一对一、一对多、多对多的查询。
此案例的业务关系是用户、订单、订单详情、商品之间的关系,其中,
一个订单只能属于一个人。
一个订单可以有多个订单详情。
一个订单详情中包含一个商品信息。
它们的关系是:
订单和人是 一对一的关系。
订单和订单详情是 一对多 的关系。
订单和商品是 多对多的关系。
数据库关系图:
一对一查询
需求:一对一查询:查询订单,并且查询出下单人的信息。SQL: SELECT o.*, u.user_name,u. NAME FROM tb_order o LEFT JOIN tb_user u ON o.user_id = u.id WHERE order_number = '20140921001'
第一种实现:
User.java
package cn.zto.mybatis.pojo;import java.util.Date;/** * * @ClassName: User * @Description:对应用户表 * @author: xyc * @date: 2017年2月11日 下午8:11:13 * */public class User implements java.io.Serializable{ private static final long serialVersionUID = 1L; private Long id; // 用户名 private String userName; // 密码 private String password; // 姓名 private String name; // 年龄 private Integer age; // 性别,1男性,2女性 private Integer sex; // 出生日期 private Date birthday; // 创建时间 private Date created; // 更新时间 private Date updated; //getter And setter @Override public String toString() { return "User [id=" + id + ", userName=" + userName + ", password=" + password + ", name=" + name + ", age=" + age + ", sex=" + sex + ", birthday=" + birthday + ", created=" + created + ", updated=" + updated + "]"; }}
Order.java
package cn.zto.mybatis.pojo;/** * * @ClassName: Order * @Description:对应订单表 * @author: xyc * @date: 2017年2月11日 下午8:22:24 * */public class Order { private Integer id; private Long userId; private String orderNumber; //getter And setter @Override public String toString() { return "Order [id=" + id + ", userId=" + userId + ", orderNumber=" + orderNumber + "]"; }}OrderUser.java
package cn.zto.mybatis.pojo;/** * * @ClassName: OrderUser * @Description: 此类用于补字段 * @author: xyc * @date: 2017年2月11日 下午8:24:51 * */public class OrderUser extends Order{ private String userName; private String name; //getter and setter @Override public String toString() { return "OrderUser [userName=" + userName + ", name=" + name + "]"; }}
OrderMapper.java
package cn.zto.mybatis.mapper;import cn.zto.mybatis.pojo.OrderUser;/** * 测试高级查询 */public interface OrderMapper { /** * 查询订单,并且查询出下单人的信息。 * @param orderNumber * @return */ public OrderUser queryOrderAndUserByOrderNumber(String orderNumber); }
OrderMapper.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"> <mapper namespace="cn.zto.mybatis.mapper.OrderMapper"><select id="queryOrderAndUserByOrderNumber" resultType="OrderUser">SELECTo.*,u.user_name, u.nameFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idWHERE order_number = #{orderNumber}</select></mapper>记得加入到全局配置文件中:
测试结果:
第二种实现:
核心思想:面向对象的思想,在Order对象中添加User对象。
package cn.zto.mybatis.pojo;/** * * @ClassName: Order * @Description:对应订单表 * @author: xyc * @date: 2017年2月11日 下午8:33:12 * */public class Order { private Integer id; private Long userId; private String orderNumber; private User user; //getter And setter}
Mapper接口:
/** * 查询订单,并且查询出下单人的信息。 * @param orderNumber * @return */ public Order queryOrderAndUserByOrderNumber2(String orderNumber);
Mapper映射文件
<!-- 在resultMap中,完成对象映射时,autoMapping默认为false,因此这里需要打开,否则有的属性关系无法对应 --><resultMap type="Order" id="orderResultMap" autoMapping="true"><id column="id" property="id"/><!--association:用户映射java对象property: 对象中的属性名称javaType:对象中的属性的类型 --><association property="user" javaType="User" autoMapping="true"><id column="user_id" property="id"/></association></resultMap><!-- 使用resultType不能完成自动映射,所以需要手动完成结果集的映射,需要使用resultMap实现。-->
<select id="queryOrderAndUserByOrderNumber2" resultMap="orderResultMap">SELECTo.*,u.user_name, u.nameFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idWHERE order_number = #{orderNumber}</select>测试:
@Testpublic void testQueryOrderAndUserByOrderNumber2() { Order order = this.orderMapper.queryOrderAndUserByOrderNumber2("20140921001"); System.out.println(order);}结果:
一对多查询
SELECTo.*,u.user_name, u.name,od.id detail_id,od.item_id,od.total_priceFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idLEFT JOIN tb_orderdetail od ON o.id = od.order_idWHERE order_number = '20140921001'
package cn.zto.mybatis.pojo;import java.util.List;/** * 订单表 * */public class Order { private Integer id; private Long userId; private String orderNumber; private User user; //映射一对多查询的订单详情 private List<Orderdetail> orderdetails; //getter And setter @Override public String toString() { return "Order [id=" + id + ", userId=" + userId + ", orderNumber=" + orderNumber + ", user=" + user + ", orderdetails=" + orderdetails + "]"; } }
package cn.zto.mybatis.pojo;/** * * @ClassName: Orderdetail * @Description:订单详情 * @author: xyc * @date: 2017年2月11日 下午9:42:28 * */public class Orderdetail { private Integer id; private Double totalPrice; private Integer status; private Integer itemId; private Item item; //getter and setter}
接口:
/** * 查询订单,查询出下单人信息并且查询出订单详情。 * * @param orderNumber * @return */public Order queryOrderAndUserAndOrderDetailByOrderNumber(String orderNumber);
<resultMap type="Order" id="orderUserOrderDetailresultMap" autoMapping="true"><id column="id" property="id"/><!-- association:映射java对象property: 对象中的属性名称javaType:对象中的属性的类型 --><association property="user" javaType="User" autoMapping="true"><id column="user_id" property="id"/></association><!-- collection:映射集合javaType: 属性的java类型ofType:集合中的对象的java类型 --><collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true"><id column="detail_id" property="id"/> </collection></resultMap><select id="queryOrderAndUserAndOrderDetailByOrderNumber" resultMap="orderUserOrderDetailresultMap">SELECTo.*,u.user_name, u.name,od.id detail_id,od.item_id,od.total_priceFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idLEFT JOIN tb_orderdetail od ON o.id = od.order_idWHERE order_number = #{orderNumber}</select>
测试:
@Testpublic void testQueryOrderAndUserAndOrderDetailByOrderNumber() { Order order = this.orderMapper.queryOrderAndUserAndOrderDetailByOrderNumber("20140921001"); System.out.println(order);}结果:
多对多查询
SELECTo.*,u.user_name, u.name,od.id detail_id,od.item_id,od.total_price,i.item_name,i.item_price,i.item_detailFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idLEFT JOIN tb_orderdetail od ON o.id = od.order_idLEFT JOIN tb_item i ON od.item_id = i.idWHERE order_number = '20140921001'
Item.java
package cn.zto.mybatis.pojo;/** * 商品表 */public class Item { private Integer id; private String itemName; private Float itemPrice; private String itemDetail; //getter and setter}
Orderdetail.java
package cn.zto.mybatis.pojo;/** * * @ClassName: Orderdetail * @Description:订单详情 * @author: xyc * @date: 2017年2月11日 下午9:42:28 * */public class Orderdetail { private Integer id; private Double totalPrice; private Integer status; private Integer itemId; private Item item; //gette and setter }
接口:
/** * 多对多查询 * 查询订单,查询出下单人信息并且查询出订单详情中的商品数据。 * @param orderNumber * @return */public Order queryOrderAndUserAndOrderDetailAndItemByOrderNumber(String orderNumber);
<resultMap type="Order" id="orderUserOrderDetailItemResultMap" autoMapping="true"><id column="id" property="id"/><!-- property: 对象中的属性名称javaType:对象中的属性的类型 --><association property="user" javaType="User" autoMapping="true"><id column="user_id" property="id"/></association><!-- 映射orderdetails --><collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true"><id property="id" column="detail_id"/><!-- 映射Orderdetail中的Item对象 --><association property="item" javaType="Item" autoMapping="true"><id property="id" column="item_id"/></association></collection></resultMap><select id="queryOrderAndUserAndOrderDetailAndItemByOrderNumber" resultMap="orderUserOrderDetailItemResultMap">SELECTo.*,u.user_name, u.name,od.id detail_id,od.item_id,od.total_price,i.item_name,i.item_price,i.item_detailFROMtb_order oLEFT JOIN tb_user u ON o.user_id = u.idLEFT JOIN tb_orderdetail od ON o.id = od.order_idLEFT JOIN tb_item i ON od.item_id = i.idWHERE order_number = #{orderNumber}</select>
测试:
@Testpublic void testQueryOrderAndUserAndOrderDetailAndItemByOrderNumber() { Order order = this.orderMapper.queryOrderAndUserAndOrderDetailAndItemByOrderNumber("20140921001"); System.out.println(order);}
结果:
ResultMap的继承
<!-- 在resultMap中,完成对象映射时,autoMapping默认为false,因此这里需要打开,否则有的属性关系无法对应 --><resultMap type="Order" id="orderResultMap" autoMapping="true"><id column="id" property="id"/><!-- property: 对象中的属性名称javaType:对象中的属性的类型 --><association property="user" javaType="User" autoMapping="true"><id column="user_id" property="id"/></association></resultMap>
我们可以通过继承来完善
<resultMap type="Order" id="orderUserOrderDetailItemResultMap" extends="orderResultMap" autoMapping="true"><!-- 映射orderdetails --><collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true"><id property="id" column="detail_id"/><!-- 映射Orderdetail中的Item对象 --><association property="item" javaType="Item" autoMapping="true"><id property="id" column="item_id"/></association></collection></resultMap>
extends的值为上面resultMap的id.
延迟加载
延迟加载的意义在于,虽然是关联查询,但不是及时将关联的数据查询出来,而且在需要的时候进行查询。
开启延迟加载:
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
lazyLoadingEnabled:true使用延迟加载,false禁用延迟加载。默认为true
aggressiveLazyLoading:true启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性)。默认为true
①. 添加cglib支持
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.1</version></dependency>
②.全局配置文件中开启延迟加载
<settings><!-- 开启驼峰映射 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 二级缓存的全局开关 --><setting name="cacheEnabled" value="true"/><!-- 延迟加载的开关 --><setting name="lazyLoadingEnabled" value="true"/><!-- true启用时,当延迟加载开启时访问对象中一个懒对象属性时,将完全加载这个对象的所有懒对象属性。false,当延迟加载时,按需加载对象属性(即访问对象中一个懒对象属性,不会加载对象中其他的懒对象属性) --><setting name="aggressiveLazyLoading" value="false"/></settings>
③.编写接口:
/** * 测试延迟加载 * 查询订单,并且查询出下单人的信息。 * @param orderNumber * @return */public Order lazyQueryOrderAndUserByOrderNumber(String orderNumber);
④.编写Mapper.xml
⑤.测试:
@Testpublic void testLazyQueryOrderAndUserByOrderNumber() { Order order = this.orderMapper.lazyQueryOrderAndUserByOrderNumber("20140921001"); User user = order.getUser();//触发延迟加载 System.out.println(user); System.out.println(order);}
结果:
- Mybatis学习总结(六).Mybatis高级查询及延迟加载
- MyBatis学习(六)---高级应用(延迟加载、缓存)
- mybatis学习之高级映射 延迟加载
- Mybatis查询延迟加载
- Mybatis框架学习(三)—高级映射,延迟加载
- mybatis详解-(16)分步查询及延迟加载
- 【MyBatis学习11】MyBatis中的延迟加载
- 【MyBatis学习11】MyBatis中的延迟加载
- 【MyBatis学习11】MyBatis中的延迟加载
- Mybatis学习(10)-MyBatis中的延迟加载
- 【MyBatis学习11】MyBatis中的延迟加载
- MyBatis学习五:延迟加载
- MyBatis学习五:延迟加载
- MyBatis学习五:延迟加载
- 【MyBatis框架】高级映射-延迟加载
- 【MyBatis框架】高级映射-延迟加载
- Mybatis延迟加载和查询缓存
- mybatis--关联映射及延迟加载
- ubnutu环境变量设置和sublime环境设置
- VC++ CEdit 和 CComboBox类 的使用
- 1月18日(作业)
- c++火柴棒问题
- Storm教程2安装部署
- Mybatis学习总结(六).Mybatis高级查询及延迟加载
- 站在巨人的肩上——Android热更新框架Tinker探索之旅
- PX4源码分析2_QGC地面站的下载和安装
- HDU4511
- 用 Python 编写网络爬虫 笔记
- 数据结构简单选择排序
- WebService 及java网络编程等基础概念(一)
- leetcode -- 235. Lowest Common Ancestor of a Binary Search Tree【区间,二叉搜索树特点】
- decltype类型指示符