Redis中在程序中的应用
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;
}
}
Redis中在程序中的应用的更多相关文章
- 在C#中winform程序中应用nlog日志工具
在C#中winform程序中应用nlog日志工具,配置文件简单应用. 文件名 nlog.config,请注意修改属性为"始终复制",发布时候容易遇到不存在文件的错误提示. 通过Nu ...
- C#中Winform程序中如何实现多维表头【不通过第三方报表程序】
问题:C#中Winform程序中如何实现多维表头. 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂.最后在新浪博客看到了一篇比较易懂的文章:[DataGridView二维表头与合并单元格 ...
- redis在.Net程序中使用
1.设置访问密码 config 2.连接redis服务器 private static string redisHost = ConfigHelper.GetAppSetting("redi ...
- Spring Boot中在程序中获得application.properties中的值
方法是使用@Value注解的方式注解一个值. 首先,在我们的application.properties中添加一个值如下: zifeiy.tmpfile.location=D:/duty 然后在我们的 ...
- C# 中从程序中下载Excel模板
方法一: #region 下载模板 /// <summary> /// 下载模板 /// </summary> /// <param name="sender& ...
- 阿里P7级教你如何在Spring Boot应用程序中使用Redis
在Spring Boot应用程序中使用Redis缓存的步骤: 1.要获得Redis连接,我们可以使用Lettuce或Jedis客户端库,Spring Boot 2.0启动程序spring-boot-s ...
- Redis在WEB开发中的应用与实践
Redis在WEB开发中的应用与实践 一.Redis概述: Redis是一个功能强大.性能高效的开源数据结构服务器,Redis最典型的应用是NoSQL.但事实上Redis除了作为NoSQL数据库使用之 ...
- ASP.NET Core MVC应用程序中的后台工作任务
在应用程序的内存中缓存常见数据(如查找)可以显着提高您的MVC Web应用程序性能和响应时间.当然,这些数据必须定期刷新. 当然你可以使用任何方法来更新数据,例如Redis中就提供了设定缓存对象的生命 ...
- 微信小程序中用户登录和登录态维护
提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户 ...
随机推荐
- MacDev.GarbageCollectionIsDeprecated-WhenXcodeCompileMacAppProject
Garbage Collection is not supported 当Xcode编译Mac OSX App时报错:"Garbage Collection is not supported ...
- BZOJ 1791: [IOI2008]Island 岛屿 - 基环树
传送门 题解 题意 = 找出无向基环树森林的每颗基环树的直径. 我们首先需要找到每颗基环树的环, 但是因为是无向图,用tarjan找环, 加个手工栈, 我也是看了dalao的博客才知道tarjan找无 ...
- ubuntu如何实现双屏显示
转载自https://blog.csdn.net/tianmaxingkong_/article/details/50570538
- Servlet会话管理三(HttpSession)
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象.由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数 ...
- [Hbase]Hbase容灾方案
介绍两种HBase的数据备份或者容灾方案:Snapshot,Replication: 一.Snapshot 开启快照功能,在hbase-site.xml文件中添加如下配置项: <property ...
- word2vec_训练模型
from gensim.models import Word2Vecfrom gensim.models.word2vec import LineSentence # 原始的训练语料转化成一个sent ...
- docker下安装tensorflow
一,查找镜像 root@xushi:~# docker search tensorflow NAME DESCRIPTION STARS OFFICIAL AUTOMATED tensorflow/t ...
- 更精确的判断对象类型js方法
function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]'; } function isRe ...
- netty4初步使用
文件 D:\jp\netty\NtServer.java import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chan ...
- centOS 6.5下升级mysql,从5.1升级到5.6
转载:https://www.cnblogs.com/vickygu2007/p/5066409.html #mysqldump -uroot -p --all-databases > data ...