欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > Mybatis之动态sql、缓存、分页、配置数据源

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

2024/10/24 13:21:01 来源:https://blog.csdn.net/qq_70314704/article/details/140330573  浏览:    关键词: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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com