在随机获取数据库记录时。我们的sql语句一般都是确定的。因此对于使用了Mybatis的项目中来说,mysql的随机数据会被Mybatis缓存下来,因此导致每次Dao获取的数据都是一样的,也就失去了随机的意义。这里需要配合mapper文件里的以下标签使用,刷新(清空)缓存。
mapper标签:flushCache="true" 举例: <select id="getRandomVideo" resultType="com.XXX.XXX.beans.XXXVideo" flushCache="true"> SELECT * FROM video ORDER BY RAND() LIMIT 1 </select>
获取随机行数的sql语句:
SELECT * FROM video ORDER BY RAND() LIMIT 1
LIMIT 1 :代表返回一条随机结果。想获取X条随机记录,那么改为 LIMIT X 即可。
ORDER BY RAND() :代表随机排序
Mybatis分两级缓存。
在此条select标签中使用flushCache,表示每次此查询执行时,都会清空缓存并且去数据库运行此条语句。这样我们的随机sql 语句才会在数据库被执行。
还有一相关Mybatis标签是:
useCache="false"
代表不使用二级缓存。true的时候表示使用二级缓存。
注意:
一级缓存是sqlsession级别的缓存。在Mybatis中无法关闭,因此当调用随机获取记录的sql语句时,如果一直是同一个sql会话,而且sql中没有添加随机数时(不更改mapper配置文件的情景下,防止Mybatis缓存sql执行结果的方式,下一段介绍),那么还会返回相同的数据。因为在标签里配置 useCache="false" 只是禁言二级缓存,使用flushCache="true"才是有效的
补充:
添加随机数的方式避免Mybatis缓存数据
此方法不用修改Mybatis相关配置,比如在上面获取随机行数的sql语句中添加一些不影响随机的参数:
SELECT * FROM video WHERE #{random}=#{random} ORDER BY RAND() LIMIT 1
当然在调用方法中要添加对应的参数。
比如之前的Dao或Mapper类中,方法是如下无参的:
getRandomVideo();
那么现在需要变为:getRandomVideo(String random);
在制作随机参数的时候也有需要注意的地方,比如调用此方法时需要注意不要使用时间戳的方式获取随机数,如下:
当service层调用 getRandomVideo(String random); 方法时
getRandomVideo(new Date().toString());是不行的。
在这里博主是使用生成UUID的方式来获取随机数:
getRandomVideo(new UUID().toString());
最后成功的获得了随机记录。
大家还有更好的方法欢迎提出来。