SSM框架上集合Redis技术
为了完成毕业设计,将之前做的电商网站进行整改,目前需要整合上Redis,说明一下步骤,为到时候答辩做个笔记
前言:Redis简介(简单概述)
- key-value存储系统
- 支持string,list链表,set集合,hash表
- 符合原子性(成功则提交,失败则回滚),要么就完成,要么就不完成,当作什么都没做,就是一定要完成一整套的操作,不可中途退出
- 无需考虑多线程的并发问题
- 缓存在内存中
以上是一些简述,我只用到这些,用到哪些写哪些,没用过的就没有写,(写上也不一定会用,额,到时候再补充)
第一步:下载Redis(跟没说一样,但是这里有关于Redis闪退的问题)
安装好Redis后,打开Redis服务有时会发现弹出一个窗口就闪退;
- 目前已知的原因只发现一个:已经有Redis进程在启动
解决方案:任务管理器 -----> 找到Redis进程 -----> 结束关闭它 -----> 再次重启
- 还有一种情况闪退,有解决方案,但是还没弄清问题产生的原因,所以先放上解决方案:
更改redis文件夹中的 redis.windows.conf
#bind 127.0.0.1 去掉#
然后重启Redis,或者CMD上 cd 到 Redis存储路径 执行 redis-server.exe redis.windows.conf
有的时候还是会报错,讲道理,这里真不知道为什么!!(百度了好久,看来还是不够认真)
如果还有错,那就这样:
redis-cli.exe -----> shutdown -----> exit -----> edis-server.exe redis.windows.conf
依次执行命令行,难受(希望有人告诉我),额,继续整合步骤!
第二步:编写Redis配置文件(redis.properties、spring-redis.xml)
这里说明一下redis.properties。后续会有SpringBoot的更换,换成yml的格式,先说一下,以免到时候忘掉
还有,我的配置文件目录形式如下:
将spring的配置文件放入spring文件夹中,方便管理,在spring-dao.xml中,这里加载了redis.properites的配置:
<bean class="com.zhaoyu.shop.util.EncryptPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
<property name="fileEncoding" value="UTF-8" />
</bean>
这里一个是jdbc的配置,一个是redis的配置;
- redis.properties的编写:
redis.hostname=127.0.0.1
redis.port=6379
redis.database=0
redis.pool.maxActive=600
redis.pool.maxIdle=300
redis.pool.maxWait=3000
redis.pool.testOnBorrow=true
这里不做过多的说明了,强调一下默认端口号 6379 (之前被问过,竟然忘了。。)
这个properties的编写和数据库连接(jdbc.properties)的一样
- spring-redis.xml的编写
-
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <!-- Redis连接池的设置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 控制一个pool可分配多少个Jedis实例 --> <property name="maxTotal" value="${redis.pool.maxActive}" /> <!-- 连接池中最多可空闲maxIdle个连接,这里取值为20,表示即使没有数据库连接时依然可以保持20个空闲的连接,而不被清除,随时处于待命状态 --> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <!-- 最大连接时间,当没有可用连接时 --> <property name="maxWaitMillis" value="${redis.pool.maxWait}" /> <!-- 在获取连接时检查有效性 --> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> </bean> <!-- 创建Redis连接池,并作相关配置 --> <bean id="jedisWritePool" class="com.zhaoyu.shop.cache.JedisPoolWriper" depends-on="jedisPoolConfig"> <constructor-arg index="0" ref="jedisPoolConfig" /> <constructor-arg index="1" value="${redis.hostname}" /> <constructor-arg index="2" value="${redis.port}" type="int" /> </bean> <bean id="jedisKeys" class="com.zhaoyu.shop.cache.JedisUtil$Keys" scope="singleton"> <constructor-arg ref="jedisUtil"></constructor-arg> </bean> <bean id="jedisStrings" class="com.zhaoyu.shop.cache.JedisUtil$Strings" scope="singleton"> <constructor-arg ref="jedisUtil"></constructor-arg> </bean> <bean id="jedisLists" class="com.zhaoyu.shop.cache.JedisUtil$Lists" scope="singleton"> <constructor-arg ref="jedisUtil"></constructor-arg> </bean> <bean id="jedisSets" class="com.zhaoyu.shop.cache.JedisUtil$Sets" scope="singleton"> <constructor-arg ref="jedisUtil"></constructor-arg> </bean> <bean id="jedisHash" class="com.zhaoyu.shop.cache.JedisUtil$Hash" scope="singleton"> <constructor-arg ref="jedisUtil"></constructor-arg> </bean> <!-- 创建Redis工具类,封装好Redis的连接并进行相关操作 --> <bean id="jedisUtil" class="com.zhaoyu.shop.cache.JedisUtil" scope="singleton"> <property name="jedisPool"> <ref bean="jedisWritePool" /> </property> </bean> </beans>
说明一下上述的配置文件:
- 首先设置Redis连接池
<!-- Redis连接池的设置 -->
<bean id="jedisPoolConfig"
class="redis.clients.jedis.JedisPoolConfig">
<!-- 控制一个pool可分配多少个Jedis实例 -->
<property name="maxTotal" value="${redis.pool.maxActive}" />
<!-- 连接池中最多可空闲maxIdle个连接,这里取值为20,表示即使没有数据库连接时依然可以保持20个空闲的连接,而不被清除,随时处于待命状态 -->
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<!-- 最大连接时间,当没有可用连接时 -->
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
<!-- 在获取连接时检查有效性 -->
<property name="testOnBorrow"
value="${redis.pool.testOnBorrow}" />
</bean>
<property name="maxTotal" value="${redis.pool.maxActive}" />
这里有个value,和jdbc的连接池一样,动态获取redis.properties中的对应值
- 创建Redis连接池,配置其属性
<!-- 创建Redis连接池,并作相关配置 -->
<bean id="jedisWritePool"
class="com.zhaoyu.shop.cache.JedisPoolWriper"
depends-on="jedisPoolConfig">
<constructor-arg index="0" ref="jedisPoolConfig" />
<constructor-arg index="1" value="${redis.hostname}" />
<constructor-arg index="2" value="${redis.port}"
type="int" />
</bean>
<constructor-arg index="2" value="${redis.port}" type="int" />
这里的value和上面一样
- 创建Redis工具类,封装好Redis的连接并进行相关操作
<!-- 创建Redis工具类,封装好Redis的连接并进行相关操作 -->
<bean id="jedisUtil" class="com.zhaoyu.shop.cache.JedisUtil"
scope="singleton">
<property name="jedisPool">
<ref bean="jedisWritePool" />
</property>
</bean>
<bean id="jedisKeys" class="com.zhaoyu.shop.cache.JedisUtil$Keys"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisStrings"
class="com.zhaoyu.shop.cache.JedisUtil$Strings" scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisLists"
class="com.zhaoyu.shop.cache.JedisUtil$Lists" scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisSets" class="com.zhaoyu.shop.cache.JedisUtil$Sets"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
<bean id="jedisHash" class="com.zhaoyu.shop.cache.JedisUtil$Hash"
scope="singleton">
<constructor-arg ref="jedisUtil"></constructor-arg>
</bean>
这块的配置就是对于Redis的相关操作,分别为key,String,List,set,hash
现在配置文件就完成了;
第三步:编写redis连接池类(jedisWritePool)管理连接
这里说到了jedis,我的理解就是jedis就是集成了redis的一些命令操作,封装了redis的java客户端。提供了连接池管理;
话句话说,jedis就是redis的客户端;
jedisWritePool.java代码如下:
/**
* 强指定redis的JedisPool接口构造函数,这样才能在centos成功创建jedispool
*
* @author xiangze
*
*/
public class JedisPoolWriper {
/**
* redis连接池对象
*/
private JedisPool jedisPool;
public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host,
final int port) {
try {
jedisPool = new JedisPool(poolConfig, host, port);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取 redis连接池对象
* @return
*/
public JedisPool getJedisPool() {
return jedisPool;
}
/**
* 注入redis连接池对象
* @param jedisPool
*/
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
}
这里就是实现构造方法,传参连接池配置信息,host地址,port端口号,然后通过get和set方法,实现对连接池的获取和注入
第四步:编写redis操作类(JedisUtil)操作Redis数据库
JedisUtil.java:代码如下
public class JedisUtil {
/** 操作Key的方法 */
public Keys KEYS;
/** 对存储结构为String类型的操作 */
public Strings STRINGS;
/** 对存储结构为List类型的操作 */
public Lists LISTS;
/** 对存储结构为Set类型的操作 */
public Sets SETS;
/** 对存储结构为HashMap类型的操作 */
public Hash HASH;
private JedisPool jedisPool;
/**
* 从Jedis连接池中获取redis连接池
* @return
*/
public JedisPool getJedisPool() {
return jedisPool;
}
/**
* 设置redis连接池
* @param jedisPoolWriper
*/
public void setJedisPool(JedisPoolWriper jedisPoolWriper) {
this.jedisPool = jedisPoolWriper.getJedisPool();
}
/**
* 从jedis连接池中获取获取jedis对象
*
* @return
*/
public Jedis getJedis() {
return jedisPool.getResource();
}
}
这就是一个简易的Jedis连接池工具类,比如像缓存生存时间等一些其他功能没有设置。。。
第五步:Redis缓存技术实现
这里就简述一个我的商品类别一览信息获取的redis缓存技术
public class ShopCategoryServiceImpl implements ShopCategoryService {
@Autowired
private JedisUtil.Strings jedisStrings;
@Autowired
private JedisUtil.Keys jedisKeys;
@Autowired
private ShopCategoryDao shopCategoryDao;
private static String SCLISTKEY = "shopcategorylist";
@Override
public List<ShopCategory> getFirstLevelShopCategoryList()
throws IOException {
//定义redis的key前缀
String key = SCLISTKEY;
//定义接受对象
List<ShopCategory> shopCategoryList = null;
//定义jackson数据转换操作类
ObjectMapper mapper = new ObjectMapper();
if (!jedisKeys.exists(key)) {
ShopCategory shopCategoryCondition = new ShopCategory();
// 当shopCategoryId不为空的时候,查询的条件会变为 where parent_id is null
shopCategoryCondition.setShopCategoryId(-1L);
shopCategoryList = shopCategoryDao
.queryShopCategory(shopCategoryCondition);
String jsonString = mapper.writeValueAsString(shopCategoryList);
jedisStrings.set(key, jsonString);
} else {
String jsonString = jedisStrings.get(key);
JavaType javaType = mapper.getTypeFactory()
.constructParametricType(ArrayList.class,
ShopCategory.class);
shopCategoryList = mapper.readValue(jsonString, javaType);
}
return shopCategoryList;
}
}
- 首先,注入JedisUtil工具类中的String,key字段属性
- 定义一个key 为 SCLISTKEY,值是shopcategorylist
- 判断redis中是否有需要的数据,若为true,则查询出数据,通过ObjectMapper类将ArrayList对象转换成ShopCategory(商品类别)类的对象
- 若redis中没有相关数据,则从数据库中查询,并将其准换成(查出的数据是list)string,然后set到redis中对应的key值
推荐阅读
-
java SSM框架 代码生成器 快速开发平台 websocket即时通讯 shiro redis
-
.NET框架-集合和LINQ中的“分组”技术代码详解
-
SSM框架上集合Redis技术
-
mysql-用MySQL运行了一个maven ssm程序框架到web上,求位大神告诉我这是什么错误?谢谢!
-
ssm弹幕视频网站系统:使用SSM/springboot框架实现,前段技术使用html+js+css+layui+jsp实现,数据库采用mysql,实现了前后端分离视频管理网站
-
mysql-用MySQL运行了一个maven ssm程序框架到web上,求位大神告诉我这是什么错误?谢谢!
-
Java核心技术点之集合框架的详细介绍
-
Java核心技术点之集合框架的详细介绍
-
.NET框架-集合和LINQ中的“分组”技术代码详解
-
java SSM框架 代码生成器 快速开发平台 websocket即时通讯 shiro redis