标签:java logs trace config 行业 容器 function key 获取数据
1、导入redis的配置文件,因为要交给web容器管理,所以直接命名为ApplicationContext-redis.xml,具体配置如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 构建连接池配置信息 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大连接数 --> <property name="maxTotal" value="${redis.maxTotal}" /> </bean> <bean id="jedisShardInfo1" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis.node1.ip}" /> <constructor-arg index="1" value="${redis.node1.port}" type="int" /> </bean> <bean id="jedisShardInfo2" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis.node2.ip}" /> <constructor-arg index="1" value="${redis.node2.port}" type="int" /> <!-- 端口必须为int类型,如果不写的话,默认是字符串类型,这是时候不起作用,所以端口就是默认端口,会造成分片失败 --> </bean> <bean id="jedisShardInfo3" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis.node3.ip}" /> <constructor-arg index="1" value="${redis.node3.port}" type="int" /> </bean> <!-- 定义集群连接池 --> <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" destroy-method="close"> <constructor-arg index="0" ref="jedisPoolConfig" /> <constructor-arg index="1"> <list> <ref bean="jedisShardInfo1" /> <ref bean="jedisShardInfo2" /> <ref bean="jedisShardInfo3"/> </list> </constructor-arg> </bean> </beans>
需要说明的是,这里是通过jedis进行操作的(jedis即java版的redis)
2、写伪service工具类
伪service--封装一个新的技术,融合进业务,而不是真正的业务层需要,但是本质还是service,目的是为了在controller中注入方便。经过伪service封装可以屏蔽掉底层的api
package com.jt.common.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
@Service
public class RedisService {
//有的工程需要,有的工程不需要。设置required=false,有就注入,没有就不注入。
@Autowired(required = false)
private ShardedJedisPool shardedJedisPool;
private <T> T execute(Function<ShardedJedis, T> function) {
ShardedJedis shardedJedis = null;
try {
// 从连接池中获取到jedis分片对象
shardedJedis = shardedJedisPool.getResource();
return function.execute(shardedJedis);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != shardedJedis) {
// 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态
shardedJedis.close();
}
}
return null;
}
/**
* 保存数据到redis中
*
* @param key
* @param value
* @return
*/
public String set(final String key, final String value) {
return this.execute(new Function<ShardedJedis, String>() {
@Override
public String execute(ShardedJedis shardedJedis) {
return shardedJedis.set(key, value);
}
});
}
/**
* 保存数据到redis中,生存时间单位是:秒
*
* @param key
* @param value
* @param seconds
* @return
*/
public String set(final String key, final String value, final Integer seconds) {
return this.execute(new Function<ShardedJedis, String>() {
@Override
public String execute(ShardedJedis shardedJedis) {
String result = shardedJedis.set(key, value);
shardedJedis.expire(key, seconds);//设置生存时间
return result;
}
});
}
/**
* 从redis中获取数据
*
* @param key
* @return
*/
public String get(final String key) {
return this.execute(new Function<ShardedJedis, String>() {
@Override
public String execute(ShardedJedis shardedJedis) {
return shardedJedis.get(key);
}
});
}
/**
* 设置key生存时间,单位:秒
*
* @param key
* @param seconds
* @return
*/
public Long expire(final String key, final Integer seconds) {
return this.execute(new Function<ShardedJedis, Long>() {
@Override
public Long execute(ShardedJedis shardedJedis) {
return shardedJedis.expire(key, seconds);
}
});
}
/**
* 从redis中删除数据
*
* @param key
* @return
*/
public Long del(final String key) {
return this.execute(new Function<ShardedJedis, Long>() {
@Override
public Long execute(ShardedJedis shardedJedis) {
return shardedJedis.del(key);
}
});
}
}
3、在对应的执行业务的service中添加缓存方法
我这里因为是要做的查询的一个三级树目录,通过点击前台页面的父选项,传递父ID给后台,查询对应的子类,并将子类集合返回
原代码如下:
package com.jt.manage.service;
import java.io.IOException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.common.service.BaseService;
import com.jt.common.service.RedisService;
import com.jt.manage.mapper.ItemCatMapper;
import com.jt.manage.pojo.ItemCat;
@Service
public class ItemCatService extends BaseService<ItemCat> {
@Autowired
private ItemCatMapper itemCatMapper;
public List<ItemCat> findItemCarList(Long parentId) {
itemCat.setParentId(parentId);
<!--这里采用的是JPA的方式,自动构建sql语句,查询的时候如果传入的是对象,那么会根据对象的属性当做where条件进行对应的匹配-->
return itemCatMapper.select(itemCat);
}
修改后的代码如下:
package com.jt.manage.service;
import java.io.IOException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jt.common.service.BaseService;
import com.jt.common.service.RedisService;
import com.jt.manage.mapper.ItemCatMapper;
import com.jt.manage.pojo.ItemCat;
@Service
public class ItemCatService extends BaseService<ItemCat> {
@Autowired
private ItemCatMapper itemCatMapper;
@Autowired
private RedisService redisService;
private static final ObjectMapper MAPPER = new ObjectMapper();
public List<ItemCat> findItemCarList(Long parentId) {
/*
* 如果传入的是对象,查询时就会根据对象的属性值添加where条件 写null表示不需要where条件
*/
ItemCat itemCat = new ItemCat();
/*
* 1、在执行业务前判断缓存总是否所有数据,如果有数据,就获取数据,直接返回结果
* 2、如果没有数据,继续执行业务,访问数据库,获取返回的值
* 3、再返回业务之前,把获取的数据在缓存中存放一份,然后再返回
* 4、放缓存:kv(String) 把java对象变成json字符串
* 5、拿缓存:把字符串转换成java对象List<ItemCat>
*/
itemCat.setParentId(parentId);
// 判断缓存中有无数据
// 定义键
String ITEM_CAT_KEY = "ITEM_CAT_" + parentId;
// 根据键获取数据
String jsonData = redisService.get(ITEM_CAT_KEY);
if (StringUtils.isNotEmpty(jsonData)) { // 缓存中有数据
try {
// 直接从缓存中获取数据,把json串转换为java对象
JsonNode jsonNode = MAPPER.readTree(jsonData);
Object obj = null;
if (jsonNode.isArray() && jsonNode.size() > 0) {
obj = MAPPER.readValue(jsonNode.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, ItemCat.class));
return (List<ItemCat>) obj;
}
} catch (Exception e) {
e.printStackTrace();
}
} else {//如果缓存中没有数据,执行业务
try {
//从数据库中获取数据
List<ItemCat> itemCatList = itemCatMapper.select(itemCat);
//将数据保存一份在缓存中
//将数据转换成json对象
String json = MAPPER.writeValueAsString(itemCatList);
//将对象保存进缓存
redisService.set(ITEM_CAT_KEY, json);
//返回需要的对象
return itemCatList;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return null;
}
}
标签:java logs trace config 行业 容器 function key 获取数据
原文地址:http://www.cnblogs.com/sxpy-lj/p/7290466.html