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 ...
随机推荐
- Yolo V3理解bbox和label的关系
假如一个bbox坐标为:[35 220 62 293 3] 第一步:将bbox转换为中心坐标和宽高形式(3种缩放比例进行缩放) 那么onehot:[0 0 0 1 0 0 0 0 0 0 ...... ...
- 曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- Asp.Net Core下的开源任务调度平台ScheduleMaster—快速上手
概述 ScheduleMaster是一个开源的分布式任务调度系统,它基于Asp.Net Core平台构建,支持跨平台多节点部署运行. 它的项目主页在这里: https://github.com/hey ...
- js六种数据类型
六种数据类型: undefined . boolean .string .number .object .function 效果地址:https://scrimba.com/c/cEedDGTd 代 ...
- 最小生成树kruskal 知识点讲解+模板
0.前言 因为本人太蒟了 我现在连NOIP的初赛都在胆战心惊 并且我甚至连最小生成树都没有学过 所以这一篇博客一定是最详细的QAQ 哈哈 请您认真看完如果有疏漏之处敬请留言指正 感谢! Thanks♪ ...
- 倍增ST应用 选择客栈(提高组)
重磅例题!ST表应用!提高组Getting! 1125: B15-倍增-习题:选择客栈[ST表应用] 时间限制: 1 Sec 内存限制: 128 MB提交: 35 解决: 12[提交] [状态] ...
- 12.方法重载overload
方法重载:overload 重载就是在一个类中,有相同的函数名称,但形参不同的函数 方法重载的规则: 方法名称必须相同 参数列表必须不同(个数不同.或类型不同.参数排列顺序不同等) 方法的返回值类型可 ...
- python接口自动化中,注册接口随机生成手机号码
如大家所知在注册接口中,手机号参数需要的是未注册的手机号,而在测试用例中,你写入的手机号不一定是未注册的.所以这时需要对注册接口中传入的手机号做处理.下面我就分享一个课程里面学到的一个处理手机号的py ...
- C++中虚析构的作用
为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用. 基本概念: 析构函数是用来回收对象的: 虚析构函数是析构函数的一种: 基类是一类对象共有属性的抽象.比如,猫和狗都是动物,都会 ...
- linux下svn安装和使用(centos)
1.安装svn 本地测试环境 centos6.5 # yum安装 yum -y install subversion # 查看svn版本 svnserve --version # 建立版本库目录 mk ...