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

embedded/2024/10/11 9:27:25/

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_62">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语句嘴鸥一个后缀的功能,对应的sqlupdate 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.ppmy.cn/embedded/59023.html

相关文章

Java多态练习(2024.7.10)

动物类 package KeepPets20240710;public class Animal {private String color;private int age;public Animal(){}public Animal(String color, int age) {this.color color;this.age age;}public String getColor() {return color;}public void setColor(String color) {t…

求职笔记day3

运动量3.5万步。五园连通未完成。 未考试&#xff0c;朋友建议按代码随想录的框架先刷对应的知识点。 代码随想录 (programmercarl.com) 704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 单词倒排_牛客题霸_牛客网 (nowcoder.com)

线性代数|机器学习-P22逐步最小化一个函数

文章目录 1. 概述2. 泰勒公式3. 雅可比矩阵4. 经典牛顿法4.1 经典牛顿法理论4.2 牛顿迭代法解求方程根4.3 牛顿迭代法解求方程根 Python 5. 梯度下降和经典牛顿法5.1 线搜索方法5.2 经典牛顿法 6. 凸优化问题6.1 约束问题6.1 凸集组合 Mit麻省理工教授视频如下&#xff1a;逐步…

深入解析大数据核心概念:数据平台、数据中台、数据湖与数据仓库的异同与应用

大数据领域内的诸多概念常常让人困惑&#xff0c;其中数据平台、数据中台、数据湖和数据仓库是最为关键的几个。 1. 数据平台 定义&#xff1a; 数据平台是一个综合性的技术框架&#xff0c;旨在支持整个数据生命周期的管理和使用。它包含数据采集、存储、处理、分析和可视化…

Flink+Paimon在阿里云大数据云原生运维数仓的实践

1. 背景 随着大数据产品云原生化的推进&#xff0c;云原生集群的规模和数量都在增加&#xff0c;云原生集群的运维难度也在不断增加&#xff0c;云原生集群的资源审计、资源拓扑、资源趋势的需要就比较迫切。云原生集群的资源审计主要是 node 资源、pod 资源&#xff0c;如当前…

从零开始做题:迷失幻境

题目 给出一个磁盘虚拟文件 解题 下载附件然后解压,得到一个虚拟机文件,使用的是DiskGenius磁盘工具打开 这样他里面的文件就全部展现出来了 我们可以看到有很多图片&#xff0c;和一个txt文档&#xff0c;还有几个没有后缀的文件&#xff0c;图片这么多&#xff0c;所以我…

3D感知视觉表示与模型分析:深入探究视觉基础模型的三维意识

在深度学习与大规模预训练的推动下&#xff0c;视觉基础模型展现出了令人印象深刻的泛化能力。这些模型不仅能够对任意图像进行分类、分割和生成&#xff0c;而且它们的中间表示对于其他视觉任务&#xff0c;如检测和分割&#xff0c;同样具有强大的零样本能力。然而&#xff0…

面试题之HashMap

目录 Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)? HashMap的Put⽅法 HashMap的扩容机制原理 1.7版本 1.8版本 HashMap扩容为什么是扩为两倍? Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)? 1. 1.7中底层是数组链表&#xff0c;1.8中底层是数组链表红⿊树&#xf…