Spring缓存机制和Redis的结合

  • 这里使用reids作为缓存。
  • 使用Mybatis来操作数据库。
  • 并使用Spring的@Cacheable,@CachePut,@CacheEvict注解来操作redis缓存。

1 准备环境

包结构
Spring缓存机制和Redis的结合_第1张图片

1 Spring配置 RootConfig.java

@Configuration
@ComponentScan(basePackages="cn.wu")
@EnableTransactionManagement
public class RootConfig {
	
	// 配置数据源
	@Bean
	public DataSource initDataSource() {
		DataSource dataSource = null;
		Properties properties =  new Properties();
		properties.setProperty("driverClassName", "com.mysql.jdbc.Driver");
		properties.setProperty("url", "jdbc:mysql://localhost:3306/ssm?useSSL=false");
		properties.setProperty("username", "root");
		properties.setProperty("password", "数据库连接密码");
		try {
			dataSource = BasicDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dataSource;
	}
	
	// 配置mybatis的SqlSession的工厂
	@Bean(name="sqlSessionFactory")
	public SqlSessionFactoryBean initSqlSessionFactoryBean() {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(initDataSource()); // 设置dataSource
		Resource resource = new ClassPathResource("mybatis-config.xml"); 
		sqlSessionFactoryBean.setConfigLocation(resource); // 设置mybatis配置文件
		return sqlSessionFactoryBean;
	}
	
	// 配置mybatis映射器的扫描器
	@Bean
	public MapperScannerConfigurer initMapperScannerConfigurer() {
		MapperScannerConfigurer mapperScannerConfigurer  = new MapperScannerConfigurer();
		mapperScannerConfigurer.setBasePackage("cn.wu.mapper");
		mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
		mapperScannerConfigurer.setAnnotationClass(Repository.class);
		return mapperScannerConfigurer;
	}
	
	// 配置事务管理器
	@Bean
	public PlatformTransactionManager initTransactionManager() {
		DataSourceTransactionManager transactionManage = new DataSourceTransactionManager();
		transactionManage.setDataSource(initDataSource());
		return transactionManage;
	}

}

mybatis-config.xml代码:

  

 
 	
 

2 使用Redis作为缓存的相关配置RedisConfig.java

@Configuration
@EnableCaching // 让Spring IOC容器启动缓存机制
public class RedisConfig {

	@Bean
	public RedisConnectionFactory initRedisConnectionFactory() {
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxIdle(50);
		poolConfig.setMaxTotal(100);
		poolConfig.setMaxWaitMillis(20000);

		JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);
		connectionFactory.setHostName("localhost");
		connectionFactory.setPort(6379);
		return connectionFactory;
	}

	@Bean
	public RedisTemplate initRedisTemplate() {
		RedisTemplate redisTemplate = new RedisTemplate();
		redisTemplate.setConnectionFactory(initRedisConnectionFactory());

		StringRedisSerializer stringSerializer = new StringRedisSerializer();
		JdkSerializationRedisSerializer jdkSSerializer = new JdkSerializationRedisSerializer();

		redisTemplate.setKeySerializer(stringSerializer);
		redisTemplate.setValueSerializer(jdkSSerializer);
		redisTemplate.setDefaultSerializer(stringSerializer);
		redisTemplate.setHashKeySerializer(stringSerializer);
		redisTemplate.setHashValueSerializer(jdkSSerializer);

		return redisTemplate;
	}

	/*
	 * 配置Spring缓存管理器
	 * 这里的缓存管理器是RedisCacheManager。
	 * RedisCacheManager实现了Spring的CacheManager接口
	 */
	@Bean(name = "redisCacheManager")
	public CacheManager initRedisCacheManager(@Autowired RedisTemplate redisTemplate) {
		RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
		// 设置键的超时时间为10分钟
		redisCacheManager.setDefaultExpiration(600L);
		// 设置缓存名称
		List cacheNames = new ArrayList<>();
		cacheNames.add("redisCacheManager");
		redisCacheManager.setCacheNames(cacheNames);
		return redisCacheManager;
	}

}

2 Mybatis映射器代码与配置

1 Role.java

public class Role implements Serializable{
	
	private static final long serialVersionUID = -4295925571801283375L;
	private Long id;
	private String roleName;
	private String note;
    // getter setter
}

2 RoleMapper.java

@Repository
public interface RoleMapper {
	Role getRole(Long id);
	
	int deleteRole(Long id);
	
	int insertRole(Role role);
	
	int updateRole(Role role);
	
	List findRoles(@Param("roleName")String roleName, @Param("note")String note);
}

3 RoleMapper.xml

  


	

	
		delete from t_role where
		id = #{id}
	

	
		insert into t_role(role_name,
		note) values(#{roleName}, #{note})
	



	
		update t_role set
		role_name = #{roleName}, note = #{note} where id = #{id}
	

	

3 使用映射器的Service代码

RoleService.java

public interface RoleService {
	Role getRole(Long id);

	int deleteRole(Long id);

	Role insertRole(Role role);

	Role updateRole(Role role);

	List findRoles(String roleName, String note);
}

RoleServiceImpl.java

@Service
public class RoleServiceImpl implements RoleService {
	@Autowired
	private RoleMapper roleMapper;
	
	/**
	 * value = "redisCacheManager"表示使用的缓存名称(这里使用的是RedisConfig中配置的缓存管理器名称)
	 * key = "'redis_role_'+#id" 表示缓存到redis时的key
	 * 
	 * @Cacheable 表示在执行getRole()代码前,先到redis查询对应key的缓存,
	 * 若存在缓存则直接返回缓存;
	 * 若缓存不存在,则执行数据库查询代码,然后将结果缓存到redis,其key为"'redis_role_'+#id"。
	 * 所以@Cacheable 适合放在查询命中率高的方法上
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@Cacheable(value = "redisCacheManager", key = "'redis_role_'+#id")
	public Role getRole(Long id) {
		return roleMapper.getRole(id);
	}
	
	/**
	 * @CachePut , 不管有没有缓存,insertRole()代码都会去执行,然后将返回的结果缓存到redis中。
	 * 所以@CachePut 适合放在插入和更新数据库的方法上。
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CachePut(value="redisCacheManager",key="'redis_role_'+#role.id")
	public Role insertRole(Role role) {
		roleMapper.insertRole(role);
		return role;
	}

	/**
	 * @CacheEvict 表示删除redis中的缓存,这里删除的时key="'redis_role_'+#id"的缓存
	 */
	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CacheEvict(value="redisCacheManager", key="'redis_role_'+#id")
	public int deleteRole(Long id) {
		return roleMapper.deleteRole(id);
	}

	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	@CachePut(value="redisCacheManager", key="'redis_role_'+#role.id")
	public Role updateRole(Role role) {
		roleMapper.updateRole(role);
		return role;
	}

	@Override
	public List findRoles(String roleName, String note) {
		return roleMapper.findRoles(roleName, note);
	}

}

4 测试

public class Main {
	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext(RootConfig.class, RedisConfig.class);
		RoleService roleService = context.getBean(RoleService.class);
		Role role = new Role();
		role.setRoleName("李华");
		role.setNote("好人");
		roleService.insertRole(role); // reids中缓存了key=redis_role_67,值为role对象
		System.out.println(role); // Role [id=67, roleName=李华, note=好人]
		Role role2 = roleService.getRole(role.getId()); // 没有执行数据库查询语句,而是直接返回了redis中的缓存
		role2.setNote("备注好人");
		roleService.updateRole(role2);// 更新了数据库中的记录和reids中的缓存
	}
}

你可能感兴趣的:(Redis笔记,Spring基础,Spring缓存,Redis,MyBatis,注解)