1.介绍

在开发中经常遇到大量的重复的,高并发的查询,此时可以使用redis缓存,将结果存入到redis中,当用户发起查询请求时,先在redis中查询结果,没有命中再去访问数据库。这样可以大大减少数据库压力。

2.结构目录

我的项目可以正常运行,代码都会给出来,所以代码都是可以跑的

基于ssm的redis配置 ssm redis_Redis

要用到的所有文件都给出来了,新建一个项目就可以了

config:文件夹是配置文件,采用了注解的方式,其实和xml差不多,用注解的方式也算是对ssm的理解吧

dao:sql的文件

model:对象

service:实现

test:main的测试类

log4j:日志的配置文件,一定要放在src的根目录下!!!!!!!

test813SpringRedis这个包也是在src的根目录下的

3.环境准备

redis服务开启;

mysql中建立库:t_role,建立表role,如下

基于ssm的redis配置 ssm redis_基于ssm的redis配置_02

服务开启;

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结果

基于ssm的redis配置 ssm redis_Redis_03

在redis中存在了经过序列化之后的java对象,即是role

看下日志;
好吧,太多,就不上图了,

你会发现只是连接了两次数据库,分别是插入和更新,所以在查的时候,取得了redis的数据,没有走数据库

11注意

我这里都是引入的jar包的方式,推荐使用maven

基于ssm的redis配置 ssm redis_spring_04

主要的东西,当然你spring,mbatis,的jar包都放进去最好了

再多说几句

那个日志信息打印,我是弄了好久才好的,本来都想放弃了的,还是坚持弄出来了。

不要差不多,如果啥子都差不多就行了,那你的人生也就差不多的人生。

君子如玉 -----记录