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中就提供了设定缓存对象的生命 ...
- 微信小程序中用户登录和登录态维护
提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户 ...
随机推荐
- iOS.Library.Architecture
在用file查看library的architechture时有以下输出: $ file WebPWebP: Mach-O universal binary with 3 architecturesWe ...
- python入门科普IDE工具和编译环境
应友人之邀,今天来讲述python的一些入门内容.本次讲解的并不是语法或者某个模块. python下载安装 大多数 Linux 发行版在默认安装的情况 ...
- PS制作纸质复古野外露营插画分享
经常有人说一些复古风,就觉得蛮难,其实制作过程其实没有想象中复杂,从1850年到2017年,通过这160多年里的平面设计,给我们的作品添加上一些新鲜的灵感和活力,本次教程就来教大家用PS做出耐看的纸质 ...
- python_docx制作word文档详细使用说明【转】
目前网上对这一个库的介绍得很少,很零散,所以很多功能我是尽量参考其官网,但是官网上面很多功能目前只有说明文档,而代码并还没有及时更新,以至于按照官网上面做了,python却报错.比如:自定义表格的 ...
- JDK 之 NIO 2 WatchService、WatchKey(监控文件变化)
JDK 之 NIO 2 WatchService.WatchKey(监控文件变化) JDK 规范目录(https://www.cnblogs.com/binarylei/p/10200503.html ...
- [JAVA]多线程下如何确定执行顺序性
最近在讨论一个下载任务:要求文件下载后进行打包,再提供给用户下载: 如何确保打包的线程在所有下载文件的线程执行完成后进行呢? 看看下面三个兄弟的本事: CountDownLatch.CyclicBar ...
- ES线程池
每个Elasticsearch节点内部都维护着多个线程池,如index.search.get.bulk等,用户可以修改线程池的类型和大小,线程池默认大小跟CPU逻辑一致 一.查看当前线程组状态 cur ...
- MongoDB相关记录
win10中zip安装 下载地址:http://dl.mongodb.org/dl/win32/x86_64 首先解压至某文件夹, 使用管理员权限打开cmd或者powershell, 进入指定目录中的 ...
- Flex + .Net从本地选择一个图片上传到服务器
<mx:TextInput id="TxtFileName" editable="false" width="200"/> &l ...
- Java类加载机制及自定义加载器
转载:https://www.cnblogs.com/gdpuzxs/p/7044963.html Java类加载机制及自定义加载器 一:ClassLoader类加载器,主要的作用是将class文件加 ...