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包都放进去最好了

再多说几句

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

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

君子如玉 -----记录

 

版权声明:本文为zzqtty原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zzqtty/article/details/81665569

智能推荐

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

猜你喜欢

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...

OpenStack代码贡献初体验

为什么80%的码农都做不了架构师?>>>     OpenStack如今已成为开源云平台中的明星项目,得到广泛关注。OpenStack的优秀出众依赖于众多开发者的努力,在享受其带来的便利与快捷的同时,为其做一份贡献也是一个开发者的义务。  在前段时间的OpenStack的测试过程中,我发现Nova项目中的一个Bug,于是向社区提交了Bug报...

SQL Server之8:sql查询每个学生得分最高的两门课

这是一道面试题,今天有空把它记下来,以后遇到此类问题作个参考!刚一看到这个题目,估计好多人都会想到关键字top,其实这里用到的关键字是partition, 好了,先看看表结构,及数据吧!     接下来看一看partition的功能,执行语句   结果如下:   到这里一目了然知道最终结果了!   View Code     &...