分开的两个程序使用共同的mysql,一端更新了表,另一端怎么及时更新缓存,使用mybatis
2016-01-26 17:49
726 查看
目前项目中由于业务系统和管理系统是分开的,管理端只负责对数据库表的CRUD,而业务系统也需要交互db。现在就存在一个问题,在管理端上改了某个表的值,业务端是无从得知的。因为业务端一直用相同的语句查询db,mybatis的二级缓存会缓存这些数据,不会真正发sql去查询真实数据。所以就需要管理端在修改表的时候,通知一下业务端是更新二级缓存,这样才能及时使用新值。
起初在想mybatis的sqlSessionFactory有没有提供可以更新全局二级缓存的接口,发现真的没有。那就手动更新嘛~ ~ ~。方法是:
首先我们的mapper是一个*Mapper.java加上*Mapper.xml,在.java中定义接口:
*Mapper.xml:
<cache />是一个全局的配置,但在每个子元素是可以配置自身。
(1)当为select语句时:
flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
useCache默认为true,表示会将本条语句的结果进行二级缓存。
(2)当为insert、update、delete语句时:
flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。
useCache属性在该情况下没有。
上面的信息我是从MyBatis官方文档中找到的,会发现当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的。
我们写一个refleshCache方法,在xml中用<update />,但是不用写一条真正的update语句,用个select 1就行了,因为貌似mybatis只认标签的类型,而不是具体是什么语句,这里发现是<update flushCache="true"/>,就会更新这个mapper中所有<select>使用的二级缓存了。
这里我们提供一个http接口给管理端用,他们每次更新db,就调一次接口,我们就知道要更新。如果说,mapper.xml有很多,那是不是要在作业类里调用每个mapper的refleshCache() ?不是的。可以利用Reflect。
具体做法是写所有要更新的xml定义起来,比如放在spring配置文件中
由于每个mapper.java都用了注解,所有spring容器可以产生他们的实例。
(下篇准备写一下项目中使用到的线程池机制,使用到了信号量等东西,做系统中统一的池挺不错,大师出品,值得依赖,敬请期待)
起初在想mybatis的sqlSessionFactory有没有提供可以更新全局二级缓存的接口,发现真的没有。那就手动更新嘛~ ~ ~。方法是:
首先我们的mapper是一个*Mapper.java加上*Mapper.xml,在.java中定义接口:
@Repository public interface AppConfMapper { public List<Map> getBizConf(@Param("jobId") long jobId); public void refreshCache(); }
*Mapper.xml:
<mapper namespace="com.szkingdom.kisp.mapper.AppConfMapper"> <!-- 开启二级缓存 --> <cache /> <select id="getBizConf" parameterType="long" resultType="map" useCache="true"> SELECT * FROM kisp_biz_conf t </select> <!-- 刷新缓存 --> <update id="refreshCache" flushCache="true"> SELECT 1; </update> </mapper>
<cache />是一个全局的配置,但在每个子元素是可以配置自身。
(1)当为select语句时:
flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
useCache默认为true,表示会将本条语句的结果进行二级缓存。
(2)当为insert、update、delete语句时:
flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。
useCache属性在该情况下没有。
上面的信息我是从MyBatis官方文档中找到的,会发现当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的。
我们写一个refleshCache方法,在xml中用<update />,但是不用写一条真正的update语句,用个select 1就行了,因为貌似mybatis只认标签的类型,而不是具体是什么语句,这里发现是<update flushCache="true"/>,就会更新这个mapper中所有<select>使用的二级缓存了。
这里我们提供一个http接口给管理端用,他们每次更新db,就调一次接口,我们就知道要更新。如果说,mapper.xml有很多,那是不是要在作业类里调用每个mapper的refleshCache() ?不是的。可以利用Reflect。
具体做法是写所有要更新的xml定义起来,比如放在spring配置文件中
<bean id="flush_mapper_cache_list" class="java.util.ArrayList"> <constructor-arg> <list> <value>appConfMapper</value> <value>exceptionMapper</value> <value>kispCoreBizDataMapper</value> </list> </constructor-arg> </bean>
由于每个mapper.java都用了注解,所有spring容器可以产生他们的实例。
private void flush(String mapperInstanceName) throws Exception { Object instance = BeanHoldFactory.getSpringBean(mapperInstanceName); Method method = instance.getClass().getMethod("refleshCache"); method.invoke(instance); logger.info(mapperInstanceName + "二级缓存刷新成功!"); }利用Method的invode就可以轻松调用方法啦~~
(下篇准备写一下项目中使用到的线程池机制,使用到了信号量等东西,做系统中统一的池挺不错,大师出品,值得依赖,敬请期待)
相关文章推荐
- MySql的desc关键字引发的问题
- mysql用户变量
- mysql 用户自定义变量
- mysql的BIT_COUNT,BIT_COUNT
- MySQL数据导入与导出(自参考)
- mysql查询的小东西
- mysql 常用命令
- [solved]access denied for user 'root'@'localhost' (using password no) ubuntu mysql
- mysql中,与日期相关的函数
- PostgreSQL与MySQL命令的使用比较
- MYSQL 定时任务调用存储过程
- mysql 查表失败
- MySQL的ON DUPLICATE KEY UPDATE 使用
- mysql limit查询优化
- mysql 性能优化
- mysql sql_mode 汇总整理
- Mysql 查看各个表格的数据量大小
- 介绍MySQL Jdbc驱动的rewriteBatchedStatements参数
- 使用JDBC在MySQL数据库中快速批量插入数据
- MySQL5.6:基于GTID的主从复制