一个简单的Spring缓存机制整合Redis实例

这个实例的文件框架结构如下:
在这里插入图片描述

首先定义一个简单的角色类:

Role.java

package com.ssm.example3.pojo;

import java.io.Serializable;

public class Role implements Serializable {
    private Long id;
    private String roleName;
    private String note;

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

注意,该类实现了Serializable接口,这说明这个类支持序列化,这样就可以通过Spring的序列化器,将其保存为对应的编码。缓存到Redis中,也可以通过Redis都会这些编码,反序列化为对应的java对象。

接下来是关于MyBatis的开发环境,这样我们就可以操作数据库了。

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="com.ssm.example3.dao.RoleDao">

    <select id="getRole" resultType="com.ssm.example3.pojo.Role">
        select id, role_name as roleName,note from role where id=#{id}
    </select>

    <delete id="deleteRole">
        delete from role where id=#{id}
    </delete>

    <insert id="insertRole" parameterType="com.ssm.example3.pojo.Role" useGeneratedKeys="true" keyProperty="id">
        insert into role (role_name,note) values (#{roleName},#{note})
    </insert>

    <update id="updateRole" parameterType="com.ssm.example3.pojo.Role">
        update role set role_name=#{roleName},note=#{note}
    </update>

    <select id="findRoles" resultType="com.ssm.example3.pojo.Role">
        select id,role_name as roleName ,note from role
        <where>
            <if test="roleName != null">
                role_name like concat('%',#{roleName},'#')
            </if>
            <if test="note != note">
                note like concat('%',#{note},'%')
            </if>
        </where>
    </select>
</mapper>

然后需要一个MyBatis角色接口,以便使用这样的一个映射文件。

RoleDao.java

package com.ssm.example3.dao;

import com.ssm.example3.pojo.Role;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface RoleDao {
   public Role getRole(Long id);

   public int deleteRole(Long id);

   public int insertRole(Role role);

   public int updateRole(Role role);

   public List<Role> findRoles(@Param("roleName") String roleName,@Param("note") String note);
}

注意@Repository便是他是一个持久层的接口。通过扫描和注解联合定义DAO层,就完成了映射器方面的内容。接下来是定义服务接口定义角色服务接口。

RoleService.java

package com.ssm.example3.service;

import com.ssm.example3.pojo.Role;

import java.util.List;

public interface RoleService {
    public Role getRole(Long id);

    public int deleteRole(Long id);

    public Role insertRole(Role role);

    public Role updateRole(Role role);

    public List<Role> findRoles(String roleName,String note);
}

这个实例我是用注解来配置定义数据库个相关的扫描内容。

RootConfig.java

package com.ssm.example3.config;

import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
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.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;


import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@ComponentScan("com.*")
//使用事务驱动管理器
@EnableTransactionManagement
//实现接口 TransactionManagementConfigurer,这样可以配置注解驱动事务
public class RootConfig implements TransactionManagementConfigurer {

    private DataSource dataSource=null;

    /**
     * 配置数据库
     * @return 数据库连接池
     */
    @Bean(name = "dataSource")
    public DataSource initDataSource(){
        if(dataSource!=null){
            return dataSource;
        }
        Properties props=new Properties();
        props.setProperty("driveClassName","com.mysql.jdbc.Driver");
        props.setProperty("url","jdbc:mysql://localhost:3306/ssm");
        props.setProperty("username","root");
        props.setProperty("password","123456");
        try {
            dataSource= BasicDataSourceFactory.createDataSource(props);
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return dataSource;
    }

    /**
     * 配置SqlSessionFactoryBean
     * @return SqlSessionFactoryBean
     */
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactoryBean initSqlSessionFactory(){
        SqlSessionFactoryBean sqlSessionFactory=new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(initDataSource());
        //配置Mybatis配置文件
        Resource resource=new ClassPathResource("com/ssm/example3/mybatis/mybatis-cfg.xml");
        sqlSessionFactory.setConfigLocation(resource);
        return sqlSessionFactory;
    }

    /**
     * 通过自动扫描,发现Mybatis Mapper接口
     * @return Mapper 扫描器
     */
    @Bean
    public MapperScannerConfigurer initMapperScannerConfigurer(){
        MapperScannerConfigurer msc=new MapperScannerConfigurer();
        //扫描包
        msc.setBasePackage("com.*");
        msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
        //区分注解扫描
        msc.setAnnotationClass(Repository.class);
        return msc;
    }

    /**
     * 实现接口方法,注册注解事务,当@Transactional使用的时候产生数据库事务
     * @return
     */
    @Override
    @Bean(name = "annotationDrivenTransactionManeger")
    public TransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
        transactionManager.setDataSource(initDataSource());
        return transactionManager;
    }
}

在里面引入了一个关于MyBatis的一个配置文件——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="com/ssm/example3/sqlMapper/RoleMapper.xml"></mapper>
    </mappers>
</configuration>

下面我们再来配置Redis的相关内容。

RedisConfig.java

package com.ssm.example3.config;

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 redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * 配置Spring缓存管理器
 */
@Configuration
@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.setPassword("123456");
        //调用后初始化方法,没有它将抛出异常
        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 initRedisCacheManager(@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;
    }
}

最后我们在编写RoleService的实现类——RoleServiceImpl。

RoleServiceImpl.java

package com.ssm.example3.service.impl;

import com.ssm.example3.dao.RoleDao;
import com.ssm.example3.pojo.Role;
import com.ssm.example3.service.RoleService;
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 java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    //角色DAO,方便执行SQL
    @Autowired
    private RoleDao roleDao=null;

    /**
     * 使用@Cacheable定义缓存策略
     * 当缓存中有值,则返回缓存数据,否则访问方法得到数据。
     * 通过value引用缓存管理器,通过key定义键
     * @param id 角色编号
     * @return 角色
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    @Cacheable(value = "redisCacheManager",key = "'redis_role_'+#id")
    public Role getRole(Long id) {
        return roleDao.getRole(id);
    }

    /**
     * 使用@CachePut则表示无论如何都会执行方法,最后将方法的返回值在保存到缓存中
     * 使用在插入数据的地方,则表示保存到数据库后,会同时插入Redis缓存中
     * @param role 角色对象
     * @return
     */
    @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;
    }

    /**
     * 使用@CachePut,表示更新数据库数据的同时,也会同步更新缓存
     * @param role 角色对象
     * @return
     */
    @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
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public List<Role> findRoles(String roleName, String note) {
        return roleDao.findRoles(roleName,note);
    }

    /**
     * 使用@CacheEvict删除缓存对应的key
     * @param id 角色编号
     * @return 返回删除记录数
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    @CacheEvict(value = "redisCacheManager",key = "'redis_role_'+#id")
    public int deleteRole(Long id) {
        return roleDao.deleteRole(id);
    }
}

到此已全部配置完成,现在我们用一个测试类来测试一下

testRedis.java

package com.ssm.example3.test;


import com.ssm.example3.config.RedisConfig;
import com.ssm.example3.config.RootConfig;
import com.ssm.example3.pojo.Role;
import com.ssm.example3.service.RoleService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class testRedis {
    public static void main(String[] args){
        ApplicationContext ctx=new AnnotationConfigApplicationContext(RootConfig.class,RedisConfig.class);
        //获取角色服务类
        RoleService roleService=ctx.getBean(RoleService.class);
        Role role=new Role();
        role.setRoleName("role_name_1");
        role.setNote("role_note_1");
        //插入角色
        roleService.insertRole(role);
        //获取角色
        Role getRole=roleService.getRole(role.getId());
        getRole.setNote("role_note_2");
        //修改角色信息
        roleService.updateRole(getRole);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值