mybatis存取blob对象+@Cacheable实现数据缓存
参考文档:
http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/
需求场景:
当前业务通过第三方接口查询一个业务数据,该数据更新频率略低(约2小时),但前端查询的频率不可控。所以,需要实现一个带有数据缓存功能的查询接口。
设计方案:
实时数据由第三方接口获取,ehcache作为一级缓存(数据有效时间60秒),mysql作为二级缓存和数据持久层(数据有效时间2小时)。查询优先级:ehcache>mysql>第三方。其中mysql的数据过期与更新需要自行实现管理。
常规的增删改查在此不表,主要说下之前很少用到的blob对象和@Cacheable。从第三方获取到的对象由于字段较多且结构复杂,所以不想在数据库建表然后再做VO-TABLE的映射。选择偷懒的方式使用blob直接存储整个对象。
mysql中blob字段对应java中byte[],所以对象在存取的时候要手动序列化(反序列化)的过程,这个借用ObjectInputStream、ByteArrayInputStream这些对象即可完成。
VO对象:
public class BusinessInfoVo
{
private int id; private String nu; private byte[] data; private Date updatetime; //...
}
表结构:
CREATE TABLE `shop_expressinfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nu` varchar(255) DEFAULT NULL,
`data` blob,
`updatetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
mapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace="com.lichmama.demo.dao.mapper.ExpressMapper"> <resultMap type="BusinessInfoVo" id="businessInfoMap">
<result property="id" column="id" />
<result property="nu" column="nu" />
<result property="data" column="data" jdbcType="BLOB" />
<result property="updatetime" column="updatetime" />
</resultMap> <select id="select" resultMap="businessInfoMap" parameterType="BusinessInfoVo">
select * from shop_expressinfo where nu = #{nu}
</select> <insert id="insert" parameterType="BusinessInfoVo">
insert into shop_expressinfo(nu, data, updatetime) values(#{nu}, #{data, jdbcType=BLOB}, now())
</insert> <update id="update" parameterType="BusinessInfoVo">
update shop_expressinfo set data = #{data, jdbcType=BLOB}, updatetime = now() where nu = #{nu}
</update> <delete id="delete" parameterType="java.lang.String">
delete from shop_expressinfo where nu = #{nu}
</delete> </mapper>
对象序列化过程:
/**
* 将对象转化为字节数组
* @author lichmama
* @param object
* @return
* @throws IOException
*/
private byte[] objectToBytes(Object object) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
baos.close();
oos.close();
return bytes;
} /**
* 将字节数组转化为对象
* @author lichmama
* @param bytes
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
private <T> T bytesToObject(byte[] bytes) throws IOException, ClassNotFoundException
{
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Object object = ois.readObject();
bais.close();
ois.close();
return (T) object;
}
在业务方法加@Cacheable注解,用于缓存数据到内存中,加速查询。这里我使用ehcache做缓存容器,下面贴出配置。
ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" dynamicConfig="false"> <!-- * maxElementsInMemory - 内存中最大缓存对象数 * eternal - 缓存元素是否永久有效,若配置为true,则其他的缓存生命周期timeout设置均无效
* timeToIdleSeconds - 设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
* timeToLiveSeconds - 设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大。
* overflowToDisk - 配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中。
* maxElementsOnDisk - 磁盘中最大缓存对象数,若是0表示无穷大。 * diskExpiryThreadIntervalSeconds
- 磁盘失效线程运行时间间隔,默认是120秒。 * memoryStoreEvictionPolicy - 当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 --> <!-- 默认配置 -->
<defaultCache maxElementsInMemory="5000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
memoryStoreEvictionPolicy="LRU" overflowToDisk="false" /> <cache
name="businessInfoCache"
maxElementsInMemory="10000"
maxElementsOnDisk="100000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
关于timeToIdleSeconds和timeToLiveSeconds的解释参看:http://blog.csdn.net/vtopqx/article/details/8522333
对应的spring配置:
<!-- ehcache -->
<cache:annotation-driven cache-manager="ehcacheManager"/> <!-- cacheManager工厂类,指定ehcache.xml的位置 -->
<bean id="ehcacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="/WEB-INF/conf/ehcache.xml" />
</bean> <!-- 声明cacheManager -->
<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcacheManagerFactory" />
</bean>
在业务方法中使用如下(在首次查询后,spring会缓存数据并保持60秒):
/**
* 获取订单的物流跟踪信息
* @author lichmama
* @param nu
* @return
*/
@Cacheable(value="businessInfoCache", key="#root.methodName" + "." + "#nu")
public ExpressInfo queryBusinessInfo(String nu)
{
//...
}
*关于@Cacheable中key的说明:
key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,至于默认策略会在后文单独介绍。
自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key。通过该root对象我们可以获取到以下信息。
参考文档:
http://blog.csdn.net/fireofjava/article/details/48913335
http://blog.csdn.net/wjacketcn/article/details/50945887
http://docs.spring.io/spring/docs/3.2.18.RELEASE/spring-framework-reference/htmlsingle/#cache-annotations-cacheable
mybatis存取blob对象+@Cacheable实现数据缓存的更多相关文章
- 利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据
利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据 实现描述:将数据存放在js对象中, 然后放在父页面的document对象中, 在页面刷新的时候将父页面的值取出来, ...
- Statement和PreparedStatement的特点 MySQL数据库分页 存取大对象 批处理 获取数据库主键值
1 Statement和PreparedStatement的特点 a)对于创建和删除表或数据库,我们可以使用executeUpdate(),该方法返回0,表示未影向表中任何记录 b)对于创建和 ...
- 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...
- [HTML5] Blob对象
写在前面 本篇主要总结Blob对象属性及作用,通过DEMO介绍Blob对象的应用场景. Blob对象 一直以来,JS都没有比较好的可以直接处理二进制的方法.而Blob的存在,允许我们可以通过JS直接操 ...
- [转] Meida视频加密二-Blob对象
2. blob 1 <video src="blob:http://www.bilibili.com/d0823f0f-2b2a-4fd6-a93a-e4c82173c107" ...
- blob 对象 实现分片上传 及 显示进度条
blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象.Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是js中的一个对象,里面可以储存大量的二进 ...
- js中关于Blob对象的介绍与使用
js中关于Blob对象的介绍与使用 blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象.Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是 ...
- jQuery 源码分析(十) 数据缓存模块 data详解
jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...
- [转] Blob对象
Blob是计算机界通用术语之一,全称写作:BLOB(binary large object),表示二进制大对象.MySql/Oracle数据库中,就有一种Blob类型,专门存放二进制数据.在javas ...
随机推荐
- JBoss7安装、测试、配置和启动以及停止,部署
转:http://www.hongyanliren.com/2014m01/3013.html 内容概要 JBoss系列三主要目的是演示如何部署应用到JBoss7/WildFly,如下图中描述了部署应 ...
- Http学习之使用HttpURLConnection发送post和get请求(1)
最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,post与get的不同之处在于post的参数不是放在URL字串里面,而是放 ...
- R语言-Kindle特价书爬榜示例 & 输出HTML小技巧(转)
自从买了kindle以后,总是想要定期刷有没有便宜的书,amazon经常有些1元/2元的书打特价,但是每次都去刷那些榜单太麻烦了,而且榜单又不能按照价格排名,捞书有点累 所以自己用R语言的rvest包 ...
- react 的五脏六腑ing~
用react一年多了.一直是在别人的影子下写的代码,他们也确实都是大神级的人物,不过,小菜鸟也有小菜鸟的思想~这不,今天就在重温一遍react!记一些零碎的知识点~不知道对你们有没有用,不过,对于我, ...
- RabbitMQ 应用学习随笔
1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang. erlang:http://www.erlang.org/download. ...
- 线程(java课堂笔记)
1.两种方式的差异 2.线程的生命周期 3.线程控制(线程的方法) 4.线程同步 5.线程同步锁 一. 两种方式的差异 A extends Thread :简单 不能再继承其他类了(Java单继承)同 ...
- Nginx上部署HTTPS
Nginx上部署HTTPS依赖OpenSSL库和包含文件,即须先安装好libssl-dev,且ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/, ...
- 一般处理程序+htm C#l简单的增删查改
首先引用两个文件一个dll: 数据库表已创建 首先编写数据读取部分 /// <summary> /// 查询 /// </summary> /// <param name ...
- 网络数据传输安全及SSH与HTTPS工作原理
本节内容 网络数据传输安全概述 数据加密算法分类 SSH工作原理 HTTPS工作原理 参考资料 个人一直在努力推动git在公司内部的普及和使用,前些日子在公司内部做了一次分享课,给大家介绍了下项目发布 ...
- 利用SSH框架开发时遇到的各种Bug及解决方法
.hibernate自动生成的配置文件 hibernate.cfg.xml 有时候是有问题的,会出现 org.hibernate.HibernateException: Could not parse ...