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.rhkb.cn/news/337099.html

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

相关文章

Docker管理工具Portainer忘记admin登录密码

停止Portainer容器 docker stop portainer找到portainer容器挂载信息 docker inspect portainer找到目录挂载信息 重置密码 docker run --rm -v /var/lib/docker/volumes/portainer_data/_data:/data portainer/helper-reset-password生成新的admin密码&#xff0c;使用新密…

分享6个打开就能让人眼前一亮的网站,每次浏览都像发现新大陆~

1、ZLibrary zh.zlibrary-be.se/ ZLibrary是一个广受欢迎的在线图书馆&#xff0c;它提供了一个庞大的电子书和文章资源库&#xff0c;数量超过千万。这个平台覆盖了国内外众多领域的电子书资源&#xff0c;几乎可以满足用户98%以上的搜索需求&#xff0c;无论是学术研究、文…

【介绍下运维,什么是运维?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

大数据开发面试题【Mysql篇】

181、mysql数据库中的引擎 用于数据存储、处理和保护数据的核心服务&#xff0c;不同的数据库引擎有其各自的特点&#xff0c;常见的引擎&#xff1a;InnoDB&#xff0c;Mylsam、Memory、Mrg_Mylsam、Blackhole innodb&#xff1a;是一个事务性存储引擎&#xff0c;提供了对事…

C++的第一道门坎:类与对象(一)

目录 1.面向过程与面向对象 1.1面向过程 1.2面向对象 1.3对比 2.类的引入 2.1类的声明方式 2.2类的成员的两种定义方式 2.2.1单文件定义 2.2.2多文件定义 3.类的访问限定符与封装 3.1访问限定符 3.2封装 4.类对象 4.1类对象的实例化 4.2类对象的存储 4.2.1 存储…

高并发项目-分布式Session解决方案

分布式Session解决方案 1.保存Session&#xff0c;进入商品列表页面 1.保存Session 1.编写工具类 1.MD5Util.java package com.sxs.seckill.utils;import org.apache.commons.codec.digest.DigestUtils;/*** Description: MD5加密工具类** Author sun* Create 2024/5/5 14…

Window系统安装Docker

因为docker只适合在liunx系统上运行&#xff0c;如果在window上安装的话&#xff0c;就需要开启window的虚拟化&#xff0c;打开控制面板&#xff0c;点击程序&#xff0c;在程序和功能中可以看到启动和关闭window功能&#xff0c;点开后&#xff0c;找到Hyper-V&#xff0c;Wi…

【环信IM集成教程】分分钟带你实现视频消息的在线播放和本地播放

有种需求&#xff0c;叫下班前实现 发送视频消息是即时通讯应用中很常见的功能&#xff0c;现在的视频播放场景五花八门&#xff0c;眼瞅快下班&#xff0c;接到产品需求 如何实现这个需求&#xff0c;好准点下班回家抢显卡 &#xff0c;快速提升自己的工作效率&#xff0c;那…

yolov5-ros模型结合zed2相机部署在 Ubuntu系统

前言 本篇文章主要讲解yolov5-ros模型结合zed2相机进行实时检测&#xff0c;经改进实现了红绿灯检测&#xff0c;并输出检测类别与置信度&#xff01; 目录 一、环境配置二、zed2驱动安装三、yolov5-ros功能包配置四、运行官方权重文件四、运行自己权重文件 一、环境配置 1、…

vue2转vue3初步下载pnpm遇到的问题 pnpm : 无法加载文件 D:\nodejs\pnpm.ps1

安装pnpm npm install -g pnpm pnpm -v 提示&#xff1a; 解决&#xff1a;nvm install 18.18.0 下载最稳定版本的nodejs nvm use 18.18.0 然后注意重新下载删除pnpm npm uninstall -g pnpm npm install -g pnpmlatest 在vscode使用pnpm报错 解决&#xff1a;管理员运行Windo…

博士毕业论文/CTEX/LATEX

LATEX环境安装 CTEX 安装 &#xff08;垃圾&#xff0c;不要装&#xff09; 运行 clean.batcomp.bat 缺少字体 Couldn’t find Adobe Heiti S.cfg’ miktex-maketfm: No creation rule for font “Adobe Heiti Std”.解决方法&#xff1a;其实就是下载这四个字体之后&…

深度学习-语言模型

深度学习-语言模型 统计语言模型神经网络语言模型语言模型的应用序列模型&#xff08;Sequence Model&#xff09;语言模型&#xff08;Language Model&#xff09;序列模型和语言模型的区别 语言模型&#xff08;Language Model&#xff09;是自然语言处理&#xff08;NLP&…

16:00面试,16:08就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

32. 【Java教程】集合

在前面的小节中&#xff0c;我们学习了数组&#xff0c;本小节学习的集合同样用于存放一组数据&#xff0c;我们将学习什么是集合、集合的应用场景 &#xff0c;在应用场景部分我们将对比 Java 数组与集合的区别&#xff0c;还将系统介绍 Java 集合的架构&#xff0c;也将结合实…

【课程总结】Day4:信息论和决策树算法

前言 本章内容主要是学习机器学习中的一个重要模型&#xff1a;决策树&#xff0c;围绕决策树的应用&#xff0c;我们展开了解到&#xff1a;熵的定义、熵的计算、决策树的构建过程(基于快速降熵)、基尼系数等&#xff0c;从而使得我们对决策树有了直观认识。 熵的介绍 因为…

用HAL库改写江科大的stm32入门-6-3 PWM驱动LED呼吸灯

接线图&#xff1a; 2 :实验目的&#xff1a; 利用pwm实现呼吸灯。 关键PWM定时器设置&#xff1a; 代码部分&#xff1a; int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*…

10.Halcon3D点云和MESH的相互转换

1.实现效果 这个案例主要是想告诉我们,如何在点云数据(全是点)和MESH(网格数据)中转换,理论上说可以点云数据可以看作的离散的,而MESH网格数据可以看作是连续的。 上图展示了三个(其实是四个)空间中的3d对象,左边第一个是一个立方体,经过降采样之后的点云,中间的是…

匿名函数(lambda)

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 匿名函数是指没有名字的函数&#xff0c;应用在需要一个函数&#xff0c;但是又不想费神去命名这个函数的场合。通常情况下&#xff0c;这样的函数只…

LabVIEW中进行步进电机的位置控制

在LabVIEW中进行步进电机的位置控制&#xff0c;通常涉及以下几个关键步骤&#xff1a;设置硬件、配置通信、编写控制算法和实施反馈控制。以下是一个详细的介绍。 硬件设置 步进电机&#xff1a;选择合适的步进电机&#xff0c;根据负载和应用需求选择适当的步数和转矩。 驱…

TensorFlow Playground神经网络演示工具使用方法详解

在现代机器学习领域,神经网络无疑是一个重要的研究方向。然而,对于许多初学者来说,神经网络的概念和实际操作可能显得相当复杂。幸运的是,TensorFlow Playground 提供了一个交互式的在线工具,使得我们可以直观地理解和实验神经网络的基本原理。在这篇博客中,我们将详细介…