MyBatis延迟加载缓存分页逆向工程

文章目录

  • 延迟加载
    • 概述
    • 步骤
  • 缓存
    • 一级缓存
      • 介绍
      • 原理
    • 二级缓存
      • 介绍
    • 设置缓存对象策略
      • 原理
      • 开启步骤
      • 属性解释
      • 是否使用一级缓存
  • 分页插件
    • 使用步骤
  • 逆向工程
    • 介绍
    • 搭建
    • 使用
      • 修改

延迟加载

概述

延迟加载本身是依赖于多表查询的

  • 延迟加载中返回值要选择resultMap
  • 返回的结果一定是Dto

延迟加载也可以成为按需加载;默认是没有开启的

步骤

  1. 在config.xml中配置下面代码
<!-- lazyLoadingEnabled:延迟加载全局开关,开启后所有关联对象都会延迟加载;默认是falseaggressiveLazyLoading:按需加载;开启时,任一方法的调用都会加载该对象的所有延迟加载属性,因此设置为false;设置为false表示的意思就是按需加载;mybatis版本3.4以上默认是false--><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="false"/>

使用的时候需要将lazyLoadingEnabled设置为true,将aggressiveLazyLoading设置为false

  1. 在mapper.xml中书写下面代码
	<!-- 一对多 --><select id="selectOrderAndDetails" resultMap="map1" >select * from b_order</select><resultMap type="BOrderDto" id="map1" extends="BaseMap"><!-- 延迟加载和多表查询(高级映射)的区别:在标签(collection或者association)中,添加column属性和select属性;select属性中:里面的内容写的是:namespace.sqlID;表示的是:用来封装当前collection或者association的返回结果也就是select属性值中的sqlid查询出来的应该是和ofType同等类型;column属性指的是:第一步查询结果中的列名——》用作参数传入到select调用的sqlId中;--><collection property="details" ofType="BOrderDetailDto" column="id" select="selectDetails"></collection></resultMap><!-- 按需加载,如果还需要查看订单详情信息,则调用该方法: --><select id="selectDetails" resultMap="map2">select  id detail_id, goods_id, main_id, price, numfrom b_order_detail where main_id = #{id}</select><resultMap type="BOrderDetailDto" id="map2"><id column="detail_id" property="id"></id><result column="goods_id" property="goodsId"/><result column="main_id" property="mainId"/><result column="price" property="price"/><result column="num" property="num"/></resultMap>

缓存

mybatis为减轻数据库压力,提高数据库性能。提供了两级缓存机制:
mybatis框架中包含了一级缓存和二级缓存

一级缓存

介绍

框架中默认开启了一级缓存,一级缓存是sqlSession级别的缓存,缓存的数据只在SqlSession内有效

原理

  1. 第一次查询用户id为1的用户信息,先去缓存中查询是否有id为1的用户信息,如果没有,从数据库中查询用户信息。得到用户信息后,再将用户信息存储到一级缓存中
  2. 如果sqlSession去执行commit操作(插入,更新,删除),就会清空sqlSession中的一级缓存,保证缓存中始终保存的是最新的信息,避免脏读
  3. 第二次查询用户id为1的信息,先去缓存中查询是否有id为1的用户信息,如果缓存中有,则直接从缓存中获取
  4. :两次查询须在同一个sqlSession中完成,否则将不会走mybatis的一级缓存。在mybatis与spring进行整合开发时,事务控制在service中进行,重复调用俩次service将不会走一级缓存,因为在第一次调用时session方法结束,SqlSession就关闭了

注意事项

  1. 一个SqlSession结束后那么它里面的一级缓存也就不存在了
  2. mybatis的缓存是基于[namespace:sql:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的

二级缓存

介绍

  1. mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的,多个sqlSession去操作同一个Mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨SqlSession的
  2. 二级缓存需要我们手动开启
  3. 作用域为namespace是指对该namespace对应的配置文件中所有的select操作结果都缓存,这样不同线程之间就可以共用二级缓存

设置缓存对象策略

  1. readOnly=“true”(只读):Mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。Mybatis为了加快获取数据,直接就会将数据在缓存中的引用交给用户。不安全,速度快
  2. readOnly=“false”(读写,默认):Myabtis觉得获取的数据可能会被修改,Mybatis会利用序列化或反序列化的技术克隆一份新的数据。安全,速度相对慢

原理

  1. 当一个sqlSession执行了一次select后,并关闭此session的时候,就会将查询结果存储到二级缓存中
  2. 当另一个sqlSession执行相同select时,首先会查询二级缓存,二级缓存中无对应数据,再去查询一级缓存,一级缓存中也没有,最后去数据库查找,从而减少了数据库压力提高了性能

注意事项

  1. 原理和一级缓存原理一样
  2. 开启了二级缓存后,还需要将要缓存的pojo实现Serializable接口,为了将缓存数据取出执行反序列化操作

开启步骤

  1. 在mybatis-config.xml中添加下列代码
<setting name="cacheEnabled" value="true"/>
  1. 在xxxMapper.xml文件中添加
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"/>
  1. 对返回的结果对应的实体类进行序列化:implements Serializable
  2. 执行的时候对SqlSession进行关闭

属性解释

  1. eviction:缓存的回收策略,默认是LRU
  • LRU:最近最少使用,移除最长时间不被使用的对象
  • FIFO:先进先出,按对象进入缓存的顺序来移除它们
  • SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
  • WEAK:弱引用,更积极地移除基于垃圾收集器和弱引用规则的对象
  1. flushInterval:缓存刷新间隔。缓存多长时间清空一次,默认不清空,设置一个毫秒值
  2. readOnly:是否只读
  • true:只读
  • false:读写,默认
  1. size:缓存存放多少个元素
  2. type:指定自定义缓存的全类名(实现Cache接口即可)

是否使用一级缓存

如果一条语句每次都需要最新的数据,就意味着每次都需要从数据库中查询数据,可以把这个属性设置为false,如

<select id="selectUserById" resultMap="map" useCache="false">

二级缓存默认会在insert,update,delete操作后刷新缓存,但可以手动配置不更新缓存

<update id="updateUserById" parameterType="User" flushCache="false">

分页插件

pageHelper
官网:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

使用步骤

  1. 在pom.xml中添加如下依赖
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>最新版本</version>
</dependency>
  1. 配置拦截器插件(在config.xml中)
<!--plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:properties?, settings?,typeAliases?, typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?, databaseIdProvider?, mappers?
-->
<plugins><!-- com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor="com.github.pagehelper.PageInterceptor"><!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --><property name="param1" value="value1"/></plugin>
</plugins>
  1. 书写代码

方式1:

//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum()); // 当前页
assertEquals(10, page.getPageSize()); //每页显示条数
assertEquals(1, page.getStartRow()); 
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());   //总条数
assertEquals(19, page.getPages());   //总页数
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());  //是否有前一页
assertEquals(true, page.isHasNextPage());

方式2:

//对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy());

逆向工程

介绍

正向工程操作:项目->需求分析->创建uml类图->创建实体类->表
逆向工程:表->创建实体类

搭建

  1. 逆向工程通常创建java项目,导入逆向工程所需要的maven插件
<build><!--可配置多个插件--><plugins><!--其中的⼀个插件:mybatis逆向⼯程插件--><plugin><!--插件的GAV坐标--><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.2</version><!--允许覆盖--><configuration><overwrite>true</overwrite></configuration><!--插件的依赖--><dependencies><!--mysql驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies></plugin></plugins></build>
  1. 在resources下创建文件名为generatorConfig.xml(文件名必须是这个)
  • xml
<!DOCTYPE generatorConfiguration PUBLIC"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!--targetRuntime有两个值:MyBatis3Simple:⽣成的是基础版,只有基本的增删改查。MyBatis3:⽣成的是增强版,除了基本的增删改查之外还有复杂的增删改查。context:一个配置文件中可以有多个context标签;id:表示唯一标识;defaultModelType:conditional:正常生成一个实体类,如果实体类中只有一个主键字段,不会生成实体类;flat:会为每张表生成一个实体类,实体类中包含表中所有字段;hierarchical:如果表中存在主键则生成主键类;表中非主键列并且非Blob类型的列,会生成一个类,该类继承主键类如果存在Blob类型的列,则为该类型的列生成专门的类,该类继承非主键类;targetRuntime:目标运行环境:--><context id="DB2Tables"  targetRuntime="MyBatis3"><!--防⽌⽣成重复代码--><plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/><commentGenerator><!--是否去掉⽣成⽇期--><property name="suppressDate" value="true"/><!--是否去除注释--><property name="suppressAllComments" value="true"/></commentGenerator><!--连接数据库信息--><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/db11?nullCatalogMeansCurrent=true"userId="root"password="123456"></jdbcConnection><!-- ⽣成pojo包名和位置 --><javaModelGenerator targetPackage="cn.ry.pojo" targetProject="src/main/java"><!--是否开启⼦包--><property name="enableSubPackages" value="true"/><!--是否去除字段名的前后空⽩--><property name="trimStrings" value="true"/></javaModelGenerator><!-- ⽣成SQL映射⽂件的包名和位置 --><sqlMapGenerator targetPackage="cn.ry.mapper" targetProject="src/main/resources"><!--是否开启⼦包--><property name="enableSubPackages" value="true"/></sqlMapGenerator><!-- ⽣成Mapper接⼝的包名和位置 --><javaClientGeneratortype="xmlMapper"targetPackage="cn.ry.mapper"targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><!-- 表名和对应的实体类名--><table tableName="tb_item" domainObjectName="Item"/></context>
</generatorConfiguration>
  1. 执行

image.png

  1. 出现BUID SUCCESS就是创建成功

image.png

使用

方法名含义
insert(obj)新增
insertSelective(obj)新增

区别:如果表中某列设置了默认值,新增语句中,刚好没给这一列赋值,此时前者赋值为null,后者赋值为默认值

方法名含义
deleteByPrimaryKey(key)根据主键id进行删除
deleteByExample(example)自定义条件删除

修改

方法名含义
updateByPrimaryKeySelective(obj)根据id进行修改,只更新不为空的数据;如果某列不想修改,直接不写,不会修改原来的值
updateByPrimaryKey(obj)根据id进行修改
updateByExampleSelective(obj,example)根据自定义条件进行修改
updateByExample(obj,example)根据自定义条件进行修改,如果没有设置id会报错

方法名含义
selectByPrimaryKey(key)根据主键去查询
countByExample(example)根据自定义条件查询数量
selectByExample(example)根据自定义条件查询

example的代码使用如下

			SqlSession s = SqlSessionUtil.getSqlSession();BOrderMapper mapper = s.getMapper(BOrderMapper.class);BOrderExample example =new BOrderExample();//创建条件对象;Criteria c = example.createCriteria();//使用条件对象中的方法:c.andOrderNoLike("%02%");c.andTotalGreaterThan(1);创建条件对象2;Criteria c1 = example.createCriteria();c1.andIdIsNotNull();example.or(c1);List<BOrder> list = mapper.selectByExample(example);System.out.println(list.size());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数学建模 —— 插值与拟合(1)

一、matlab画图 1.1 plot&#xff08;二维图形&#xff09; plot(x) —— 缺省自变量绘图格式 plot(x,y) —— 基本格式&#xff0c;以y(x)的函数关系作出直角坐标图&#xff0c;如果y为nm的矩阵&#xff0c;则以x为自变量&#xff0c;作出m条曲线 plot(x1,y1,x2,y2,…,xn,…

python循环引用和解决方法

目录 1. 延迟导入 2. 使用 importlib 3. 重构代码 4. 使用类型提示的前向引用 在Python中&#xff0c;两个文件循环引用的问题通常发生在模块相互依赖导致的导入循环。这种情况下&#xff0c;解决循环引用的方法有几种&#xff0c;以下是一些常见的解决方案&#xff1a; 1…

神经网络算法详解与前沿探索

神经网络算法详解与前沿探索 随着人工智能技术的迅猛发展&#xff0c;神经网络成为机器学习领域的重要组成部分&#xff0c;广泛应用于图像识别、自然语言处理和推荐系统等。本文将详细探讨神经网络的基本原理、结构、训练过程及其应用实例&#xff0c;并扩展至更多相关领域和…

基于标准库的STM32的外部中断EXTI

毕设已经告一段落了&#xff0c;接下来准备开始整理一下毕设中用到的知识与技术细节&#xff0c;今天整理的是STM32从编码器获取数据的方式-----外部中断&#xff08;EXTI&#xff09;&#xff1a; 外部中断分为四个硬件相关外设&#xff0c;GPIO/AFIO/EXTI/NVIC&#xff08;E…

jQuery前端开发入门图片:探索图片操作的奥秘与技巧

jQuery前端开发入门图片&#xff1a;探索图片操作的奥秘与技巧 在前端开发中&#xff0c;图片的处理与展示往往占据着举足轻重的地位。jQuery&#xff0c;作为一款流行的JavaScript库&#xff0c;为我们提供了丰富的图片操作方法和技巧。本文将通过四个方面、五个方面、六个方…

戴尔向“数”而行,以“质”致远,做新质生产力的躬耕者

【全球存储观察 &#xff5c; 热点关注】 自1984年戴尔成立&#xff0c;一路走来&#xff0c;戴尔科技集团40年长期持续的技术创新&#xff0c;一直引领全球科技行业的技术趋势。 到如今&#xff0c;AIGC风行一时&#xff0c;在重塑千行百业的同时&#xff0c;也加速了科技行业…

选择算法之冒泡排序【图文详解】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

题目:求0—7所能组成的奇数个数。

题目&#xff1a;求0—7所能组成的奇数个数。 There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated should…

[大师C语言(第十七篇)]C语言链表背后技术详解

引言 链表是一种常见的数据结构&#xff0c;用于存储线性数据集合。在C语言中&#xff0c;链表由一系列节点组成&#xff0c;每个节点包含数据和指向下一个节点的指针。本文将深入探讨C语言链表背后的技术原理&#xff0c;并通过丰富的代码示例来讲解其应用。 第一部分&#…

北斗应急救援终端如何做好汛期重点行业安全防控?

【安全提示】 汛期各地高温多雨、极端天气增多 防汛和安全生产形势严峻复杂如何做好汛期重点行业企业安全生产风险防控&#xff1f; 顶坚北斗短报文终端V1单北斗定位终端 北斗应急救援终端在汛期重点行业安全防控中扮演着关键角色&#xff0c;其高可靠性、稳定性和丰富的功能扩…

达摩院AI早癌筛查技术闪耀联合国,癌症早治时代来临?

全文预计1200字左右&#xff0c;预计阅读需要6分钟。 5月30日&#xff0c;在日内瓦举行的联合国AI大会上&#xff0c;各国的代表性企业拿出最优秀的AI成果进行分享。其中代表中国的是阿里巴巴集团的下属机构-达摩院&#xff0c;其在现场播放的一段影像&#xff0c;让在场的所有…

uniApp子组件监听数据的变化的方法之一

props:{//用来接收外界传递过来的数据swiperList:{type:Array,default:[]}}, swiperList&#xff1a;是父组件传递过来的值 通过 watch 监听&#xff08;在父组件中也同样可以使用&#xff0c;跟VUE的监听数据变化同理&#xff09; watch:{//监听组件中的数据变化swiperList(ol…

Diffusion Facial Forgery (DiFF) ——一个新的大规模人脸伪造检测数据集

1. 概述 近年来&#xff0c;条件扩散模型&#xff08;CDM&#xff09;在图像生成领域备受关注。它能够通过简单的输入&#xff08;如自然语言提示&#xff09;生成令人惊讶的忠实图像。然而&#xff0c;这一进步也引发了新的安全和隐私问题。例如&#xff0c;怀有恶意的个人现…

【笔记】使用XtraBackup进行热备份

备份环境&#xff1a; 具备dockermysql8(5.7及以下版本更换xtrabackup版本即可&#xff0c;具体版本号查看官网)将云盘挂载到服务器上&#xff0c;可以使用s3协议 #!/bin/bash# 目录配置部分 HOST_BACKUP_DIR"/root/docker/mysql8/backup/full" # 宿主机备份目录 H…

结构体(C保姆级讲解)

前言&#xff1a; 为什么会有结构体&#xff0c;结构体可以用来面熟一个复杂对象&#xff0c;我们知道C语言中有哪些数据类型&#xff0c;有整型&#xff0c;有浮点型&#xff0c;有字符型&#xff0c;但是在生活中&#xff0c;我们需要描述一些比较复杂的东西&#xff0c;比如…

如何理解央行买卖国债?

浙商证券覃汉认为&#xff0c;央行对长债的风险持续关注&#xff0c;30年国债收益率较难突破2.5%&#xff0c;区间底部已经多次印证&#xff0c;在学习效应影响下&#xff0c;长端利率预计继续以震荡调整为主。 1、央行买卖国债的政策要求、历史经验、优势 2023年中央金融工作…

语音助手拦截,拦截小秘书

呼叫中心业务场景下会遇到很多的语音助手和语音小秘书&#xff0c;还有一些漏话提醒、语音信箱等&#xff1b;大部分原因是由于主叫号码标记问题导致的局端和终端拦截策略&#xff0c;电话没有真实有效的触达并产生了通信费&#xff0c;这让很多业务场景下通信成本上涨据不完全…

常用中间件各版本下载

常用中间件下载地址 前言分布式中间件负载均衡中间件缓存中间件数据库中间件其他中间件1、Maven下载地址2、Git下载地址2、JDK下载地址3、MySQL下载地址4、Redis下载地址5、Nacos下载地址6、Tomcat下载地址7、Nginx下载地址8、RocketMQ下载地址8、RabbitMQ下载地址8、Erlang下载…

【Redis】常见的 Redis 集群方案

Redis 集群用于在多个 Redis 节点之间分布数据&#xff0c;以提高可用性和扩展性。常见的 Redis 集群方案有以下几种&#xff1a; 1. 哨兵 (Sentinel) Sentinel 是一种高可用解决方案&#xff0c;用于监控 Redis 主从复制的实例并在主节点发生故障时进行自动故障转移。 优点…

Amazon云计算AWS(三)

目录 五、关系数据库服务RDS&#xff08;一&#xff09;RDS的基本原理&#xff08;二&#xff09;RDS的使用 六、简单队列服务SQS&#xff08;一&#xff09;SQS的基本模型&#xff08;二&#xff09;SQS的消息 七、内容推送服务CloudFront&#xff08;一&#xff09;CDN&#…