基于redis缓存实现用户增删改查的项目分析
需求
redis的作用是实现数据的缓存,以此来提升系统性能。
在本案例中,基本功能是实现用户的增删改查,主要在用户的查询和修改时用到了redis的缓存。
- 业务逻辑 -查询:首先对接收到的userid在redis缓存中查询,如果没有在查询mysql数据库,查询到以后将查询结果封装成json类型发送给redis进行缓存,方便下次读取
- 业务逻辑 -更新:执行更新操作后,需要将redis中原来的缓存也一并删除,并将更新过的数据重新插入redis缓存
项目运行环境
1、在运行项目时,需要打开单机版redis,以及redis图形化工具RedisDesktopManager(方便查看数据变更信息)
2、需要关闭防火墙
3、需要有mysql或者oracle数据库
项目搭建
1、父工程
采取maven来构建项目,父工程为pom工程,并且添加以下坐标,并对其版本进行控制
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 对依赖的jar包的版本统一进行定义 -->
<properties>
<jedis.version>2.9.0</jedis.version>
<jedis.version>2.9.0</jedis.version>
<junit.version>4.12</junit.version>
<spring.version>4.1.3.RELEASE</spring.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mysql.version>5.1.32</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<druid.version>1.0.9</druid.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<tomcat.version>2.2</tomcat.version>
<jsp-api.version>2.0</jsp-api.version>
<jackson.version>2.4.2</jackson.version>
</properties>
<!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
<dependencyManagement>
<dependencies>
<!-- Jedis,实现java操作redis数据库 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
<pluginManagement>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2、子工程
jar工程,进行业务功能的具体实现,下面将主要粘贴一些重要代码
- JedisDao 与其实现类
package com.bjsxt.jedisdao;
public interface JedisDao {
String set(String key,String value);
String get(String key);
Long hset(String key,String field,String value);
String hget(String key,String field);
/**
* 用于设置失效时间
* @param key
* @param sec
* @return
*/
Long expire(String key,int sec);
/**
* 删除jedis缓存
* @param key
* @return
*/
Long del(String key);
}
package com.bjsxt.jedisdao.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bjsxt.jedisdao.JedisDao;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@Service
public class JedisDaoSingleImpl implements JedisDao{
//使用@Autowired要开启组件扫描,不使用的话要通过pagebean的propertie注入进来
@Autowired
private JedisPool jedispool;
@Override
public String set(String key, String value) {
Jedis resource=jedispool.getResource();
return resource.set(key, value);
}
@Override
public String get(String key) {
Jedis resource=jedispool.getResource();
return resource.get(key);
}
@Override
public Long hset(String key, String field, String value) {
Jedis resource=jedispool.getResource();
return resource.hset(key, field, value);
}
@Override
public String hget(String key, String field) {
Jedis resource=jedispool.getResource();
return resource.hget(key, field);
}
@Override
public Long expire(String key, int sec) {
Jedis resource = jedispool.getResource();
return resource.expire(key, sec);
}
@Override
public Long del(String key) {
Jedis resource = jedispool.getResource();
return resource.del(key);
}
}
- 业务实现类(核心代码),实现用户的增删改查并使用redis缓存对系统进行优化
package com.bjsxt.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.bjsxt.commons.JsonUtils;
import com.bjsxt.jedisdao.JedisDao;
import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import redis.clients.jedis.JedisPool;
/**
* 业务逻辑 -查询:首先对接受到的userid在redis数据库中查询,如果没有在查询mysql数据库,查询以后将拆线呢结果封装成json类型发送给redis缓存
* 业务逻辑 -更新:执行更新操作后,需要将redis中的缓存也一并删除,并将更新过的数据重新插入redis缓存
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UsersMapper userMapper;
@Autowired
private JedisDao jedisDao;
//@Autowired
//private JedisPool jedisPool;
@Override
public void addUser(Users users) {
this.userMapper.insertUsers(users);
}
@Override
public void updateUser(Users users) {
this.userMapper.updateUser(users);
int userid = users.getUserid();
try {
//删除原来的redis缓存
this.jedisDao.del(this.REDIS_USERS_PRIFX+":"+userid);
} catch (Exception e) {
e.printStackTrace();
}
try {
//删除后将更新过后的信息放入redis
String objectToJson = JsonUtils.objectToJson(users);
//String redis_Key = this.REDIS_USERS_PRIFX+":"+userid;
jedisDao.set(this.REDIS_USERS_PRIFX+":"+userid, objectToJson);
jedisDao.expire(this.REDIS_USERS_PRIFX+":"+userid,100);//如果设置失败,最好clean一下
//jedisPool.getResource().expire(redis_Key, 20);
} catch (Exception e) {
e.printStackTrace();
}
}
//添加了一个配置文件内容为:REDIS_USERS_PRIFX=REDIS_USERS_PRIFX
//@Value,获取配置文件中相关参数的值
@Value("${REDIS_USERS_PRIFX}")
private String REDIS_USERS_PRIFX;
@Override
public Users findByUserid(int userid) {
try {
//查看缓存
String json=this.jedisDao.get(this.REDIS_USERS_PRIFX+":"+userid );//p拼接成json类型字符串key:value
//在缓存中是否命中
if (json != null && json.length()>0) {//命中
System.out.println("-----------------调用查看redis缓存操作--------------------");
Users users=JsonUtils.jsonToPojo(json, Users.class);
return users;
}
} catch (Exception e) {//保证不影响功能正常实现,需要用try。。。catch
e.printStackTrace();
}
//查询数据库
Users users=this.userMapper.selByUserId(userid);
System.out.println(users);
System.out.println("==================查询mysql并放入redis缓存=========================");
try {
//放入redis中
String objectToJson = JsonUtils.objectToJson(users);
//String redis_Key = this.REDIS_USERS_PRIFX+":"+userid;
jedisDao.set(this.REDIS_USERS_PRIFX+":"+userid, objectToJson);
jedisDao.expire(this.REDIS_USERS_PRIFX+":"+userid,60);//如果设置失败,最好clean一下
//jedisPool.getResource().expire(redis_Key, 1000);
} catch (Exception e) {
e.printStackTrace();
}
return users;
}
}
- 扫描配置文件,在application-dao.xml配置文件中添加如下代码
<!-- 配置解析properties文件的工具类 -->
<!-- <context:property-placeholder location="classpath:db.properties"/> -->
<context:property-placeholder location="classpath:resource/*.properties"/>
- 令redis生效的applicationContext-jedis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1、首先配置组件扫描,在这里秩序依赖spring来扫描 -->
<!-- <context:component-scan base-package="com.bjsxt.jedisdao.JedisDao"/> -->
<!-- jedisPool的配置 -->
<bean id="poolconfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大连接数 -->
<property name="maxTotal" value="30" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="10" />
<!-- 每次释放连接的最大数目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 释放连接的扫描间隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 连接最小空闲时间 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在获取连接的时候检查有效性, 默认false -->
<property name="testOnBorrow" value="true" />
<!-- 在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true" />
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- 3、配置JedisPool -->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig">
<ref bean="poolconfig"></ref>
</constructor-arg>
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>6379</value>
</constructor-arg>
</bean>
<!-- 2、springJedisDaoSingleImpl -->
<bean id="jedisDaoSingleImpl" class="com.bjsxt.jedisdao.impl.JedisDaoSingleImpl"></bean>
<!-- a、配置JedisCluster -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8001</value>
</constructor-arg>
</bean>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8002</value>
</constructor-arg>
</bean>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8003</value>
</constructor-arg>
</bean>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8004</value>
</constructor-arg>
</bean>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8005</value>
</constructor-arg>
</bean>
<bean name="hostAndPort" class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host">
<value>192.168.179.131</value>
</constructor-arg>
<constructor-arg name="port">
<value>8006</value>
</constructor-arg>
</bean>
</set>
</constructor-arg>
<constructor-arg name="poolConfig">
<ref bean="poolconfig"></ref>
</constructor-arg>
</bean>
<!-- 配置JedisDaoClusterImpl -->
<!-- <bean id="jedisDaoClusterImpl" class="com.bjsxt.jedisdao.impl.JedisDaoClusterImpl"></bean> -->
</beans>
运行效果
第一次查询id为1的用户
第二次查询id为1的用户(相当于刷新页面)
修改数据:
redis客户端显示的结果
项目源码~~~
链接:https://pan.baidu.com/s/1Bat7QS6akuSF4k6MprIFiw
提取码:z23d
复制这段内容后打开百度网盘手机App,操作更方便哦