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

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 防御笔记第四天(持续更新)
  • 最优化(10):牛顿类、拟牛顿类算法
  • 百日筑基第十七天-消息队列入门
  • Linux驱动开发-03字符设备驱动框架搭建
  • 阿里云通义千问开源两款语音基座模型分别是SenseVoice和CosyVoice
  • 在Spring Boot项目中集成单点登录解决方案
  • vue 搭建 pinia
  • 14.爬虫---Selenium 经典动态渲染工具的使用
  • MATLAB基础应用精讲-【数模应用】RFM模型
  • 若依vue集成electron实现打包exe应用程序
  • 自建搜索引擎-基于美丽云
  • 法律智能的新纪元:Transformer模型在智能法律咨询的突破性应用
  • 苹果笔记本电脑能玩哪些游戏 苹果电脑可以玩的单机游戏推荐
  • Hospital Management System v4.0 SQL 注入漏洞(CVE-2022-24263)
  • 使用ssh服务器管理远程主机
  • @jsonView过滤属性
  • Angular6错误 Service: No provider for Renderer2
  • E-HPC支持多队列管理和自动伸缩
  • Java方法详解
  • Java深入 - 深入理解Java集合
  • Mocha测试初探
  • Python打包系统简单入门
  • Rancher-k8s加速安装文档
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 深入 Nginx 之配置篇
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 微服务核心架构梳理
  • 学习Vue.js的五个小例子
  • 积累各种好的链接
  • 昨天1024程序员节,我故意写了个死循环~
  • ​io --- 处理流的核心工具​
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ​学习一下,什么是预包装食品?​
  • ​一些不规范的GTID使用场景
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #LLM入门|Prompt#3.3_存储_Memory
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (第一天)包装对象、作用域、创建对象
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (论文阅读40-45)图像描述1
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (算法)前K大的和
  • (转)iOS字体
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET Framework .NET Core与 .NET 的区别
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .NET正则基础之——正则委托
  • @RestControllerAdvice异常统一处理类失效原因
  • @selector(..)警告提示