MyBatis --- 缓存、逆向工程、分页插件

news/2024/4/24 7:35:30/

一、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&amp;useSSL=false&amp;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]


http://www.ppmy.cn/news/47445.html

相关文章

ElasticSearch——详解主从模式,以及主节点的选取算法(一)

详解主从模式&#xff0c;以及主节点的选取算法 Discovery模块负责发现集群中的节点&#xff0c;以及选择主节点。 ES支持多种不同Discovery类型选择&#xff0c;内置的实现称为Zen Discovery&#xff0c;其他的包括公有云平台亚马逊的EC2、谷歌的GCE等。本文讨论内置的Zen Di…

rviz 可视化手机 IMU

原博客&#xff1a;https://www.cnblogs.com/hitcm/p/5616364.html 原代码&#xff1a;https://github.com/hitcm/Android_Camera-IMU.git 上面说的不太详细&#xff0c;出现了无法可视化 IMU 转交的情况。git 的 issue 中也有人遇到这个问题。本博客记录了自己如何克服 BUG 并…

【C++】map和set的模拟实现

文章目录 1、map、set和红黑树源码的截取2、红黑树的迭代器3、代码部分3-1、Set.h3-2、Map.h3-3、RBTee.h3-4、测试代码 1、map、set和红黑树源码的截取 我们红黑树的节点只需要用到value值就够了&#xff0c;value是什么&#xff0c;节点就存什么。但是&#xff0c;红黑树的源…

MySQL学习笔记第一天

第02章 MySQL环境搭建 1.MySQL的卸载 步骤1&#xff1a;停止MySQL服务 在卸载之前&#xff0c;先停止MySQL8.0的服务。按键盘上的“Ctrl Alt Delete”组合键&#xff0c;打开“任务管理器”对话框&#xff0c;可以在“服务”列表找到“MySQL8.0”的服务&#xff0c;如果现…

肖 sir_就业课__014python讲解

python讲解 一、python梳理 1、python 数据类型有哪些&#xff1f; 字符、列表、元组、字典、集合 2、列表、元组、字典、集合的区别&#xff1f; 3、python中函数&#xff1f; &#xff08;1&#xff09;自定义函数 def 函数名&#xff08;&#xff09; &#xff08;2&#…

树莓派计算机视觉编程:6~10

原文&#xff1a;Raspberry Pi Computer Vision Programming 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&#xff…

maven安装教程(结合eclipse和IDEA)

一.安装maven 本文须知:安装maven环境之前要先安装java jdk环境(没有安装java环境的可以先去看安装JAVA环境的教程)Maven 3.3+ require JDK 1.7 及以上。 第一步:下载maven(本教程安装的是3.8.4) 官方下载链接:https://maven.apache.org/download.cgi Binary是可执行版本…

MyBatisPlus3.4.3版自动生成代码的使用

AutoGenerator 是 MyBatis-Plus 的代码生成器&#xff0c;通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码&#xff0c;极大的提升了开发效率。 1 准备工作 创建springboot工程&#xff0c;这里省略。 2 导入依赖 <d…

靶机精讲之HackademicRTB1

主机发现 nmap扫描 端口扫描 只有80端口开放 UDP扫描 web渗透 服务扫描 脚本扫描 DOS攻击漏洞 枚举漏洞 查看web端 进行目录爆破 点击 点击后发现地址结构像有目录爆破 接上面枚举漏洞 复制那枚举目录到web 接目录爆破 apeache服务器 查看内容管理系统是否是自建的 在库搜索…

第九篇 Spring数据库事务管理

《Spring》篇章整体栏目 ————————————————————————————— 【第一章】spring 概念与体系结构 【第二章】spring IoC 的工作原理 【第三章】spring IOC与Bean环境搭建与应用 【第四章】spring bean定义 【第五章】Spring 集合注入、作用域 【第六章】…

以人为本的重点是有效网络安全计划的关键

安全和风险管理 (SRM) 领导者在根据九大行业趋势创建和实施网络安全计划时&#xff0c;必须重新考虑他们在技术和以人为本的元素之间的投资平衡。 以人为本的网络安全方法对于减少安全故障至关重要。 在控制设计和实施以及通过业务沟通和网络安全人才管理中关注人&#xff…

learn_C_deep_3 (最名不符实的关键字 - static、static关键字总结、基本数据类型、最冤枉的关键字 - sizeof)

目录 最名不符实的关键字 - static stati修饰全局变量和函数 static修饰局部变量 static关键字总结 几个问题 1.c语言要设置全局变量和函数可以跨文件使用的原因 2.C程序地址空间是什么样的&#xff1f; 3.局部变量为什么具有临时性 4.全局变量为什么具有全局性 5.为…

辉煌优配|军工板块逆市上涨,16只概念股已披露一季度业绩预喜

今日&#xff0c;军工股逆市上涨。 4月21日&#xff0c;A股三大股指低开低走&#xff0c;半导体、AI使用、信创工业、软件等科技属性概念领跌&#xff0c;国防军工、食品饮料和电力设备等板块上涨。 工业互联网中心工业规模超1.2万亿元 据央视新闻报道&#xff0c;本年是《工业…

组态王与FX5U之间如何快速实现无线通讯?

本方案是基于Modbus RTU协议下实现的1主多从自组网无线通信形式&#xff0c;主站为组态王&#xff0c;从站为两台三菱FX5U PLC。在工厂里&#xff0c;组态王和plc所处位置距离较为分散&#xff0c;重新铺设电缆线工期长&#xff0c;成本高&#xff0c;故采用日系PLC专用无线通讯…

Prophet模型中使用外生变量、自定义周期性

Prophet模型中使用外生变量 在使用 Prophet 进行时间序列预测时&#xff0c;我们可能需要考虑一些与时间序列相关但是并不在时间序列中体现的因素&#xff0c;比如天气、特别节日等&#xff0c;这些因素被称为 外生变量&#xff08;external regressors&#xff09;。添加外生变…

案例分享 | 汽车电机控制箱螺钉浮高检测

电机控制器是通过主动工作来控制电机按照设定的方向、速度、角度、响应时间进行运动的集成电路&#xff0c;日常生活中的洗衣机、冰箱、印刷机等设备都需要电机控制器来控制其运行工作&#xff0c;是各种机械设备中不可或缺的部件。 在电动车辆中&#xff0c;电机控制器也是关…

Google FLASH-QUAD Transformer模型的设计雷点

这个模型用来做无序弱监督分类&#xff0c;效果好&#xff0c;特别是收敛速度比标准多头Attention层快多了&#xff0c;完全没得比。 问题1 但这模型我用来做自回归生成&#xff0c;非常垃圾。 同时尝试了 GPT 和 T5 这两种模型结构的设计&#xff0c;明明Loss正常下降&#…

Python‘s Standard Library :Networking

Python’s Standard Library &#xff1a;Networking Python的标准库为创建网络服务和远程访问服务提供了一些模块。例如&#xff1a;ipaddress, socket, socketserver 等。 Python’s standard library comes complete with modules for creating network services, as well …

JAVA面试宝典: SpringCloud知识点(通俗易懂易背)

1、什么是 Spring Cloud&#xff1f; Spring Cloud 是基于 Spring Boot 的微服务架构开发工具箱&#xff0c;提供了在分布式系统中构建可靠的、弹性的、灵活的应用所需的大多数工具。Spring Cloud 中包含的子项目如下&#xff1a; Spring Cloud Config&#xff1a;配置管理工具…

STL :双端队列容器 Deque

Deque #include<deque> using namesace std; 双端队列容器 &#xff1a;双向开口的连续线性空间&#xff1b; 擅长尾部和头部添加或删除元素&#xff1a;常数阶&#xff1b; 存储元素并不能保证所有元素都存储到连续的内存空间中&#xff1b; deque 是动态的以分段…