当前位置: 首页 > news >正文

MyBatis —— 动态SQL和缓存

前言

        在上一篇文章中荔枝梳理了一些特殊的SQL查询和一对多、多对一的映射关系,而在这篇文章中荔枝将会梳理有关MyBatis动态SQL和MyBatis缓存的相关知识,同时也稍微了解了有关MyBatis中借助MAVEN中的插件管理来实现逆向工程。希望对需要的小伙伴有帮助哈哈哈~~~


文章目录

目录

一、动态SQL

1.1 if标签

1.2 where标签

1.3 trim标签 

1.4 choose、when、otherwise标签

1.5 foreach标签

1.5 sql标签

二、MyBatis的缓存

2.1 一级缓存

2.2 二级缓存

2.3 MyBatis缓存查询顺序

三、MyBatis的逆向工程(MBG)

总结


一、动态SQL

        Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的问题。在执行SQL查询时,只有属性值存在我们才能做相应的SQL语句的拼接,因此我们需要动态来拼装SQL语句。在JDBC中我们根据不同的条件拼接SQL语句时往往需要注意一些预留处理,而MyBatis的动态SQL特性就极大地简化了这一处理过程。

1.1 if标签

根据if标签中的test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.crj.mybatis.mapper.DynamicSQLMapper"><!--    List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="Emp">select * from t_emp where 1=1<if test="empName != null and empName != ''">and emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="sex != null and sex != ''">and sex = #{sex}</if></select>
</mapper>

        这段实例demo中,我们需要在select语句中添加一个恒成立的条件1=1,这是为了防止SQL语句在某些属性不存在时出现的拼接错误。动态SQL的特性其实类似一种按需加载的过程,弹性拼接起SQL语句。if标签中的test属性其实就是if标签中的SQL语句段拼接的条件,满足这个条件才能拼接在原有的查询SQL语句中。

1.2 where标签

        where标签可以辅助我们动态生成SQL语句中的where关键字,当where后面有内容时,where标签会帮助我们自动生成where关键字,同时会去掉内容前多余的and和or关键字,此时就无需我们手动添加where关键字和恒成立的条件了;当where后面没有内容时,此时不会生成where关键字。

<!--    List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="Emp">select * from t_emp<where><if test="empName != null and empName != ''">and emp_name = #{empName}</if><if test="age != null and age != ''">and age = #{age}</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select>

1.3 trim标签 

若标签中有内容时,属性功能正常;若标签没有内容时, trim不会有任何效果。

几个属性:

prefix:将trim标签中内容前面添加指定内容

suffix:将trim标签中内容后面添加指定内容

prefixOverrides:将trim标签中内容前面去掉指定内容

suffixOverrides:将trim标签中内容后面去掉指定内容

<!--    List<Emp> getEmpByCondition(Emp emp);--><select id="getEmpByCondition" resultType="Emp">select * from t_emp<trim prefix="where" suffixOverrides="and|or"><if test="empName != null and empName != ''">emp_name = #{empName} and</if><if test="age != null and age != ''">age = #{age} and</if><if test="sex != null and sex != ''">sex = #{sex}</if></trim></select>

1.4 choose、when、otherwise标签

choose和when标签组合起来相当于if...else if...else的结构,如果所有的when条件都不满足,则会执行otherwise中的条件。

<!--    List<Emp> getEmpByChoose(Emp emp);--><select id="getEmpByChoose" resultType="Emp">select * from t_emp<where><choose><when test="empName != null and empName != ''">emp_name = #{empName}</when><when test="age != null and age != ''">age = #{age}</when><when test="sex != null and sex != ''">sex = #{sex}</when><otherwise>did = 1</otherwise></choose></where></select>

1.5 foreach标签

foreach标签简单来说就是一个循环,可以被用来执行批量操作,foreach标签有五种属性:

  • collection:设置需要循环的数组或集合
  • item:循环出来的单个对象
  • sqparator:循环体之间的分隔符
  • open:循环的所有内容开头的内容
  • close:循环的所有内容结束的内容
<!--    int deleteMoreByArray(Integer[] eids);--><delete id="deleteMoreByArray">delete * from t_emp where eid in<foreach collection="eids" item="eid" separator="," open="(" close=")">#{eid}</foreach></delete>

1.5 sql标签

sql标签又成为SQL片段,它可以用来记录常用的sql执行语句。通过include标签来引用SQL片段。

    <sql id="emColumns">eid,emp_name,age,sex,email</sql><select id="getEmpByChoose" resultType="Emp">select <include refid="emColumns"></include> from t_emp      </select>

二、MyBatis的缓存

2.1 一级缓存

MyBatis的一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据就会从缓存中直接获取而不会从数据库中重新访问。一级缓存是默认开启的

一级缓存失效的四种情况:

  • 不同的SqlSession对应不同的一级缓存
  • 同一个SqlSession但是查询条件不同
  • 同一个SqlSessioni两次查询期间执行了任何一次增删改操作
  • 同一个SqlSession两次查询期间手动清空了缓存 

手动清空缓存:

sqlSession.clearCache();

2.2 二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSessioni查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取。

二级缓存开启的条件:

  1. 在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
  2. 在映射文件中设置标签<cache />
  3. 二级缓存必须在SqlSession关闭或提交之后有效 sqlSession.close() | sqlSession.commit()
  4. 查询的数据所转换的实体类类型必须实现序列化的接口

实体类实现序列化接口

public class Emp implements Serializable 

二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效。

二级缓存的相关配置

在二级缓存的开启条件中,我们发现<cache />标签是可以配置一些属性的,具体如下

eviction属性:缓存回收策略

  • LRU(Least Recently Used)-最近最少使用的:移除最长时间不被使用的对象。
  • FIFO(First in First out)-先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT-软引用:移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK-弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

默认的是LRU。

flushlnterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用增删改语句时刷新

size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出

readOnly属性:只读,true/false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是flse。

2.3 MyBatis缓存查询顺序

        首先先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。如果二级缓存没有命中,再查询一级缓存;如果一级缓存也没有命中,则查询数据库。注意在sqlSession关闭之后,一级缓存中的数据会写入二级缓存


三、MyBatis的逆向工程(MBG)

正向工程:先创建ava实体类,由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。
逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

  • Java实体类
  • Mapper接口
  •  MapperB映射文件 

在使用逆向工程之前首先应该配置好项目依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.crj</groupId><artifactId>MyBatis_MBG</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><!--依赖MyBatis核心包--><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.3</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><!--数据库连接池c3p0--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.2</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.8</version></dependency></dependencies></plugin></plugins></build>
</project>

逆向工程配置文件:

<?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:生成基本的CRUDMyBatis:生成带条件的CRUD--><!-- 是否去除自动生成的注释 true:是 : false:否 --><context id="DB2Tables" targetRuntime="MyBatis3Simple"><!-- 数据库连接 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/mybatis"userId="root"password="123456"></jdbcConnection><!--javaBean的生成策略生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下--><javaModelGenerator targetPackage="com.crj.mybatis.pojo" targetProject=".\src\main\java"><!--是否能够使用子包--><property name="enableSubPackages" value="true" /><!-- 从数据库返回的值被清理前后的空格  --><property name="trimStrings" value="true" /></javaModelGenerator><!--SQL映射文件的生成策略对应的mapper.xml文件--><sqlMapGenerator targetPackage="com.crj.mybatis.mapper" targetProject=".\src\main\resources"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- 对应的Mapper接口类文件的生成策略 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.crj.mybatis.mapper" targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 逆向分析的表 --><table tableName="t_emp" domainObjectName="Emp"/><table tableName="t_dept" domainObjectName="Dept"/></context>
</generatorConfiguration>

测试类中我们这样来进行条件查询:

EmpExample example = new EmpExample();
//这里可以借助example.createCriteria().and开头的方法来设置查询条件
example.createCriteria().andEmpNameEqualTo("荔枝");
mapper.selectByExample(example);

总结

嘿哈!MyBatis的相关知识学习也就大致到这里啦,荔枝接下来会继续学习mall项目,希望九月份能遇见不一样的自己吧哈哈哈哈。最近看丙哥的文章嘿嘿,分享给大家一句话:习惯自律,享受孤独~~~

今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,麻烦举起小爪爪点个赞吧哈哈哈~~~ 比心心♥~~~

相关文章:

MyBatis —— 动态SQL和缓存

前言 在上一篇文章中荔枝梳理了一些特殊的SQL查询和一对多、多对一的映射关系&#xff0c;而在这篇文章中荔枝将会梳理有关MyBatis动态SQL和MyBatis缓存的相关知识&#xff0c;同时也稍微了解了有关MyBatis中借助MAVEN中的插件管理来实现逆向工程。希望对需要的小伙伴有帮助哈哈…...

恒流电路的三种设计方案

作为硬件研发工程师相信对恒流电路不会陌生&#xff0c;本文介绍下三种恒流电路的原理图。 三极管恒流电路 三极管恒流电路 三极管的恒流电路&#xff0c;主要是利用Q2三极管的基级导通电压为0.6~0.7V这个特性&#xff1b;当Q2三极管导通&#xff0c;Q1三极管基级电压被拉低而…...

QT基础 关于QT延迟

目录 QT提供延时 1.自定义延时 2.使用QElapsedTimer 3.使用事件循环 4.跨平台延时 QT提供延时 这里提供四种方法&#xff1a; 1、多线程程序使用QThread::sleep()或者QThread::msleep()或QThread::usleep()或QThread::wait()进行延时处理。 Sleep不会释放对象锁&#x…...

LLM - LLaMA-2 获取文本向量并计算 Cos 相似度

目录 一.引言 二.获取文本向量 1.hidden_states 与 last_hidden_states ◆ hidden_states ◆ last_hidden_states 2.LLaMA-2 获取 hidden_states ◆ model config ◆ get Embedding 三.获取向量 Cos 相似度 1.向量选择 2.Cos 相似度 3.BERT-whitening 特征白化 …...

【创建型设计模式】C#设计模式之工厂模式,以及通过反射实现动态工厂。

题目如下&#xff1a; 假设你正在为一家汽车制造公司编写软件。公司生产多种类型的汽车&#xff0c;包括轿车、SUV和卡车。每种汽车都有不同的特点和功能。请设计一个工厂模式&#xff0c;用于创建不同类型的汽车对象。该工厂模式应具有以下要求&#xff1a;工厂类名为 CarFac…...

可拖拽编辑的流程图X6

先上图 //index.html&#xff0c;有时候可能加载失败&#xff0c;那就再找一个别的cdn 或者npm下载&#xff0c;如果npm下载&#xff0c; //那么需要全局引入或者局部引入&#xff0c;代码里面写法也会不同&#xff0c;详细的可以看示例<script src"https://cdn.jsdeli…...

神经网络与卷积神经网络

全连接神经网络 概念及应用场景 全连接神经网络是一种深度学习模型&#xff0c;也被称为多层感知机&#xff08;MLP&#xff09;。它由多个神经元组成的层级结构&#xff0c;每个神经元都与前一层的所有神经元相连&#xff0c;它们之间的连接权重是可训练的。每个神经元都计算…...

《Java极简设计模式》第05章:原型模式(Prototype)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…...

OceanBase 4.1解读:读写兼备的DBLink让数据共享“零距离”

梁长青&#xff0c;OceanBase 高级研发工程师&#xff0c;从事 SQL 执行引擎相关工作&#xff0c;目前主要负责 DBLink、单机引擎优化等方面工作。 沈大川&#xff0c;OceanBase 高级研发工程师&#xff0c;从事 SQL 执行引擎相关工作&#xff0c;曾参与 TPC-H 项目攻坚&#x…...

STM32的HAL库的定时器使用

用HAL库老是忘记了定时器中断怎么配置&#xff0c;该调用哪个回调函数。今天记录一下&#xff0c;下次再忘了就来翻一下。 系统的时钟配置&#xff0c;定时器的时钟是84MHz 这里定时器时钟是84M&#xff0c;分频是8400后&#xff0c;时基就是1/10000s&#xff0c;即0.1ms。Per…...

Flink+Paimon多流拼接性能优化实战

目录 &#xff08;零&#xff09;本文简介 &#xff08;一&#xff09;背景 &#xff08;二&#xff09;探索梳理过程 &#xff08;三&#xff09;源码改造 &#xff08;四&#xff09;修改效果 1、JOB状态 2、Level5的dataFile总大小 3、数据延迟 &#xff08;五&…...

cocos 2.4 版本 设置物理引擎步长 解决帧数不一致的设备 物理表现不一致问题 设置帧刷新率

官网地址Cocos Creator 3.8 手册 - 2D 物理系统 官网好像写的不太对 下面是我自己运行好使的 PhysicsManager.openPhysicsSystem()var manager cc.director.getPhysicsManager();// 开启物理步长的设置manager.enabledAccumulator true;// cc.PhysicsManagercc.PhysicsManag…...

Spark及其生态简介

一、Spark简介 Spark 是一个用来实现快速而通用的集群计算的平台&#xff0c;官网上的解释是&#xff1a;Apache Spark™是用于大规模数据处理的统一分析引擎。 Spark 适用于各种各样原先需要多种不同的分布式平台的场景&#xff0c;包括批处理、迭代算法、交互式查询、流处理…...

从Instagram到TikTok:利用社交媒体平台实现业务成功

自 2000年代初成立和随后兴起以来&#xff0c;社交媒体一直被大大小小的品牌用作高度针对性的营销工具&#xff0c;自 Facebook推出近二十年以来&#xff0c;这些网站继续彻底改变企业处理广告的方式。 在这篇博文中&#xff0c;我们将讨论订阅企业应该如何从整体上对待社交媒…...

单元测试

1. 单元测试Junit 1.1 什么是单元测试&#xff1f;&#xff08;掌握&#xff09; 对部分代码进行测试。 1.2 Junit的特点&#xff1f;&#xff08;掌握&#xff09; 是一个第三方的工具。&#xff08;把别人写的代码导入项目中&#xff09;&#xff08;专业叫法&#xff1a;…...

科技云报道:AI+云计算共生共长,能否解锁下一个高增长空间?

科技云报道原创。 在过去近一年的时间里&#xff0c;AI大模型从最初的框架构建&#xff0c;逐步走到落地阶段。 然而&#xff0c;随着AI大模型深入到千行百业中&#xff0c;市场开始意识到通用大模型虽然功能强大&#xff0c;但似乎并不能完全满足不同企业的个性化需求。 大…...

ReactPy:使用 Python 构建动态前端应用程序

在 Web 开发领域,ReactJS 已成为主导者,为开发人员提供了用于创建动态和交互式用户界面的强大工具集。但是,如果您更喜欢 Python 的多功能性和简单性作为后端,并且希望在前端也利用它的功能,该怎么办?ReactPy 是一个 Python 库,它将熟悉的 ReactJS 语法和灵活性带入了 P…...

安全攻防基础以及各种漏洞库

安全攻防基础以及各种漏洞库 信息搜集企业信息搜集1. 企业架构2. ICP备案查询&#xff0c;确定目标子域名3. 员工信息&#xff08;搜集账号信息、钓鱼攻击&#xff09;4. 社交渠道 域名信息搜集IP搜集信息泄露移动端搜集打点进内网命令和控制&#xff08;持续控制&#xff09;穿…...

护眼灯值不值得买?开学给孩子买什么样的护眼台灯

如果不想家里的孩子年纪小小的就戴着眼镜&#xff0c;从小就容易近视&#xff0c;那么护眼灯的选择就非常重要了&#xff0c;但是市场上那么多品类&#xff0c;价格也参差不齐&#xff0c;到底怎么选呢&#xff1f;大家一定要看完本期内容。为大家推荐五款热门的护眼台灯 一、…...

windows安装Scala

Windows安装Scala 下载地址&#xff1a;https://downloads.lightbend.com/scala/2.11.11/scala-2.11.11.zip 解压完成之后 配置环境变量...

API类型和集成规范指南

在我们的常见应用中&#xff0c;往往包含着大量服务于各种数据交换的API类型、以及各种常见的API架构与协议。下面&#xff0c;我将从集成的角度和您讨论&#xff0c;在准备将多个服务相互集成时&#xff0c;使用不同类型、架构和协议的API意味着什么?我们可以使用哪些工具&am…...

[ES]mac安装es、kibana、ik分词器

一、安装es和kibana 1、创建一个网络&#xff0c;网络内的框架(eskibana)互联 docker network create es-net 2、下载es和kibana docker pull elasticsearch:7.12.1 docker pull kibana:7.12.1 3、运行docker命令部署单点eskibana&#xff08;用来操作es&#xff09; doc…...

YOLO目标检测——视觉显著性检测MSRA1000数据集下载分享

MSRA1000数据集是一个常用的视觉显著性检测数据集&#xff0c;它包含了1000张图像和对应的显著性标注。在以下几个应用场景中&#xff0c;MSRA1000数据集可以发挥重要作用&#xff1a;图像编辑和后期处理、图像检索和分类、视觉注意力模型、自动驾驶和智能交通等等 数据集点击下…...

【基于空间纹理的残差网络无监督Pansharpening】

Unsupervised Pansharpening method Using Residual Network with Spatial Texture Attention &#xff08;基于空间纹理的残差网络无监督泛锐化方法&#xff09; 近年来&#xff0c;深度学习已经成为最受欢迎的泛锐化工具之一&#xff0c;许多相关方法已经被研究并反映出良好…...

2023年信息安全管理与评估(赛项)评分标准第三阶段夺旗挑战CTF(网络安全渗透)

全国职业院校技能大赛 高职组 信息安全管理与评估 &#xff08;赛项&#xff09; 评分标准 第三阶段 夺旗挑战CTF&#xff08;网络安全渗透&#xff09; 竞赛项目赛题 本文件为信息安全管理与评估项目竞赛-第三阶段赛题&#xff0c;内容包括&#xff1a;夺旗挑战CTF&#xff08…...

开启智能时代:深度解析智能文档分析技术的前沿与应用

开启智能时代&#xff1a;深度解析智能文档分析技术的前沿与应用 本章主要介绍文档分析技术的理论知识&#xff0c;包括背景介绍、算法分类和对应思路。通过本文学习&#xff0c;你可以掌握&#xff1a;1. 版面分析的分类和典型思想 2. 表格识别的分类和典型思想 3. 信息提取的…...

高级时钟项目

高级时钟项目 笔者来介绍一下一个简单的时钟项目&#xff0c;主要功能就是显示时间 1、背景 2、数码管版本&#xff08;第一版&#xff09; 3、OLED屏幕版本&#xff08;第二版&#xff09; 3.1、Boot 3.2、app 3.3、上位机 界面一&#xff1a;时间天气显示 界面二 &…...

跨境海淘攻略:如何实现自己批量养买家账号海淘

近年来&#xff0c;随着互联网的发展&#xff0c;网购已经成为人们日常生活中不可或缺的一部分。不仅在国内购买商品&#xff0c;在跨境电商行业越来越成熟&#xff0c;很多的消费者开始选择购买国外平台商品&#xff0c;价格相比国内专柜来说会更为优惠。因此&#xff0c;海淘…...

【lua】在微软 windows 系统上安装 lua

https://sourceforge.net/projects/luabinaries...

系统学习Linux-PXE无人值守装机(附改密)

目录 pxe实现系统自动安装pxe工作原理 大致的工作过程如下&#xff1a; PXE的组件&#xff1a; 一、配置vsftpd 二、配置tftp 三、准备pxelinx.0文件、引导文件、内核文件 四、配置dhcp 配置ip 配置dhcp 五、创建default文件 六、新建测试主机用来测试装机效果 七、…...