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中就提供了设定缓存对象的生命 ...
- 微信小程序中用户登录和登录态维护
提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情.像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件. 让用户 ...
随机推荐
- 796B Find The Bone
B. Find The Bone time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- EXISTS 和 IN 的区别
exists子句的用法 select * from 表1 where exists (select * from 表2 where 表1.列名=表2.列名); exists子句返回的结果并不是从数据库 ...
- Spring 中参数名称解析 - ParameterNameDiscoverer
Spring 中参数名称解析 - ParameterNameDiscoverer Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.ht ...
- 爬虫初窥day4:requests
Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 模块提供了你所需要的大多数 ...
- 虚函数与bind 实现设计模式的练习
相同模式使用虚函数与bind function进行实现对比 #include "stdafx.h" #include <iostream> #include <f ...
- mysql链接
一 Mysql命令行连接 一般对于刚刚安装好的mysql,如果勾选启用mysql lineclient的话.可以直接通过找到开始---程序--- mysql command line client如下 ...
- SpringMVC学习八 @ResponseBody注解
(一)在方法上只有@RequestMapping 时,无论方法返回值是什么认为需要跳转,代码实例如下 @RequestMapping("demo10") public People ...
- Mac版Java安装与配置
一.下载并安装JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 双击下载的 ...
- Shader中的lerp
下面解释下什么是lerp的功能: 官方解释 float lerp(float a, float b, float w) { return a + w*(b-a); } 木有看懂 我的解释:把上面的 ...
- flask框架基础
一 web的一些框架介绍 Flask:短小精悍,内部没有包含多少组件,但是第三方的组件是非常丰富的. Django:django是一个重武器,内部包含了非常多的组件:orm,form,modelFor ...