Mybatis之动态sql、缓存、分页、配置数据源

SQL动态查询

if标签

当传递某个DTO时,需要根据某个属性是否存在而动态增加条件时,就可以使用if标签

<select id="getUser" resultType="user">select id, name, age, sex from user where 1=1<if test="userDto.name != null and userDto.name !=''">AND name = #{userDto.name}</if><if test="userDto.age != null">AND age = #{userDto.age}</if>
</select>

如果test中的条件判断通过,则会将if标签中的内容拼接到前面的sql语句中,否则就不做处理

[!warning]

if标签中的test检测语句和if标签中的sql语句中不能出现<符号表示小于

因为<符号在xml文件中代表的是标签的开始

如果是test中,可以使用!进行反转; 如果在if标签中的sql语句,需要使用CDATA标签进行包裹,比如

<if test="userDto.age != null and !userDto.age >20"><![CDATA[AND age <= #{userDto.age}]]></if>

where标签

类似于上一段代码,书写 where 1=1 这样的语句时不规范的,所以就可以使用where标签代替

<select id="getUser" resultType="user">select id, name, age, sex from user<where><if test="userDto.name != null and userDto.name !=''">AND name = #{userDto.name}</if><if test="userDto.age != null">AND age = #{userDto.age}</if></where>
</select>

如果if中的条件成立,则sql语句将会是select id, name, age, sex from user where name =? and age = ?

如果都不成立,则时期类语句是select id, name, age, sex from user

使用where标签时,会自动将第一个条件的 AND 或者 OR 替换掉

sql标签

如果在多个查询中存在校相同的sql片段,则可以使用sql标签抽取出来

<sql id="columns" >id, name, age, sex
</sql><select id="getUser" resultType="user">select<include refid="columns"/>from user
</select>

在需要使用要这个sql片段的地方使用inclued标签进行引用

set标签

set标签使用在更新操作中,对应sql语句中的set

<update id="updateUser">update user<set><if test="userDto.name != null and userDto.name !=''">name = #{userDto.name},</if><if test="userDto.age != null">age = #{userDto.age},</if></set>
</update>

set标签还具有省略sql语句嘴鸥一个后缀的功能,对应的sql为 update user set name = ?, age = ?

trim标签

Mybatis提供了trim标签来代替where和set标签

<select id="getUser" resultType="user">select id, name, age, sex from user<trim prefix="where" prefixOverrides="AND"><if test="userDto.name != null and userDto.name !=''">AND name = #{userDto.name}</if><if test="userDto.age != null">AND age = #{userDto.age}</if></trim>
</select>

trim 标签有四个属性 prefix(前缀) prefixOverrides(被替代的前缀) suffix(后缀) suffixOverrides(被替代的后缀)

比如上面的sql语句, 对应的是 select id, name, age, sex from user where name =? and age = ?

被替代的前缀是 AND,替换为了前缀 where,同理还可以用在set标签中替换最后一个逗号

foreach标签

循环标签通常用于插入、删除、更新和查询操作

<insert id="saveUser">insert into user(name, age)values<foreach collection="userList" item="user" separator=",">(#{user.name}, #{user.age})</foreach>
</insert>
<!------------------------------------------------------------------------------------>
<select id="getUsers" resultType="user">select * from user where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</select>

foreach提供了六个标签,分别是

  • collection(传入的集合/数组)
  • itme(集合/数组中的元素)
  • separator(元素之间的分割符)
  • open(开始符号)
  • close(结束符号)
  • index(元素下标,不经常使用)

第一句对应的sql是 insert into user(name, age) values(?,?),(?,?)…

第二局对应的sql是 select* from user where id in (?,?,?,?…)

Mybatis缓存

缓存就是存储在内存中的临时数据,将用户经常查询的数据放在缓存(内存)中,用户再次查询数据的时候就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,能够提高查询效率,解决了高并发系统的性能问题

优势:减少和数据库的交互次数,减少系统开销,提高系统效率

使用场景:经常查询并且不经常改变的数据

Mybatis提供了两级缓存:一级缓存和二级缓存

  • 一级缓存是Sqlsession级别的缓存(本地缓存),默认开启,同一个SqlSession执行同构查询的时候,结果放入一级缓存
  • 二级缓存是SqlSessionFactory级别的缓存,需要手动开启,同一个SqlSessionFactory构建的SqlSession执行同构查询,如果SqlSession关闭,查询结果保存在二级缓存中

全局缓存配置

<!-- config.xml -->
<settings><!-- 开启二级缓存 --><setting name="cacheEnabled" value="true"/>
</settings>

Mapper中的配置

readOnly:只读

flushInterval:刷新时间,单位为毫秒

size:缓存的数据条目

eviction:缓存淘汰策略

​ LRU:最近最少使用回收,移除最长时间不被使用

​ FIFO:先进先出,按照缓存进入的顺序进行移除

​ SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象

​ WEAK:弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象

<cache flushInterval="300000" readOnly="true" size="10000" eviction="LRU"/>

标签中的设置

设置属性useCache="true"

<select id="getUsersInclude" resultMap="map2" useCache="true">
。。。。。
</select>

当开启二级缓存之后,在控制台可以看到Cache Hit Ratio [cn.cnmd.mapper.UserMapper]: 0.5,代表缓存命中率
缓存命中率 = 缓存中查询数 总查询数 缓存命中率 = \frac{缓存中查询数}{总查询数} 缓存命中率=总查询数缓存中查询数

分页插件Page-Helper

maven配置

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.2.1</version>
</dependency>

插件配置

<plugins><plugin interceptor="com.github.pagehelper.PageHelper"/>
</plugins>

代码

SqlSession session = MybatisUtil.getSession();PersonMapper mapper = session.getMapper(PersonMapper.class);PageHelper.startPage(1, 5);//这一步必须在调用方法之前进行List<Person> person = mapper.getPerson();PageInfo<Person> pageInfo = new PageInfo<>(person);//查询出的数据必须封装在PageInfo对象中System.out.println("总条数:" + pageInfo.getTotal());
System.out.println("总页数:" + pageInfo.getPages());pageInfo.getList().forEach(System.out::println);// 当前页数据展示

结果

Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1f59a598]
==>  Preparing: SELECT count(0) FROM rbac.simple_table
==> Parameters: 
<==    Columns: count(0)
<==        Row: 32
<==      Total: 1
==>  Preparing: SELECT * from rbac.simple_table LIMIT ?
==> Parameters: 5(Integer)
<==    Columns: id, name, age, gender
<==        Row: 1, 张三, 25, 男
<==        Row: 2, 李四, 30, 女
<==        Row: 3, 王五, 22, 男
<==        Row: 4, 赵六, 28, 女
<==        Row: 5, 孙七, 35, 男
<==      Total: 5
总条数:32
总页数:7
Person(id=1, name=张三, age=25, gender=男)
Person(id=2, name=李四, age=30, gender=女)
Person(id=3, name=王五, age=22, gender=男)
Person(id=4, name=赵六, age=28, gender=女)
Person(id=5, name=孙七, age=35, gender=男)

配置数据源 Druid

maven配置

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.20</version>
</dependency>

创建 DruidDataSourceFactory, 并继承 PooledDataSourceFactory,并替换数据源

public class DruidDataSourceFactory extends PooledDataSourceFactory {public DruidDataSourceFactory() {this.dataSource = new DruidDataSource();//替换数据源}
}
<dataSource type="cn.cnmd.dataSource.DruidDataSourceFactory"><!--1.3配置连接池需要的参数--><!--修改为druid数据源时,一定要把driver修改为 driverClassName才能生效--><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/>
</dataSource>

控制台出现字样说明配置成功

七月 10, 2024 5:43:47 下午 com.alibaba.druid.pool.DruidDataSource info

信息: {dataSource-1} inited
Row: 3, 王五, 22, 男
<== Row: 4, 赵六, 28, 女
<== Row: 5, 孙七, 35, 男
<== Total: 5
总条数:32
总页数:7
Person(id=1, name=张三, age=25, gender=男)
Person(id=2, name=李四, age=30, gender=女)
Person(id=3, name=王五, age=22, gender=男)
Person(id=4, name=赵六, age=28, gender=女)
Person(id=5, name=孙七, age=35, gender=男)


# 配置数据源 Druid### maven配置```xml
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.20</version>
</dependency>

创建 DruidDataSourceFactory, 并继承 PooledDataSourceFactory,并替换数据源

public class DruidDataSourceFactory extends PooledDataSourceFactory {public DruidDataSourceFactory() {this.dataSource = new DruidDataSource();//替换数据源}
}
<dataSource type="cn.cnmd.dataSource.DruidDataSourceFactory"><!--1.3配置连接池需要的参数--><!--修改为druid数据源时,一定要把driver修改为 driverClassName才能生效--><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/>
</dataSource>

控制台出现字样说明配置成功

七月 10, 2024 5:43:47 下午 com.alibaba.druid.pool.DruidDataSource info

信息: {dataSource-1} inited

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

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

相关文章

EventBus原理分析

EventBus 是一个流行的事件发布/订阅框架&#xff0c;主要用于简化 Android 应用中不同组件之间的通信。它的设计基于观察者模式&#xff0c;可以有效地减少组件间的耦合性&#xff0c;使得代码更加模块化和可维护。 下面是 EventBus 的实现原理&#xff0c;结合其源码进行说明…

快到不可思议!Internet Download Manager下载器,让你的网速飞起来!

&#x1f31f; 快到不可思议&#xff01;Internet Download Manager下载器&#xff0c;让你的网速飞起来&#xff01;&#x1f680; 嗨喽&#xff0c;各位csdn的朋友们&#xff01;&#x1f44b;今天我要跟大家分享一个我超爱的下载神器——Internet Download Manager&#xff…

MySQL相关函数

SQL函数 聚合函数 定义&#xff1a;聚合函数作用与一组数据&#xff0c;并对一组数据返回一个值。 常用&#xff1a;AVG()、SUM()、MAX()、MIN()、COUNT()。 说明&#xff1a;聚合函数不能嵌套使用。 字符串函数 MYSQL中常用的字符串函数&#xff1a; 函数名作用concat(s1,s…

springboot+vue项目实战2024第三集修改用户信息

1.获取用户信息 GetMapping("/userInfo")// RequestHeader(name "Authorization") String tokenpublic Result<User> userInfo(){// Map<String, Object> map JwtUtil.parseToken(token);Map<String,Object> map ThreadLocalUti…

基于uni-app与图鸟UI的知识付费小程序模板

一、项目概述 在知识经济蓬勃发展的背景下&#xff0c;移动互联网成为知识传播与消费的重要渠道。本项目旨在利用前沿的前端技术栈——uni-app及高效UI框架图鸟UI&#xff0c;打造一款集多功能于一体的、面向广大求知者的知识付费平台移动端模板。该模板旨在简化开发流程&…

Java:分批查询

前言 最近遇到一个场景问题&#xff0c;就是基于SQL server数据库的规范&#xff0c;查询条件in如果个数超过2100个就会报错。由于是ORM映射框架采用的MybatisPlus 起初我想到的是基于 MybatisPlus 的 参数分割&#xff0c;测试还是不行&#xff0c;于是就直接基于 mybatis xm…

自定义业务非受检异常

【受检和非受检异常】 受检异常&#xff1a;当你需要强制调用者对异常异常进行处理时&#xff0c;抛出该类型异常。往往适用于开发通用的底层接口、或者调用第三方出现异常时。 非受检异常&#xff1a;当你不需要调用者关心时&#xff0c;抛出该类型异常。往往适用于普通的业务…

arm64架构下源码编译安装kafka —— 筑梦之路

一般来说&#xff0c;直接使用官方提供的二进制文件即可&#xff0c;没有必要使用源码编译安装的方式&#xff0c;而对于有特殊用途的&#xff0c;选择源码编译安装无疑是更好地选择。比如修改源码实现想要的功能&#xff0c;mirrormaker2保持topic名称不变。 git clone https…

缓存击穿、缓存穿透、缓存雪崩以及应对措施

1.缓存击穿 1.1概念 是指当某一key的缓存时间过期时大量并发量的请求同时访问此key&#xff0c;瞬间击穿服务器的直接访问数据库&#xff0c;让数据库处于负载的情况。 1.2解决措施 1.2.1异步定时更新 在缓存处理上&#xff0c;某一个热点数据的过期时间为一小时&#xff…

线性回归笔记

https://blog.51cto.com/u_16213589/7682076 残差图 多元回归-最小二乘法-残差分析笔记 一.多元线性回归模型的假设 我们需要进行以下六个假设&#xff0c;这些假设是经典的多元线性回归模型有效的前提&#xff1a; 1、因变量Y和自变量X1&#xff0c;X2&#xff0c;…&#…

Vue3.js“非原始值”响应式实现基本原理笔记(三)

如果您觉得这篇文章有帮助的话&#xff01;给个点赞和评论支持下吧&#xff0c;感谢~ 作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者/csdn百万访问前端博主/B站千粉前端up主 此篇文章是博主于2022年学习《Vue.js设计与实现》时的笔记整理而来 书籍&a…

BEV 之 LSS概要

1、 Lift 显示估计图像下采样&#xff08;16倍&#xff09;后的特征点深度&#xff0c;将2D图像提升到3D空间&#xff0c;得到图像特征的视锥&#xff08;点云&#xff09;。 根据图像和深度均分得到3D视锥索引 下采样16倍&#xff0c;得到特征图大小为 H x W, 每个特征点深…

机器视觉理论入门

文章目录 前言一、马尔视觉理论二、图形与图像三、图像基础名词总结 前言 Marr的视觉计算理论立足于计算机科学&#xff0c;系统地概括了心理物理学、神经生理学、临床神经病理学等方面已取得的所有重要成果&#xff0c;是迄今为止最为系统的视觉理论。Marr 的视觉计算理论虽然…

LiteOS GPIO操作

在源码工程中&#xff0c; 华为海思在hi_io.h头文件里已定义好表示每个IO口的宏定义&#xff0c;如&#xff1a; typedef enum {HI_IO_NAME_GPIO_0, /**< GPIO0 */HI_IO_NAME_GPIO_1, /**< GPIO1 */HI_IO_NAME_GPIO_2, /**< GPIO2 */... } 并且在此头文…

【论文速读】《面向深度学习的联合消息传递与自编码器》

这篇文章来自华为的渥太华无线先进系统能力中心和无线技术实验室&#xff0c;作者中有大名鼎鼎的童文。 一、自编码架构的全局收发机面临的主要问题 文章对我比较有启发的地方&#xff0c;是提到自编码架构的全局收发机面临的主要问题&#xff1a; 问题一&#xff1a;基于随…

洛杉矶裸机云大宽带服务器的特性和优势

洛杉矶裸机云大宽带服务器是结合了物理服务器性能和云服务灵活性的高性能计算服务&#xff0c;为用户提供高效、安全的计算和存储能力。在了解如何使用洛杉矶裸机云大宽带服务器之前&#xff0c;需要了解其基本特性和优势。以下是对洛杉矶裸机云大宽带服务器的具体分析&#xf…

使用lv虚拟卷扩展磁盘

使用centos演示。 首先创建centos虚拟机。链接&#xff1a;VMWARE安装Centos8,并且使用ssh连接虚拟机-CSDN博客 1. 增加磁盘。 选中要扩容的虚拟机&#xff0c;右键选择设置&#xff0c;然后点击磁盘&#xff0c;选择添加。 这里选择NVM的磁盘。选择这种磁盘是为了保持与之前…

有Daemon字眼的守护线程,和没有的差异是什么?怎么创建有daemon字眼的线程?

在编程中&#xff0c;尤其是在Java等支持多线程的编程语言中&#xff0c;守护线程&#xff08;Daemon Thread&#xff09;与普通线程&#xff08;Non-Daemon Thread&#xff09;之间存在一些关键差异。这些差异主要体现在它们对程序终止行为的影响上。 主要差异 程序终止行为…

SpringBoot新手快速入门系列教程:前述

我自己是一个SpringBoot新手&#xff0c;花了一天时间学了SpringBoot。大家不要惊讶&#xff0c;前提是我自己已经有了10几年的编程经验精通多门语言&#xff0c;并且在人间最强兵器Chat某T的AI助手帮助下&#xff0c;才能创造一天快速学会一个框架的神话。 当然中间遇到了很多…

笔试算法刷题

猿辅导2021校园招聘笔试&#xff08;算法一&#xff09; 牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推&#xff0c;求职就业一站解决_牛客网 (nowcoder.com) 第一眼看到这个题想到的是蓝桥杯飞机降落&#xff0c;贪心题。但是这样算的是最大不相交区间数量&#xff0…