1. 程式人生 > >Spring Boot中引入Redis快取

Spring Boot中引入Redis快取

本文模擬兩種場景,一是使用Dao從資料庫讀取資料並快取,一是使用RedisTemplate操作快取。

1、Redis配置

pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.properties

# REDIS (RedisProperties)
# Redis資料庫索引(預設為0
) spring.redis.database=0 # Redis伺服器地址 spring.redis.host=127.0.0.1 # Redis伺服器連線埠 spring.redis.port=6379 # Redis伺服器連線密碼(預設為空) spring.redis.password=123456 # 連線超時時間(毫秒),不能使用0,否則報錯:超時 spring.redis.timeout=100

RedisConfig.java

package com.test.demo.config;

import org.springframework.beans.factory.annotation.
Value; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.*; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonAutoDetect; @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport{ @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Bean public RedisTemplate<String, String> redisTemplate( RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); setSerializer(template);// 設定序列化工具 template.afterPropertiesSet(); return template; } private void setSerializer(StringRedisTemplate template) { @SuppressWarnings({ "rawtypes", "unchecked" }) Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer( Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); } }

DemoApplication.java
增加dao包掃描,開啟快取

@SpringBootApplication
// 在啟動類中新增對mapper包掃描@MapperScan
@MapperScan({"com.test.demo.mybatis.dao","com.test.demo.redis"})
//開啟快取功能[redis]
@EnableCaching
public class DemoApplication

2、業務模擬一

Redis實體

package com.test.demo.redis;

import java.io.Serializable;

public class UserBean implements Serializable {
	private static final long serialVersionUID = 56613L;
	private Long id;
	private String username;
	private String name;
	private String password;
	private String salt;
	private String state;
	
	get,set....
}

RedisUserDao.java

package com.test.demo.redis;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
@CacheConfig(cacheNames = "users")
public interface RedisUserDao {
	@Select("select * from USER_INFO where id =#{id}")
	@Cacheable(key = "'userid:'+#p0")
	// SpEL表示式:在SpEL表示式中,預設情況下,表示式字首為 ' # ' ,而後綴為 ' } '
	// 如果表示式中沒有字首和字尾,那麼表示式字串就被當作純文字
	UserBean findByCacheKey(@Param("id") String id);
}

Controller類
在HelloController類中,新增如下內容:

	@Resource
	RedisUserDao redisService;
	
	@RequestMapping("/getRedisUser")
	public UserBean getRedisUser(String key) {
		System.out.println("-- key - Username --"+key);
		return this.redisService.findByCacheKey(key);
	}

執行
瀏覽器中訪問http://cos6743:8081/getRedisUser?key=802
返回結果:{“id”:802,“username”:“yangtom”,“name”:“tom”,“password”:“25f9e79388b62b”,“salt”:null,“state”:null}

3、業務模擬二

UserRedisMapper.java

package com.test.demo.redis;

import javax.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class UserRedisMapper {
	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 普通快取獲取
	 * @param key 鍵
	 * @return 值
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}

	/**
	 * 普通快取放入
	 * @param key 鍵
	 * @param value 值
	 * @return true成功 false失敗
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}

Controller類
在HelloController類中,新增如下內容:

	@Resource
	UserRedisMapper redisMapper;
	@RequestMapping("/getRedisUserinfo")
	public UserBean getRedisUserInfo(String key) {
		//為了key的區分,增加 user 開頭
		return (UserBean)this.redisMapper.get("user:"+key);
	}
	@RequestMapping("/addRedisUserinfo")
	public boolean setRedisUserInfo(String key) {
		UserBean user = new UserBean();
		user.setId(100L);
		user.setName(key);
		user.setUsername("Tom");
		user.setPassword("miwen");
		return this.redisMapper.set("user:"+key, user);
	}

執行
1、增加使用者:瀏覽器中訪問http://cos6743:8081/addRedisUserinfo?key=yang
返回結果:true
2、檢視使用者:瀏覽器中訪問http://cos6743:8081/getRedisUserinfo?key=yang
返回結果:{“id”:100,“username”:“Tom”,“name”:“yang”,“password”:“miwen”,“salt”:null,“state”:null}

4、Redis客戶端檢視keys

keys

5、SpringBootTest

注意區分 RedisTemplateStringRedisTemplate

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestRedis {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;    
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test() throws Exception {
    	redisTemplate.opsForValue().set("aaa", "111");
        Assert.assertEquals("111", redisTemplate.opsForValue().get("aaa"));
    }
    
    @Test
    public void testObj() throws Exception {
        boolean exists=redisTemplate.hasKey("testkey");
        if(exists){
            System.out.println("the value: "+redisTemplate.opsForValue().get("aaa"));
            System.out.println("the spring value: "+stringRedisTemplate.opsForValue().get("testkey"));
        }else{
            System.out.println("exists is false");
        }
    }
}