今日知识

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的更多相关文章

  1. python 各模块

    01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 语言支 ...

  2. Python Standard Library

    Python Standard Library "We'd like to pretend that 'Fredrik' is a role, but even hundreds of vo ...

  3. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

  4. AndroidStudio — Error:Failed to resolve: junit:junit:4.12错误解决

    原博客:http://blog.csdn.net/u013443865/article/details/50243193 最近使用AndroidStudio出现以下问题: 解决:打开app下的buil ...

  5. 读过MBA的CEO更自私?《哈佛商业评论》2016年第12期。4星

    老牌管理杂志.每期都值得精度.本期我还是给4星. 以下是本书中的一些内容的摘抄: 1:他们发现在Airbnb上,如果客人姓名听起来像黑人,那么比名字像白人的客人的接受率会低16%.#45 2:对立组织 ...

  6. 12个小技巧,让你高效使用Eclipse

    集成开发环境(IDE)让应用开发更加容易.它们强调语法,让你知道是否你存在编译错误,在众多的其他事情中允许你单步调试代码.像所有的IDE一 样,Eclipse也有快捷键和小工具,这些会让您感觉轻松许多 ...

  7. 第12章 Linux系统管理

    1. 进程管理 1.1 进程查看 (1)进程简介 进程是正在执行的一个程序或命令(如ls命令也是一个进程),每个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源. (2)进程管理的作用 ...

  8. Jexus Web Server 完全傻瓜化图文配置教程(基于Ubuntu 12.04.3 64位)[内含Hyper-v 2012虚拟机镜像下载地址]

    1. 前言 近日有感许多新朋友想尝试使用Jexus,不过绝大多数都困惑徘徊在Linux如何安装啊,如何编译Mono啊,如何配置Jexus啊...等等基础问题,于是昨日向宇内流云兄提议,不如搞几个配置好 ...

  9. CSharpGL(12)用T4模板生成CSSL及其renderer代码

    CSharpGL(12)用T4模板生成CSSL及其renderer代码 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立 ...

  10. ABP(现代ASP.NET样板开发框架)系列之12、ABP领域层——工作单元(Unit Of work)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之12.ABP领域层——工作单元(Unit Of work) ABP是“ASP.NET Boilerplate Pr ...

随机推荐

  1. Nginx的一理解(2)

    1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片)通过HTTP协议展现给客户端. 配置:

  2. python 注册登录(文件操作)

    name = input("请注册用户:") password = input("请注册密码:") with open(file="user" ...

  3. python 验证客户端的合法性

    目的:对连接服务器的客户端进行判断 # Server import socket import hmac import os secret_key = bytes('tom', encoding='u ...

  4. IO系统-文件与目录操作

    1.文件内核数据结构 一个打开的文件在内核中使用三种数据结构表示: (1)文件描述符表 文件描述符标志 文件表项指针 (2)文件表项: 文件状态标志:读.写.追加.同步和非阻塞等状态标志 当前文件偏移 ...

  5. 3d动态文字的绘制

    在这里介绍一种3D文字的一种动态效果,可以说这是一种伪3D创建的一种3D的视觉效果 简单的讲解一下:大家或多或少都会听说过素描这种绘画手法,其实这种手法就是巧妙的利用了.阴影给人们带来的立体的视觉冲击 ...

  6. 养成编程思维,可以从python开始,今天说说python注释

    先看思维导图!对内容简单了解一下. 提高代码的可读性,需要提供对代码的注释.python注释,主要作用在代码中,对代码功能进行解释,是一种标注性文字.一般情况下分成三类,单行注释.多行注释.中文声明注 ...

  7. Spring(四)核心容器 - BeanDefinition 解析

    前言 在上篇文章中,我们讨论了 refresh 的前四个方法,主要是对 ApplicationContext 上下文启动做一些准备工作.原计划是对接下来的 invokeBeanFactoryPostP ...

  8. Docker基础内容之仓库

    前言 Docker提供了开放的中央仓库dockerhub,同时也允许我们使用registry搭建本地私有仓库.搭建私有仓库有如下的优点: 节省网络带宽,提升Docker部署速度,不用每个镜像从Dock ...

  9. 推荐一本书学习springcloud书籍的SpringCloud微服务全栈技术与案例解析

    整本书还算是挺详细的,基本大部分轮子都讲到了,唯一不足就是版本比较旧,而且springcloud 版本现在迭代这么快 很多内容其实高版本中完全没有了,得自己敲代码多采坑 前面基本章节其实可以大致略过一 ...

  10. sys model 常见用法

    import sys #与python解释器 交互 print(sys.argv) #是一个列表 解释器执行文件名后面可以增加字符串 以列表元素形式添加进去def foo(): print('ok') ...