mybatis 查询数据库如何关闭缓存,让每次都走数据库

~涛 2021-02-28 11:00:47

mybatis 版本:3.2.7/3.2.8
刚开始登录查询时是走的数据库,但是到后面,返回的数据全是之前的查询数据,查资料说把缓存关闭,但是没效果。
还有一个线程是专门在定时查询数据库中数据的,也出现类似情况,但是每次获取新的sqlsession查询数据可以获取数据库的数据,如果用一个sqlsession则不会走数据库,全是缓存的数据。
------------------------------------------
mapper上加注解没用
@Options(flushCache = true )
List<User> selectByExample(UserExample example);


xml文件加 flushCache="true" 也没用
<select id="selectByExample" resultMap="BaseResultMap" flushCache="true" parameterType="com.coopll.springmvc.pojo.UserExample" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from user
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
...全文
3203 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
白开水233 2021-03-12
  • 打赏
  • 举报
回复
有帮助到你的话记得结贴给分哦
白开水233 2021-03-12
  • 打赏
  • 举报
回复 1
你可以配置每次查询之后清楚一级缓存达到关闭一级缓存的效果,同时关闭二级缓存。在sqlMapConfig.xml加如下配置, <settings> <setting name="cacheEnabled" value="false" /> <setting name="localCacheScope" value="STATEMENT" /> </settings>
~涛 2021-03-05
  • 打赏
  • 举报
回复
引用 12 楼 hbhbhbhbhb1021 的回复:
用什么工具逆向生成的clear方法啊,能帮忙贴一下吗?想看看里面做了啥 flushCache="true"这个参数我刚试了下,是好用的啊,测试环境是springboot +事务的情况下,单boot 不走这个缓存
Mybatis 的generatorSqlmapCustom工具。springboot 没学过不知清楚,
~涛 2021-03-05
  • 打赏
  • 举报
回复
引用 20 楼 老王就是我 的回复:
一般查询不是都new一个新的example的吗?为什么要复用example对象?
开发经验不足,谢谢指导,又学会了一招。
老王就是我 2021-03-05
  • 打赏
  • 举报
回复
一般查询不是都new一个新的example的吗?为什么要复用example对象?
hbhbhbhbhb1021 2021-03-05
  • 打赏
  • 举报
回复
没关系的,反正最近也没啥事情,一起上来学习下,你再看看上面那个回复 这个参数是有用的flushCache="true",看有没有走一级缓存,不能看结果,把日志调成Debug级别,里面会有sql语句。正常情况下每一次调用都会有一句sql打印出来。如果连续调了两次,只打了一句sql说明走了缓存。测试的时候别用反向生成的selectByExample这个方法,用selectByPrimaryKey这个简单点。这个反向工具会生成好多额外的东西。
~涛 2021-03-05
  • 打赏
  • 举报
回复
引用 15 楼 luj_1768 的回复:
数据库都是这样服务的呀:第一次查询使用数据,后面的查询使用缓存。你的需求好像没有什么办法解决,可否讲解一下你的需求背后的目的?数据库都是干活用的,对于没有实际意义的要求,通常会不予理睬。
还是自己缺乏底层的了解,才会出现这个问题。主要是自己写的代码,没有达到预期的目的,也不知问题出在哪,总以为是缓存的问题。
~涛 2021-03-05
  • 打赏
  • 举报
回复
引用 14 楼 hbhbhbhbhb1021 的回复:
兄弟,我就觉得奇怪,这个问题貌似不是一级缓存引起的。我用了那个反向工程工具。这个工具会把查询条件打成一个列表,在mybatis动态去处理。

<sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
生成的clear方法只是将查询条件的list调用了jdk底层的clear方法,没有涉及到sqlsession。
public void clear() {
        oredCriteria.clear();  //这里是查询条件List的clear()
        orderByClause = null;
        distinct = false;
    }
我用了你的代码做了测试,如果不去调用clear方法,连续两笔不同的入参确实会出问题,但日志中的sql是不一样的,而不是没有第二条的sql日志 问题出在那个or()上面,查询条件这个列表oredCriteria会存在上一笔的查询条件,并且是或者的关系,也就是会多查出来,最后又通过get(0)列表只取一笔,导致总是查询出列表中的第一个。
2021-03-05 12:46:05.468 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : ==>  Preparing: select id, name from user WHERE ( id = ? )
2021-03-05 12:46:05.488 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : ==> Parameters: 1(Long)
2021-03-05 12:46:05.505 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : <==      Total: 1
[org.outerwaterfire.mybatis_test.po.User@21e9cb2e]
2021-03-05 12:52:40.804 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : ==>  Preparing: select id, name from user WHERE ( id = ? ) or( id = ? )
2021-03-05 12:52:40.804 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : ==> Parameters: 1(Long), 2(Long)
2021-03-05 12:52:40.900 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : <==      Total: 2
谢谢大佬的这么详细解读:由于这是自己自学以来自己第一个写的作品,缺乏底层的了解,所以才出现了这个问题。 后来测试发现 or() 方法其实是创建了一个Criteria ,这才想起来之前 Hibernate 中使用 Criteria 查询时需要清除上一次的查询条件。 Criteria criteria = userExample.or(); 至于之前使用 sqlsession 直接查数据库的时候,无论是否使用 flushCache="true" 查询结果不变的情况,现在也没模拟出来,也不知自己曾经哪里出错了。
luj_1768 2021-03-05
  • 打赏
  • 举报
回复
数据库都是这样服务的呀:第一次查询使用数据,后面的查询使用缓存。你的需求好像没有什么办法解决,可否讲解一下你的需求背后的目的?数据库都是干活用的,对于没有实际意义的要求,通常会不予理睬。
hbhbhbhbhb1021 2021-03-05
  • 打赏
  • 举报
回复
兄弟,我就觉得奇怪,这个问题貌似不是一级缓存引起的。我用了那个反向工程工具。这个工具会把查询条件打成一个列表,在mybatis动态去处理。

<sql id="Example_Where_Clause" >
    <where >
      <foreach collection="oredCriteria" item="criteria" separator="or" >
        <if test="criteria.valid" >
          <trim prefix="(" suffix=")" prefixOverrides="and" >
            <foreach collection="criteria.criteria" item="criterion" >
              <choose >
                <when test="criterion.noValue" >
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue" >
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue" >
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue" >
                  and ${criterion.condition}
                  <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
生成的clear方法只是将查询条件的list调用了jdk底层的clear方法,没有涉及到sqlsession。
public void clear() {
        oredCriteria.clear();  //这里是查询条件List的clear()
        orderByClause = null;
        distinct = false;
    }
我用了你的代码做了测试,如果不去调用clear方法,连续两笔不同的入参确实会出问题,但日志中的sql是不一样的,而不是没有第二条的sql日志 问题出在那个or()上面,查询条件这个列表oredCriteria会存在上一笔的查询条件,并且是或者的关系,也就是会多查出来,最后又通过get(0)列表只取一笔,导致总是查询出列表中的第一个。
2021-03-05 12:46:05.468 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : ==>  Preparing: select id, name from user WHERE ( id = ? )
2021-03-05 12:46:05.488 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : ==> Parameters: 1(Long)
2021-03-05 12:46:05.505 DEBUG 28636 --- [nio-8080-exec-1] o.o.m.mapper.UserMapper.selectByExample  : <==      Total: 1
[org.outerwaterfire.mybatis_test.po.User@21e9cb2e]
2021-03-05 12:52:40.804 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : ==>  Preparing: select id, name from user WHERE ( id = ? ) or( id = ? )
2021-03-05 12:52:40.804 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : ==> Parameters: 1(Long), 2(Long)
2021-03-05 12:52:40.900 DEBUG 28636 --- [nio-8080-exec-2] o.o.m.mapper.UserMapper.selectByExample  : <==      Total: 2
~涛 2021-03-04
  • 打赏
  • 举报
回复
引用 9 楼 xls丶 的回复:
clear方法哪里来的 [quote=引用 7 楼 ~涛 的回复:] 问题解决了,查询之前清除一下***Example的查询条件。这个错误现在看来有点低级!
[/quote] Mybatis 逆向工厂生成的代码中的。
~涛 2021-03-04
  • 打赏
  • 举报
回复
Mybatis 逆向工厂生成的代码中的。
hbhbhbhbhb1021 2021-03-04
  • 打赏
  • 举报
回复
用什么工具逆向生成的clear方法啊,能帮忙贴一下吗?想看看里面做了啥 flushCache="true"这个参数我刚试了下,是好用的啊,测试环境是springboot +事务的情况下,单boot 不走这个缓存
xls丶 2021-03-02
  • 打赏
  • 举报
回复
clear方法哪里来的
引用 7 楼 ~涛 的回复:
问题解决了,查询之前清除一下***Example的查询条件。这个错误现在看来有点低级!
~涛 2021-03-02
  • 打赏
  • 举报
回复
引用 6 楼 KeepSayingNo 的回复:
一级缓存是必走的吧,能关闭的只能是二级缓存,楼主你为什么要这样干了,那就干脆不用mybatis了,直接JDBC搞
大老就不要挖苦毕竟刚初出茅庐的小弟了。
~涛 2021-03-02
  • 打赏
  • 举报
回复
问题解决了,查询之前清除一下***Example的查询条件。这个错误现在看来有点低级!
KeepSayingNo 2021-03-02
  • 打赏
  • 举报
回复
一级缓存是必走的吧,能关闭的只能是二级缓存,楼主你为什么要这样干了,那就干脆不用mybatis了,直接JDBC搞
~涛 2021-03-01
  • 打赏
  • 举报
回复
引用 1 楼 HuangHe201691 的回复:
有个最下下策的方法就是每次改变执行的SQL,缓存的机制是每次先检查执行是否相同,如果相同则在缓存中获取;还有就是可以试试释放缓存,每次执行完成后释放
可能你说的是这个吧!
~涛 2021-03-01
  • 打赏
  • 举报
回复
引用 2 楼 nayi_224 的回复:
finduserbyuser里面的代码发出来
这是findUserByUser的代码
~涛 2021-03-01
  • 打赏
  • 举报
回复
这是service层的代码和UserMapper.xml的代码
加载更多回复(2)

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧