12-MyBatis02
今日知识
1. 关联查询
2. 延时加载
3. 查询缓存
关联查询
1.一对一 resultType实现
1. 写个定单的扩展类
public class OrdersExt extends Orders {
private String username;
private String address;
2. 声明定单接口
public interface OrdersMapper {
//根据订单id查询订单信息
public OrdersExt findOrdersUser(int id);
}
3. 声明定单配置文件
<mapper namespace="com.rqy.mapper.OrdersMapper">
<sql id="select_orders">
orders.id,
orders.number,
orders.createtime,
orders.note,
</sql>
<sql id="select_user">
user.username,
user.address
</sql>
<select id="findOrdersUser" parameterType="int" resultType="ordersExt">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>
FROM
orders,user
WHERE
orders.user_id=user.id and orders.id=#{?};
</select>
</mapper>
4. 加载映射文件
<mappers>
<package name="com.rqy.mapper"/>
</mappers>
5. 测试
@Test
public void test(){
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
OrdersExt ordersExt = ordersMapper.findOrdersUser(3);
System.out.println(ordersExt);
sqlSession.commit();
}
6. 一对一 resultMap实现
<!--一对一 resultMap实现-->
<resultMap id="ordersRsMap" type="orders">
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象,Orders类有User user-->
<association property="user" javaType="com.rqy.model.User">
<id property="id" column="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersByRsMap" parameterType="int" resultMap="ordersRsMap">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>
FROM
orders,user
WHERE
orders.user_id=user.id and orders.id=#{?};
</select>
2.一对多 resultType实现
1. 在Orders中添加定单明细
private List<Orderdetail> orderdetails;
public List<Orderdetail> getOrderdetails() {
return orderdetails;
}
public void setOrderdetails(List<Orderdetail> orderdetails) {
this.orderdetails = orderdetails;
}
2. Mapper接口
//根据订单id查询订单信息,包括订单项
public Orders findOrdersByRsMap2(int ordersId);
3. OrderMapper.xml
<!--一对多resultMap实现-->
<resultMap id="ordersRsMap2" type="orders">
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象-->
<association property="user" javaType="com.rqy.model.User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
<!--集合映射-->
<collection property="orderdetails" ofType="orderdetail">
<id column="detail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itmesNum"/>
</collection>
</resultMap>
<select id="findOrdersByRsMap2" parameterType="int" resultMap="ordersRsMap2">
SELECT
<include refid="select_orders"/>
<include refid="select_user"/>,
orderdetail.id detail_id,
orderdetail.items_id,
orderdetail.items_num
FROM
orders,user,orderdetail
WHERE
orders.user_id=user.id
and orders.id=orderdetail.orders_id
and orders.id=#{?};
</select>
4. 测试
//一对一多resultMap实现
@Test
public void test2(){
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders order = ordersMapper.findOrdersByRsMap2(3);
System.out.println(order);
}
5. 总结:mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性
中。
3.多对多 resultType实现
1. 将用户信息映射到user中。
* 在user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist
* 在Orders中添加订单明细列表属性List<Orderdetail> detailList,将订单的明细映射到detailList
* 在Orderdetail中添加Items属性,将订单明细所对应的商品映射到Items
2. Mapper.xml
//查询用户信息及用户购买的商品信息
public List<User> findUserAndItemsRslMap();
3. UserMapper.xml
<!--查询用户购买的商品信息,多对多-->
<resultMap id="userAndItemsRslMap" type="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
<!--1.User里面的orderlist属性-->
<collection property="orderslist" ofType="orders">
<id column="orders_id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--2.Order里面的orderdetail属性-->
<collection property="orderdetails" ofType="orderdetail">
<id column="detail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itmesNum"/>
<!--orderdetail里面的items属性-->
<association property="items" javaType="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="findUserAndItemsRslMap" resultMap="userAndItemsRslMap">
SELECT
user.id,
user.username,
user.address,
orders.id orders_id,
orders.number,
orders.createtime,
orders.note,
orderdetail.id detail_id,
orderdetail.items_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>
4. 测试
//多对多resultMap实现
@Test
public void test3(){
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userAndItemsRslMap = userMapper.findUserAndItemsRslMap();
for (User user : userAndItemsRslMap) {
System.out.println("用户名:"+user.getUsername()+"-地址:"+user.getAddress());
for (Orders order : user.getOrderslist()){
System.out.println("订单id:"+order.getId());
System.out.println("订单number:"+order.getNumber());
System.out.println("订单时间:"+order.getCreatetime());
System.out.println("----------------------------------------");
for (Orderdetail orderdetail : order.getOrderdetails()) {
System.out.println();
System.out.println("商品数量:"+orderdetail.getItmesNum());
System.out.println("商品名称:"+orderdetail.getItems().getName());
System.out.println("商品详情:"+orderdetail.getItems().getDetail());
}
}
}
}
延时加载
* 分次查询:支持懒加载
* 连接查询:不支持懒加载
1. 概念:延迟加载又叫懒加载,也叫按需加载。
也就是说先加载主信息,在需要的时候,再去加载从信息。
2. 在mybatis中,resultMap标签的association标签和
collection标签具有延迟加载的功能。
3. 案例
1. OrdersMapper.java
//懒加载订单和用户信息
public List<Orders> findOrderAndUserByLazyLoading();
2. OrderMapper.xml配置
<!--==============懒加载==================-->
<resultMap id="LazyLoadingordersRsMap" type="orders">
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!--关联内部对象 ,支持懒加载-->
<association property="user" select="com.rqy.mapper.UserMapper.findUserById" column="user_id">
</association>
</resultMap>
<select id="findOrderAndUserByLazyLoading" resultMap="LazyLoadingordersRsMap">
SELECT * FROM orders
</select>
3. SqlMapConfig.xml
!--配置懒加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
4. 测试
//懒加载
@Test
public void test4(){
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
List<Orders> ordersList = ordersMapper.findOrderAndUserByLazyLoading();
for (Orders order : ordersList) {
System.out.println("订单号:"+order.getNumber());
System.out.println("订单所属人:"+order.getUser().getUsername());
System.out.println("========================");
}
}
5. 注意:association和collection:添加一个标签:当配置了lazyLoadingEnabled=true后,所有的分次查询都是懒加载,使用fetchType="eager",可以修改懒加载为立即加载
查询缓存
1. 概念:Mybatis的缓存,包括一级缓存和二级缓存,一级缓存是默认使用的。二级缓存需要手动开启。
2. 一级缓存
* 概念:一级缓存指的就是sqlsession,在sqlsession中有一个数据区域,是map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
* 案例:
1. @Test
public void test(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(35);
System.out.println(user);
System.out.println("======================");
//查询两次该用户信息,第二次不会执行sql语句
User user2 = mapper.findUserById(35);
System.out.println(user2);
}
2. 如果一旦执行完修改,添加,删除用户执行完commit,就会清空一级缓存。
@Test
public void test2(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(35);
System.out.println(user);
//保存,删除,更新会消除一级缓存
User u=new User("123","男",new Date(),"河南");
mapper.insertUser(u);
//第二次不会执行sql语句
User user2 = mapper.findUserById(35);
System.out.println(user2);
}
3. 二级缓存
* 概念:二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一个唯一值。一级缓存中的value,就是查询出的结果对象。
1. 步骤一:User序列化public class User implements Serializable {
2. <settings>
<!--二级缓存开关-->
<setting name="cacheEnabled" value="true"/>
</settings>
3. UserMapper中配置 二级缓存
<!--默认使用perpetualCache-->
<cache></cache>
4. 测试
//二级缓存
//查询
@Test
public void test3(){
SqlSession sqlSession1=ssf.openSession();
SqlSession sqlSession2=ssf.openSession();
SqlSession sqlSession3=ssf.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2= sqlSession2.getMapper(UserMapper.class);
UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
User user = mapper1.findUserById(35);
System.out.println(user);
sqlSession1.close();
//添加,删除,修改提交后,会清空二级缓存
mapper3.insertUser(user);
sqlSession3.commit();
//第二次不会执行sql语句
User user2 = mapper2.findUserById(35);
System.out.println(user2);
}
5. 禁用指定方法二级缓存
select标签中加入:useCache="false"
6. 刷新缓存
select,insert,update,加入flushCache="false",此时添加,删除,修改提交后,不会清空二级缓存,默认情况下:flushCache="true".
12-MyBatis02的更多相关文章
- python 各模块
01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 语言支 ...
- Python Standard Library
Python Standard Library "We'd like to pretend that 'Fredrik' is a role, but even hundreds of vo ...
- 在mybatis中写sql语句的一些体会
本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...
- AndroidStudio — Error:Failed to resolve: junit:junit:4.12错误解决
原博客:http://blog.csdn.net/u013443865/article/details/50243193 最近使用AndroidStudio出现以下问题: 解决:打开app下的buil ...
- 读过MBA的CEO更自私?《哈佛商业评论》2016年第12期。4星
老牌管理杂志.每期都值得精度.本期我还是给4星. 以下是本书中的一些内容的摘抄: 1:他们发现在Airbnb上,如果客人姓名听起来像黑人,那么比名字像白人的客人的接受率会低16%.#45 2:对立组织 ...
- 12个小技巧,让你高效使用Eclipse
集成开发环境(IDE)让应用开发更加容易.它们强调语法,让你知道是否你存在编译错误,在众多的其他事情中允许你单步调试代码.像所有的IDE一 样,Eclipse也有快捷键和小工具,这些会让您感觉轻松许多 ...
- 第12章 Linux系统管理
1. 进程管理 1.1 进程查看 (1)进程简介 进程是正在执行的一个程序或命令(如ls命令也是一个进程),每个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源. (2)进程管理的作用 ...
- Jexus Web Server 完全傻瓜化图文配置教程(基于Ubuntu 12.04.3 64位)[内含Hyper-v 2012虚拟机镜像下载地址]
1. 前言 近日有感许多新朋友想尝试使用Jexus,不过绝大多数都困惑徘徊在Linux如何安装啊,如何编译Mono啊,如何配置Jexus啊...等等基础问题,于是昨日向宇内流云兄提议,不如搞几个配置好 ...
- CSharpGL(12)用T4模板生成CSSL及其renderer代码
CSharpGL(12)用T4模板生成CSSL及其renderer代码 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立 ...
- ABP(现代ASP.NET样板开发框架)系列之12、ABP领域层——工作单元(Unit Of work)
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之12.ABP领域层——工作单元(Unit Of work) ABP是“ASP.NET Boilerplate Pr ...
随机推荐
- 快速搭建一个自己的个人博客(Github Pages~二次元主题)
前言 本次的一个布局技术都写的非常详细了,只要按着来就行,不过,先说明本次主题为二次元主题. 如果真的喜欢本主题的不妨可以试一试(==建议跟据目录来看==) 在很久很久以前.... 嘛,就在前不久我正 ...
- Elasticsearch系列---搜索执行过程及scroll游标查询
概要 本篇主要介绍一下分布式环境中搜索的两阶段执行过程. 两阶段搜索过程 回顾我们之前的CRUD操作,因为只对单个文档进行处理,文档的唯一性很容易确定,并且很容易知道是此文档在哪个node,哪个sha ...
- Docker学习(九)Volumn容器间共享数据
Docker学习(九)Volumn容器间共享数据 volume是什么 volume在英文中是容量的意思, 在docker中是数据卷的意思,是用来保存数据的容器 为什么要进行数据共享 在集群中有多台to ...
- java 方法定义 调用
一.定义 格式: 修饰符 返回值类型 方法名(参数){ return } 相比之下python方法的定义简单多了 public static 是修饰符 二.调用 方法名(); 注意:要在main方法中 ...
- scrapy持久化到Excel表格
前提条件: 防止乱码产生 ITEM_PIPELINES = { 'xpc.pipelines.ExcelPipeline': 300, } 方法一 1.安装openpyxl conda install ...
- CBV 序列化
一.模型表 from django.db import models # Create your models here. class Publish(models.Model): name = mo ...
- 月经贴 】 Csharp in depth
让你 真正 喜欢 上 C# 编译器 准备 为你 上演 的 奇迹. C# 3 中 相对 乏味 的 一些 特性 开始. 自动 实现 的 属性 和 简化 的 初始化, 有一个 私 有的 无 参 构造 函 ...
- Python学习,第一课 - 基础学习
前言. 本内容全部以python3所讲 一.Python安装 windows 1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\pyth ...
- 异想家Ubuntu安装的软件
[替换国内源] https://developer.aliyun.com/mirror/ubuntu 我提供一个下载,方便第一次安装懒得敲命令: https://jfz.me/16.04/source ...
- Intellij IDEA中将打开的代码与类文件进行关联
Intellij IDEA中在导航栏打开多个类时,如何快速定位到某个类所在的目录? 经过研究,可以通过以下设置完成: 设置完成后,点击导航栏中的类,左边的Project导航就可以快速定位到该类所在的目 ...