SSM中使用redis做中间缓存,详细注释,代码可以运行
1.介绍
在开发中经常遇到大量的重复的,高并发的查询,此时可以使用redis缓存,将结果存入到redis中,当用户发起查询请求时,先在redis中查询结果,没有命中再去访问数据库。这样可以大大减少数据库压力。
2.结构目录
我的项目可以正常运行,代码都会给出来,所以代码都是可以跑的
要用到的所有文件都给出来了,新建一个项目就可以了
config:文件夹是配置文件,采用了注解的方式,其实和xml差不多,用注解的方式也算是对ssm的理解吧
dao:sql的文件
model:对象
service:实现
test:main的测试类
log4j:日志的配置文件,一定要放在src的根目录下!!!!!!!
test813SpringRedis这个包也是在src的根目录下的
3.环境准备
redis服务开启;
mysql中建立库:t_role,建立表role,如下
服务开启;
4.配置文件
RedisConfig:
package test813SpringRedis.config;import java.util.ArrayList;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import com.mysql.fabric.xmlrpc.base.Array;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Template;import redis.clients.jedis.JedisPoolConfig;/*** @Description* @Author zengzhiqiang* @Date 2018年8月13日 */
@Configuration
//EnableCaching 表示 Spring IoC 容器启动了缓存机制
@EnableCaching
public class RedisConfig {@Bean(name = "redisTemplate")public RedisTemplate initRedisTemplate(){JedisPoolConfig poolConfig = new JedisPoolConfig();//最大空闲数poolConfig.setMaxIdle(50);//最大连接数poolConfig.setMaxTotal(100);//最大等待毫秒数poolConfig.setMaxWaitMillis(20000);//创建 Jedis 连接工厂JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);connectionFactory.setHostName("localhost");connectionFactory.setPort(6379);//调用后初始化方法,没有它将抛出异常connectionFactory.afterPropertiesSet();//自定 Redis 序列化器RedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();RedisSerializer stringRedisSerializer = new StringRedisSerializer();//定义 RedisTemplate 并设置连接工程RedisTemplate redisTemplate = new RedisTemplate();redisTemplate.setConnectionFactory(connectionFactory);//设置序列化器redisTemplate.setDefaultSerializer(stringRedisSerializer);redisTemplate.setKeySerializer(stringRedisSerializer);redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);redisTemplate.setHashKeySerializer(stringRedisSerializer);redisTemplate.setHashValueSerializer(jdkSerializationRedisSerializer);return redisTemplate;}@Bean(name="redisCacheManager")public CacheManager initcCacheManager(@Autowired RedisTemplate redisTemplate){RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);//设置超时时间为 10 分钟,单位为秒cacheManager.setDefaultExpiration(600);//设置缓存名称List<String> cacheNames = new ArrayList<String>();cacheNames.add("redisCacheManager");cacheManager.setCacheNames(cacheNames);return cacheManager;} }
RootConfig:
package test813SpringRedis.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;/**
* @Description
* @Author zengzhiqiang
* @Date 2018年8月13日
*/
@Configuration
//定义 Spring 扫描的包
@ComponentScan("test813SpringRedis.*")
//使用事务驱动管理器
@EnableTransactionManagement
//实现接口 TransactionManagementConfigurer ,这样可以配置注解驱动事务
public class RootConfig implements TransactionManagementConfigurer{
private DataSource dataSource = null;
/**
* 设置日志
* @Description 这里有个坑,log4j的配置文件得放到源文件加的更目录下,src下才起作用,放包里不起作用,找了好久的错误
* @Param
* @Return
*/
@Bean(name="PropertiesConfigurer")
public PropertyPlaceholderConfigurer initPropertyPlaceholderConfigurer(){
PropertyPlaceholderConfigurer propertyLog4j = new PropertyPlaceholderConfigurer();
Resource resource = new ClassPathResource("log4j.properties");
propertyLog4j.setLocation(resource);
return propertyLog4j;
}
/**
* 配置数据库
*/
@Bean(name="dataSource")
public DataSource initDataSource(){
if(dataSource!=null){
return dataSource;
}
Properties props = new Properties();
props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
props.setProperty("url", "jdbc:mysql://localhost:3306/t_role");
props.setProperty("username","root");
props.setProperty("password", "123456");
try {
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
/**
* 配置 SqlSessionFactoryBean,这里引入了spring-mybatis的jar包,是两个框架的整合
*/
@Bean(name="sqlSessionFactory")
public SqlSessionFactoryBean initSqlSessionFactory(){
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
//配置 MyBatis 配置文件
Resource resource = new ClassPathResource("test813SpringRedis/config/mybatis-config.xml");
sqlSessionFactory.setConfigLocation(resource);
return sqlSessionFactory;
}/**
* 通过自动扫描,发现 MyBatis Mapper 接口
*/
@Bean
public MapperScannerConfigurer initMapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//扫描包
msc.setBasePackage("test813SpringRedis.*");
msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
//区分注解扫描
msc.setAnnotationClass(Repository.class);
return msc;
}
/**
* 实现接口方法,注册注解事务 当@Transactonal 使用的时候产生数据库事务
*/
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(initDataSource());
return transactionManager;
}}
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<mapper resource="test813SpringRedis/dao/mapping/RoleMapper.xml" />
</mappers>
</configuration>
当然你也可以把它换成xml的配置形式
注释很详细了,代码全都在这里了
5.dao实现
RoleDao:
package test813SpringRedis.dao.mapper;
import java.util.List;
import org.springframework.stereotype.Repository;
import test813SpringRedis.model.Role;
/**
* @Description
* @Author zengzhiqiang
* @Date 2018年8月13日
*/
@Repository
public interface RoleDao {public Role getRole(int id);
public int deleteRole(int id);
public int insertRole(Role role);
public int updateRole(Role role);
public List<Role> findRoles( String name);
}
RoleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="test813SpringRedis.dao.mapper.RoleDao"><insert id = "insertRole" parameterType="test813SpringRedis.model.Role">
insert into role(id,name,note) values(#{id},#{name},#{note})
</insert><update id = "updateRole" parameterType="test813SpringRedis.model.Role">
update role set name=#{name},note=#{note} where id = #{id}
</update><delete id = "deleteRole">
delete from role where id=#{id}
</delete><select id = "getRole" resultType="test813SpringRedis.model.Role">
select * from role where id =#{id}
</select><select id = "findRoles" resultType="test813SpringRedis.model.Role">
select * from role
<where>
<if test="name!= null">
name like concat('%',#{name},'%')
</if></where>
</select>
</mapper>
6.对象
package test813SpringRedis.model;
import java.io.Serializable;
/**
* @Description 注意,该类实现了 Serializable 接口,这说明这个类支持序列化,这样就可以通过 Spring
的序列化器,将其保存为对应的编码,缓存到 Redis 中,也可以通过 Redis 读回那些编码,
反序列化为对应的 Java 对象。
* @Author zengzhiqiang
* @Date 2018年8月13日
*/public class Role implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int id ;
private String name;
private String note;public int getId() {
return id;
}public void setId(int id) {
this.id = id;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public String getNote() {
return note;
}public void setNote(String note) {
this.note = note;
}}
7.实现
RoleService
package test813SpringRedis.service.inf;
import java.util.List;
import test813SpringRedis.model.Role;
/**
* @Description
* @Author zengzhiqiang
* @Date 2018年8月14日
*/public interface RoleService {
public Role getRole(int id);
public int deleteRole(int id);
public Role insertRole(Role role);
public Role updateRole(Role role);
public List<Role> findRoles(String name);
}
RoleServiceImpl
package test813SpringRedis.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import test813SpringRedis.dao.mapper.RoleDao;
import test813SpringRedis.model.Role;
import test813SpringRedis.service.inf.RoleService;/**
* @Description
* @Author zengzhiqiang
* @Date 2018年8月14日
*/
@Service
public class RoleServiceImpl implements RoleService{
@Autowired
private RoleDao roleDao ;
/**
* 使用自Cacheable 定义缓存策略:先去访问缓存,没有命中则访问数据库
* 通过 value 引用缓存管理器,通过 key 定义键
* key="'redis_role_'+#id" 这是spring的EL表达式,计算返回一个key,用key访问redis
*/@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@Cacheable(value = "redisCacheManager",key="'redis_role_'+#id")
public Role getRole(int id) {
return roleDao.getRole(id);
}/**
* 使用@ CacheEvict 移除缓存对象
* 使用在插入数据的地方,则表示保存到数据库后,会同期插入 Redis 缓存中
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CacheEvict(value="redisCacheManager",key="'redis_role_'+#id")
public int deleteRole(int id) {
return roleDao.deleteRole(id);
}/**
* #result.id 写法就会返回方法返回的角色 id(使用于主键数据库生成,其实这里我是自己生成的)
*/
@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CachePut(value="redisCacheManager",key="'redis_role_'+#result.id")
public Role insertRole(Role role) {
roleDao.insertRole(role);
return role;
}@Override
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
@CachePut(value="redisCacheManager",key="'redis_role_'+#role.id")
public Role updateRole(Role role) {
roleDao.updateRole(role);
return role ;
}/**
* 条件查询不使用缓存策略
*/
@Override
public List<Role> findRoles(String name) {
return roleDao.findRoles(name);
}}
8.测试
package test813SpringRedis.test;
import org.apache.log4j.Logger;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;import test813SpringRedis.config.RedisConfig;
import test813SpringRedis.config.RootConfig;
import test813SpringRedis.model.Role;
import test813SpringRedis.service.inf.RoleService;/**
* @Description
* @Author zengzhiqiang
* @Date 2018年8月14日
*/public class TestMain {
private static Logger log = Logger.getLogger(TestMain.class);
@SuppressWarnings("resource")
public static void main(String[] args) {
log.info("begin....");
//使用注解 Spring IoC 容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(RootConfig.class,RedisConfig.class);
//获取角色服务类
RoleService roleService = ctx.getBean(RoleService.class);
Role role = new Role();
role.setId(5);
role.setName("role_name_1");
role.setNote("role_note_1");
roleService.insertRole(role);
Role getRole = roleService.getRole(role.getId());
getRole.setNote("role_note_1_update");
roleService.updateRole(getRole);
System.out.println("operation ok");
}}
9日志
log4j.properties
log4j.rootLogger = DEBUG,stdout
log4j.logger.org.springframework=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n
10结果
在redis中存在了经过序列化之后的java对象,即是role
看下日志;
好吧,太多,就不上图了,
你会发现只是连接了两次数据库,分别是插入和更新,所以在查的时候,取得了redis的数据,没有走数据库
11注意
我这里都是引入的jar包的方式,推荐使用maven
主要的东西,当然你spring,mbatis,的jar包都放进去最好了
再多说几句
那个日志信息打印,我是弄了好久才好的,本来都想放弃了的,还是坚持弄出来了。
不要差不多,如果啥子都差不多就行了,那你的人生也就差不多的人生。
君子如玉 -----记录
SSM中使用redis做中间缓存,详细注释,代码可以运行相关推荐
- Spring整合Redis做数据缓存(Windows环境)
当我们一个项目的数据量很大的时候,就需要做一些缓存机制来减轻数据库的压力,提升应用程序的性能,对于java项目来说,最常用的缓存组件有Redis.Ehcache和Memcached. Ehcache是 ...
- DotNetty系列六:将服务端和客户端改为Winform窗口,使用Redis做为缓存,实现用户登录,好友,群组上下线显示。
这次改动挺大的. 1.服务端和客户端改为Winform窗口.好多细节未处理,只是实现了功能. 2.使用Redis做为缓存,版本redis-3.0.1,和RedisDesktopManager做 ...
- 【Java项目中 利用Redis实现数据缓存】
文章目录 Java SpringBoot项目中 用Redis实现数据缓存 1 环境搭建 1.1 maven坐标 1.2 配置文件 1.3 配置类 2 实现缓存短信验证码 3 缓存菜品数据 4 Spri ...
- redis做数据库缓存
只读缓存 使用只读缓存时,是先把修改写到后端数据库中,再把缓存中的数据删除.当下次访问这个数据时,会以后端数据库中的值为准,重新加载到缓存中. 这样做的优点是,数据库和缓存可以保证完全一致,并且缓存中 ...
- jedis使用_Mybatis的二级缓存、使用Redis做二级缓存
什么是二级缓存? 二级缓存和一级缓存的原理是一样的,第一次查询,会将数据放入缓存中,然后第二次查询则会直接去缓存中取.但是一级缓存是基于的sqlSession,而二级缓存是基于mapper文件的nam ...
- redis做mysql缓存的优点_面试官:如何保障数据库和redis缓存的一致性
随着互联网的高速发展,使用互联网产品的人也越来越多,团队不可避免得也会面对越来越复杂的高并发业务场景(如下图),比如热点视频/文章的观看(读场景),热点视频/文章的评论,点赞等(写场景). 众所周知, ...
- 实际开发中使用Redis做分布式锁,躲坑指南,收藏起来
今天我们来聊聊Redis分布式锁,曾经被Redis分布式锁的坑给坑惨了,接下来,我就进行一个完整的整理,希望大家都能避免踩坑. 在分布式系统中,由于redis分布式锁相对于更简单和高效,成为了分布式锁 ...
- SSM中通过Json做前后端分离
场景 前面项目已经搭建到SSM中进行注解式和XML配置式事务管理阶段 参照: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/851 ...
- 《机器学习实战》萌新读书笔记 ② — — 第三章 决策树 内容提要、知识拓展和详细注释代码
目录 引入: 什么是决策树? 决策树相较KNN的优势? 决策树的运作方式? 决策树模型的优缺? 决策树的构造: 构造思路 信息增益 划分数据集 递归构造决策树 绘制决策树树形图 Matplotlib注 ...
最新文章
- linux find 排除某目录或文件 执行
- vb.net form 最大化按钮 代码_【React】利用antd的form自定义表单控件
- 开源天生就不是为了赚钱!
- 如何将妙控键盘连接到 Macbook?
- c#-多线程中lock用法的经典实例
- 实现一个文本文件的解析类(vector,字符串解析的应用)
- 单机安装DynamicsAX2012R3VM
- Oracle查询执行计划
- C1083,无法打开包括文件...
- Django Setting的时区设置
- 计算机两字符是多少磅,word字符磅 word里一个字符等于多少磅
- IBM Spectrum LSF RTM
- 反编译获取小程序源码
- 微信小程序的重点(重中之重)
- OC:不会说话的汤姆猫(2014年12月)未添加音频
- 人工智能会成为下一场的科技革命吗?
- NLPCC2023 | 视频定位问答比赛CMIVQA赛题解析
- 【Kotlin 协程】Flow 异步流 ⑤ ( 流的上下文 | 上下文保存 | 查看流发射和收集的协程 | 不能在不同协程中执行流的发射和收集操作 | 修改流发射的协程上下文 | flowOn函数 )
- C语言程序设计——结构体 给定如下定义:struct date_rec { int day ; int month ; int year ; } ; struct date_rec current_
- centos查看linux硬盘型号ssd,centos linux查看硬盘型号