从未见过写得这么简单、详细的文章,spring的缓存大家可以参考
https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/
以下是我根据这篇文章,结合自己项目的一些经验
根据项目需求,上次的微博也有提到,有几张表的数据量太大,随意需要做分表。在插入数据的时候,要判断这张表在数据库是否存在。每次都去查询数据库太浪费资源,所以这次的目的是将表名写入到spring自带的缓存。废话不多说,直接上代码:
新加spring-cache-anno.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="default" />
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="accountCache" />
</set>
</property>
</bean>
</beans>
然后在springxxx中引入
<import resource="classpath*:spring-cache-anno.xml" ></import>
controller:
//根据传入的时间参数获取对应的表名
String tableName = xxxService.getTableNameByDate(new Date());
//从缓存中获取所有以"visit_history_"开头的表名,并放入缓存中,如果缓存已存在,就不查询数据库
List<String> tableNameList = tjscVisitBuyHistoryService.getTableNameListCache();
//表名不存在,则创建该表,并刷新缓存
if (tableNameList == null || !tableNameList.contains(tableName)) {
xxxService.createTable(tableName);
xxxService.updateTableNameListCache();
}
service:
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
//根据日期返回表名
public String getTableNameByDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
String calendarMounth = null;
//日历获取的月份为0-11,所以这里加1
if (calendar.get(Calendar.MONTH) < 9) {
calendarMounth = "0" + (calendar.get(Calendar.MONTH) + 1);
}
else {
calendarMounth = String.valueOf((calendar.get(Calendar.MONTH) + 1));
}
String tableName = preTableName + calendar.get(Calendar.YEAR) + calendarMounth;
return tableName;
}
//使用了一个缓存名叫 accountCache
/*@Cacheable(value=”accountCache”),
这个注释的意思是,当调用这个方法的时候,会从一个名叫 accountCache
的缓存中查询,如果没有,则执行实际的方法(即查询数据库),
并将执行的结果存入缓存中,否则返回缓存中的对象*/
@Cacheable(value = "accountCache")
public List<String> getTableNameListCache() {
return getTableNameListFromDB();
}
// 更新accountCache 缓存
@CacheEvict(value="accountCache")
public void updateTableNameListCache() {
updateTableNameListFromDB();
}
private List<String> getTableNameListFromDB() {
//从数据库获取表名,具体sql是
/*SELECT table_name FROM information_schema.`tables` WHERE TABLE_SCHEMA='mydb' AND table_name LIKE 'visit_history%_'*/
return xxxMapper.getTableNameList();
}
private void updateTableNameListFromDB() {
//从数据库获取表名
xxxMapper.getTableNameList();
}
第一次访问的时候tableNameList会从数据库中获取,后续除了更新缓存,再也没有数据库的查询操作~