MyBatis --- 缓存、逆向工程、分页插件
一、MyBatis的缓存
1.1、MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
使一级缓存失效的四种情况:
1、不同的SqlSession对应不同的一级缓存
2、同一个SqlSession但是查询条件不同
3、同一个SqlSession两次查询期间执行了任何一次增删改操作
4、同一个SqlSession两次查询期间调用 clearCache()方法 手动清空了缓存
@Testpublic void testGetEmpById(){SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);Emp emp1 = mapper1.getEmpById(1);System.out.println(emp1);sqlSession1.clearCache();//手动清空一级缓存//mapper1.insertEmp(new Emp(null, "小红", 25, "男"));Emp emp2 = mapper1.getEmpById(1);System.out.println(emp2);/*SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);Emp emp3 = mapper2.getEmpById(1);System.out.println(emp3);*/}
1.2、MyBatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
二级缓存开启的条件:
1、在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
2、在映射文件中设置 <cache /> 标签
3、二级缓存必须在SqlSession关闭或提交之后有效
4、查询的数据所转换的实体类类型必须实现序列化的接口 Serializable
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
@Testpublic void testCache() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);SqlSession sqlSession1 = sqlSessionFactory.openSession(true);CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);Emp emp1 = mapper1.getEmpById(1);System.out.println(emp1);sqlSession1.close();SqlSession sqlSession2 = sqlSessionFactory.openSession(true);CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);Emp emp2 = mapper2.getEmpById(1);System.out.println(emp2);sqlSession2.close();}
1.3、二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置一些属性:
1、eviction属性:缓存回收策略,默认的是 LRU。
LRU(Least Recently Used)– 最近最少使用的:移除最长时间不被使用的对象。
FIFO(First in First out)– 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
2、flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新(增删改)
3、size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出
4、readOnly属性:只读, true / false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。
1.4、MyBatis缓存查询的顺序
先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
如果二级缓存没有命中,再查询一级缓存
如果一级缓存也没有命中,则查询数据库
SqlSession关闭之后,一级缓存中的数据会写入二级缓存
1.5、整合第三方缓存EHCache
1.5.1、添加依赖
<!-- Mybatis EHCache整合包 --><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.1</version></dependency><!-- slf4j日志门面的一个具体实现 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>
1.5.2、各jar包功能
1.5.3、创建EHCache的配置文件ehcache.xml
<?xml version="1.0" encoding="utf-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"><!-- 磁盘保存路径 --><diskStore path="D:\mybatis\ehcache"/><defaultCachemaxElementsInMemory="1000"maxElementsOnDisk="10000000"eternal="false"overflowToDisk="true"timeToIdleSeconds="120"timeToLiveSeconds="120"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache>
</ehcache>
1.5.4、设置二级缓存的类型
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
1.5.5、加入logback日志
存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日 志。 创建logback的配置文件logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true"><!-- 指定日志输出的位置 --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 日志输出的格式 --><!-- 按照顺序分别是: 时间、日志级别、线程名称、打印日志的类、日志主体内容、换行--><pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger][%msg]%n</pattern></encoder></appender><!-- 设置全局日志级别。日志级别按顺序分别是: DEBUG、INFO、WARN、ERROR --><!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 --><root level="DEBUG"><!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender --><appender-ref ref="STDOUT" /></root><!-- 根据特殊需求指定局部日志级别 --><logger name="com.atguigu.crowd.mapper" level="DEBUG"/>
</configuration>
1.5.6、EHCache配置文件说明
二、MyBatis的逆向工程
正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工 程的。
逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
- Java实体类
- Mapper接口
- Mapper映射文件
2.1、创建逆向工程的步骤
①添加依赖和插件
<!-- 依赖MyBatis核心包 --><dependencies><!-- Mybatis核心 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.13</version></dependency><!-- junit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.32</version></dependency><!-- log4j日志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><!-- 控制Maven在构建过程中相关配置 --><build><!-- 构建过程中用到的插件 --><plugins><!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.0</version><!-- 插件的依赖 --><dependencies><!-- 逆向工程的核心依赖 --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.2</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.32</version></dependency></dependencies></plugin></plugins></build>
②创建MyBatis的核心配置文件
③创建逆向工程的配置文件
文件名必须是:generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!--targetRuntime: 执行生成的逆向工程的版本MyBatis3Simple: 生成基本的CRUD(清新简洁版)MyBatis3: 生成带条件的CRUD(奢华尊享版)--><context id="DB2Tables" targetRuntime="MyBatis3"><!-- 数据库的连接信息 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true"userId="root"password="mdzz"></jdbcConnection><!-- javaBean的生成策略--><javaModelGenerator targetPackage="com.ssm.mybatis.pojo"targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- SQL映射文件的生成策略 --><sqlMapGenerator targetPackage="com.ssm.mybatis.mapper"targetProject=".\src\main\resources"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- Mapper接口的生成策略 --><javaClientGenerator type="XMLMAPPER"targetPackage="com.ssm.mybatis.mapper" targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 逆向分析的表 --><!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName --><!-- domainObjectName属性指定生成出来的实体类的类名 --><table tableName="t_emp" domainObjectName="Emp"/><table tableName="t_dept" domainObjectName="Dept"/></context>
</generatorConfiguration>
④执行MBG插件的generate目标
⑤效果
2.2、QBC查询
@Testpublic void testMBG(){SqlSession sqlSession = SqlSessionUtil.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//根据id查询数据/*Emp emp = mapper.selectByPrimaryKey(1);System.out.println(emp);*///查询所有数据/*List<Emp> list = mapper.selectByExample(null);list.forEach(System.out::println);*///根据条件查询数据/*EmpExample example = new EmpExample();example.createCriteria().andEmpNameEqualTo("张三").andAgeGreaterThanOrEqualTo(20);example.or().andGenderEqualTo("男");List<Emp> list = mapper.selectByExample(example);list.forEach(System.out::println);*/Emp emp = new Emp(1, "小黑", null, "女");//测试普通修改功能//mapper.updateByPrimaryKey(emp);//测试选择性修改mapper.updateByPrimaryKeySelective(emp);}
三、分页插件
3.1、分页插件的使用步骤
①添加依赖
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.0</version>
</dependency>
②配置分页插件
在MyBatis的核心配置文件中配置插件
<plugins><!--设置分页插件--><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
3.2、分页插件的使用
1、在查询功能之前使用 PageHelper.startPage(int pageNum, int pageSize) 开启分页功能
pageNum:当前页的页码
pageSize:每页显示的条数
2、在查询获取list集合之后,使用 PageInfo pageInfo = new PageInfo<>(List list, int navigatePages) 获取分页相关数据
list:分页之后的数据
navigatePages:导航分页的页码数
3、分页相关数据
public class PageTest {/*** PageInfo{* pageNum=1, pageSize=4, size=4,* startRow=1, endRow=4, total=30,* pages=8,* list=Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=30, pages=8, reasonable=false, pageSizeZero=false}[Emp{empId=1, empName='aaa', age=null, gender='null', deptId=null}, Emp{empId=2, empName='a', age=null, gender='null', deptId=null}, Emp{empId=3, empName='a', age=null, gender='null', deptId=null}, Emp{empId=4, empName='a', age=null, gender='null', deptId=null}],* prePage=0, nextPage=2, isFirstPage=true,* isLastPage=false, hasPreviousPage=false,* hasNextPage=true, navigatePages=5,* navigateFirstPage=1, navigateLastPage=5, navigatepageNums=[1, 2, 3, 4, 5]}*/@Testpublic void testPage(){SqlSession sqlSession = SqlSessionUtil.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//查询功能之前开启分页功能Page<Object> page = PageHelper.startPage(1, 4);List<Emp> list = mapper.selectByExample(null);//查询功能之后可以获取分页相关的所有数据PageInfo<Emp> pageInfo = new PageInfo<>(list, 5);list.forEach(System.out::println);System.out.println(pageInfo);}
}
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]
相关文章:

MyBatis --- 缓存、逆向工程、分页插件
一、MyBatis的缓存 1.1、MyBatis的一级缓存 一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问 使一级缓存失效的四种情况: 1、…...

vue3自定义svg图标组件
可参考: 未来必热:SVG Sprites技术介绍 懒人神器:svg-sprite-loader实现自己的Icon组件 在Vue3项目中使用svg-sprite-loader 前置知识 在页面中,虽然可以通过如下的方式使用img标签,来引入svg图标。但是,…...

智能火焰与烟雾检测系统(Python+YOLOv5深度学习模型+清新界面)
摘要:智能火焰与烟雾检测系统用于智能日常火灾检测报警,利用摄像头画面实时识别火焰与烟雾,另外支持图片、视频火焰检测并进行结果可视化。本文详细介绍基于智能火焰与烟雾检测系统,在介绍算法原理的同时,给出Python的…...

Java实习生------JUC并发编程(多线程)10道面试题打卡⭐⭐⭐
目录 并行和并发有什么区别? 线程和进程有什么区别? 创建线程有哪几种方式? runnable和callable有什么区别? 线程的状态及转换? sleep()和wait()的区别? run()和start()有什么区别? 在…...

ChatGPT和百度文心一言写用例,谁更强?
文心一言发布的第一时间,就排队申请了邀请码,昨晚看了下,邀请码已经到手,索性就拿一个例子试了一下,看看哪个能够真正意义上的提高生产力,最简单的录制了个GIF动画如下:问题:你是一个…...

设计模式总结
设计模式的六大原则 开放-封闭原则(OCP) (总原则) Open-Close Principle:该对扩展开放,对修改关闭。 目的就是保证程序的扩展性好,易于维护和升级。 开放-封闭原则是面向对象设计的核心所在, 开闭原则是Java世界里最基础的设计原则。 开闭…...

【K8S系列】深入解析Pod对象(一)
目录 序言 1.问题引入 1.1 问题描述 2 问题解答 2.1 pod 属性 2.1.1 NodeSelector 2.1.2 HostAliases 2.1.3 shareProcessNamespace 2.1.4 NodeName 2.1.5 其他pod属性 2.2 容器属性 2.2.1 ImagePullPolicy 2.2.2 Lifecycle 3 总结 4. 投票 序言 任何一件事情&am…...

JVM学习.02 内存分配和回收策略
1、前言《JVM学习.01 内存模型》篇讲述了JVM的内存布局,其中每个区域是作用,以及创建实例对象的时候内存区域的工作流程。上文还讲到了关于对象存货后,会被回收清理的过程。今天这里就着重讲一下对象实例是如何被清理回收的,以及清…...

logstash+elasticsearch+Kibana(ELK)日志收集
文章目录一.安装ELK 7.17二.为Elasticsearch设置密码三.配置logstash四.springboot整合logstash五.spring整合Elastic Search一.安装ELK 7.17 不要一股脑执行以下语句,请观察修改要修改的地方 安装logstash # logstash安装docker run -d --name logstash \-p 5043:5043 -p 5…...

今天面试了一个2年Java经验的
今天去面试了一个26岁的程序员,看了简历,2年经验,本科,写得很牛叉。 Spring cloud alibaba全家桶、redis,分布式锁,服务调用,数据库事务,线程,Zookeeper、Dubbo 、Rabbi…...

逻辑覆盖测试用例设计
逻辑覆盖测试用例设计 实验目标 能够依据程序画出程序流程图理解常用覆盖方法的内涵理解常用覆盖方法的强弱关系能够使用常用覆盖方法设计测试用例 背景知识 白盒测试通常采用静态测试方法和动态测试方法开展。动态测试是参照系统需求或测试规则,通过预先设计一…...

面试官:说一下MySQL中的锁机制吧
5. 1MySQL有哪些锁? 为保证数据的一致性,需要对并发操作进行控制,因此产生了锁。同时锁机制也为实现MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库并发访问性能的一个重要因素。所以锁对数据库而言显得尤其重要,也更加…...

STL库中list的迭代器实现痛点分析
前文本篇文章准备换个模式,之前都是先详解模拟实现,但是模拟实现的基本逻辑大多数老铁都是明白的,所以我们这次主要讲解STL库中list的独特性,也就是模拟实现中的重难点文末有模拟实现的源码一,list实现的特殊类list实现…...

字符编码对比(GBK、Unicode、UTF-8)
摘要我们在网上能看到各种文字和符号,那么它们是怎么存储和转化的,还有我们常常提及的UTF-8,为什么都要设置这种编码方式,这里就探讨下。字符集字符集:就是各国文字、符号、数字的集合。常见的字符集有:ASC…...

【百面成神】Redis基础11问,你能坚持到第几问
前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:纯手打总结面试题,自用备用 🌰 文章简介:Redis最基础、重要的11道面试题 文章目录…...

十大排序算法极简汇总篇
说明 十大排序算法可以说是每个程序员都必须得掌握的了,如果你们像从 0 详细学习每一篇,那么你们可以看前面的文章。 但是呢,有些人可能已经学过,想要快速复习一下,看看代码怎么写的,那么可以看这篇十大排…...

数据结构笔记
文章目录第一章:数据结构与算法第二章:稀疏数组和队列一 、稀疏sparsearray 数组(一)案例需求(二)稀疏数组介绍(三)应用实列(四)代码实现二、队列(…...

web前端框架——Vue的特性
目录 前言: 一.vue 二.特性 1.轻量级 2.数据绑定 3.指令 4.插件 三.比较Angular 、React 、Vue 框架之间的比较 1. Angular Angular的优点: 2. React React 的优点: 3.vue 3.Vue的优点: 前言: 本篇文章…...

提权工具推荐(PEASS-ng、linpeas_linux_amd64、winPEASany_ofs)
介绍 在这里,您可以找到适用于Windows、Linux/Unix*和MacOS的权限提升工具。 这些工具搜索您可以利用的可能的本地权限提升路径,并用漂亮的颜色打印给您,这样您就可以很容易地识别错误配置。 查看book.hacktricks.xyz中的本地Windows权限提升检查表WinPEAS-Windows本地权限…...

Spark - 继承 FileOutputFormat 实现向 HDFS 地址追加文件
目录 一.引言 二.源码浅析 1.RDD.saveAsTextFile 2.TextOutputFormat 3.FileOutputFormat 三.源码修改 1.修改文件生成逻辑 - getRecordWriter 2.允许目录存在 - checkoutputSpecs 3.全部代码 - TextOutputFormatV2 四.追加存储代码实战 五.总结 一.引言 Output d…...

树莓派编程控制继电器及继电器组
目录 一,继电器说明 ● 继电器接口说明 ① 继电器输入端: ② 继电器输出端: 二,树莓派控制继电器 三,树莓派控制继电器组 一,继电器说明 通俗点讲,可以把继电器理解成是一些功能设备的控制开关。 ● LOW&#…...

oracle和mysql的区别
Oracle与MySQL的区别以及优缺点 MySQL的特点 1、性能卓越,服务稳定,很少出现异常宕机; 2、开放源代码无版本制约,自主性及使用成本低; 3、历史悠久,社区和用户非常活跃,遇到问题及时寻求帮助…...

<Linux开发> linux应用开发-之-uart通信开发例程
一、简介 串口全称叫做串行接口,串行接口指的是数据一个一个的按顺序传输,通信线路简单。使用两条线即可. 实现双向通信,一条用于发送,一条用于接收。串口通信距离远,但是速度相对会低,串口是一种很常用的工…...

基于深度学习的安全帽检测系统(YOLOv5清新界面版,Python代码)
摘要:安全帽检测系统用于自动化监测安全帽佩戴情况,在需要佩戴安全帽的场合自动安全提醒,实现图片、视频和摄像头等多种形式监测。在介绍算法原理的同时,给出Python的实现代码、训练数据集,以及PyQt的UI界面。安全帽检…...

Linux - 进程控制(进程替换)
0.引入创建子进程的目的是什么?就是为了让子进程帮我执行特定的任务让子进程执行父进程的一部分代码如果子进程想执行一个全新的程序代码呢? 那么就要使用进程的程序替换为什么要有程序替换?也就是说子进程想执行一个全新的程序代码ÿ…...

Java中 ==和equals的区别是什么?
作用: 基本类型,比较值是否相等引用类型,比较内存地址值是否相等不能比较没有父子关系的两个对象equals()方法的作用: JDK 中的类一般已经重写了 equals(),比较的是内容自定义类如果没有重写 equals(),将…...

Linux(网络基础---网络层)
文章目录0. 前言1. IP协议1-1 基本概念1-2 协议头格式2. 网段划分2-1 基本概念2.2 IP地址分五大类2-3 特殊的IP地址2-4 IP地址的数量限制2-5 私有IP地址和公网IP地址2-6 路由0. 前言 前面我们讲了,应用层、传输层;本章讲网络层。 应用层:我…...

空间信息智能应用团队研究成果介绍及人才引进
目录1、多平台移动测量技术1.1 车载移动测量系统1.2 机载移动测量系统2、数据处理与应用技术研究2.1 点云与影像融合2.2 点云配准与拼接2.3 点云滤波与分类2.4 道路矢量地图提取2.5 道路三维自动建模2.6 道路路面三维病害分析2.7 多期点云三维变形分析2.8 地表覆盖遥感监测分析…...

ChatGPT应用场景与工具推荐
目录 写在前面 一、关于ChatGPT 二、应用实例 1.写文章 2.入门新的知识 3.解决疑难问题 4.生成预演问题 5.文本改写 6.语言翻译 7.思维导图 8.PDF阅读理解 9.操作格式化的数据 10.模拟场景 11.写代码 三、现存局限 写在前面 本文会简单介绍ChatGPT的特点、局限以…...

图像分类卷积神经网络模型综述
图像分类卷积神经网络模型综述遇到问题 图像分类:核心任务是从给定的分类集合中给图像分配一个标签任务。 输入:图片 输出:类别。 数据集MNIST数据集 MNIST数据集是用来识别手写数字,由0~9共10类别组成。 从MNIST数据集的SD-1和…...