SpringBoot整合Redis--RedisTemplate
1、导入依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
复制代码 2、编写配置文件
- spring:
- redis:
- host: 192.168.27.132
- port: 6379
- password: lzyredis
- database: 1
- jedis:
- pool:
- max-active: 10
- max-wait: 3000
- min-idle: 5
- max-idle: 10
复制代码 3、测试代码
RedisTemplate.opsForXxx().操作
- Xxx:代表要操作的数据类型【value代表操作的是string】
- @SpringBootTest
- class SpringbootRedisDemoApplicationTests {
- @Autowired
- private RedisTemplate redisTemplate;
- @Test
- public void test(){
- //setIfAbsent 就是 setnx
- Boolean absent = redisTemplate.opsForValue().setIfAbsent("name", "xiaoming", 5 * 60, SECONDS);
- System.out.println("absent = " + absent);
- String name = (String) redisTemplate.opsForValue().get("name");
- System.out.println("name = " + name);
- }
- }
复制代码 springboot整合redis测试后存储的数据 打印结果 在第一张图中发现存储的key和value前出现了一些不认识的字符,虽然在RedisDesktopManager工具上显示不是期望的格式,但在打印结果上看却是正常显示的。
这是因为使用RedisTemplate来操作字符串时,在存储数据时会对key和value进行序列化操作。
序列化操作会对选择对应的序列化器来操作,如果没有指定序列化器,那么默认选择是JDK序列化器。
所以会出现一长串字符串。
4、RedisTemplate选择序列化器的原理:
RedisTemplate 继承RedisAccessor类,而该类实现了InitializingBean接口,
所以RedisTemplate会调用afterPropertiesSet方法。
在该方法中会对操作key和value进行序列化操作,
如果指定了具体的序列化器,那么就会使用指定的序列化器,
如果没有指定具体的序列化器,则使用JDK序列化器
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- boolean defaultUsed = false;
- if (this.defaultSerializer == null) {
- //没有指定的序列化器,那默认序列化器就为jdk序列化器
- this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
- }
- if (this.enableDefaultSerializer) {
- if (this.keySerializer == null) {
- this.keySerializer = this.defaultSerializer;
- defaultUsed = true;
- }
- if (this.valueSerializer == null) {
- this.valueSerializer = this.defaultSerializer;
- defaultUsed = true;
- }
- if (this.hashKeySerializer == null) {
- this.hashKeySerializer = this.defaultSerializer;
- defaultUsed = true;
- }
- if (this.hashValueSerializer == null) {
- this.hashValueSerializer = this.defaultSerializer;
- defaultUsed = true;
- }
- }
- if (this.enableDefaultSerializer && defaultUsed) {
- Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
- }
- if (this.scriptExecutor == null) {
- this.scriptExecutor = new DefaultScriptExecutor(this);
- }
- this.initialized = true;
- }
复制代码 如果不想使用默认的序列化器,可以自己指定序列化器或使用redis提供的StringRedisTemplate对象
5、配置序列化器
- 增加一个配置类,类上加@Configuration注解
- 添加如下方法,返回类型为RedisTemplate,并通过@Bean注解注入容器中
- @Configuration
- public class MyRedisConfig {
- @Bean("myRedisTemplate")
- public RedisTemplate myRedisTemplate(RedisConnectionFactory connectionFactory){
- RedisTemplate myRedisTemplate = new RedisTemplate();
- //设置连接工厂
- myRedisTemplate.setConnectionFactory(connectionFactory);
- //更换key和value的序列化器
- myRedisTemplate.setKeySerializer(new StringRedisSerializer());
- myRedisTemplate.setValueSerializer(new StringRedisSerializer());
- return myRedisTemplate;
- }
- }
复制代码- @SpringBootTest
- public class myRedisTemplateTest {
- @Autowired
- private RedisTemplate myRedisTemplate;
- @Test
- public void myRedisTemplateTest(){
- Boolean flag = myRedisTemplate.opsForValue().setIfAbsent("name2", "zhangsan", 5 * 60, TimeUnit.SECONDS);
- System.out.println("flag = " + flag);
- String name2 = (String) myRedisTemplate.opsForValue().get("name2");
- System.out.println("name2 = " + name2);
- }
- }
复制代码 redisTemlate指定序列化器后存储的数据 6、StringRedisTemplate
6.2 StringRedisTemplate分析
StringRedisTemplate就相当于指定了String序列化器的RedisTemplate对象。
查看org.springframework.data.redis.core包下的StringRedisTemplate源码:- public class StringRedisTemplate extends RedisTemplate<String, String> {
- public StringRedisTemplate() {
- this.setKeySerializer(RedisSerializer.string());
- this.setValueSerializer(RedisSerializer.string());
- this.setHashKeySerializer(RedisSerializer.string());
- this.setHashValueSerializer(RedisSerializer.string());
- }
- public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
- this();
- this.setConnectionFactory(connectionFactory);
- this.afterPropertiesSet();
- }
- protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
- return new DefaultStringRedisConnection(connection);
- }
- }
复制代码 从源码中可以看到StringRedisTemplate构造函数中指定了key、value的序列化器为string序列化器
这就相当于第五点我们自定义RedisTemplate并指定string序列化器。因此我们可以直接注入使用StringRedisTemplate对象
6.2 StringRedisTemplate使用
- @SpringBootTest
- public class myRedisTemplateTest {
- @Resource
- private StringRedisTemplate stringRedisTemplate;
- @Test
- public void test(){
- stringRedisTemplate.opsForValue().set("age","123");
- }
- }
复制代码 StringRedisTemplate使用结果 7、redisTemplate存储对象
使用redisTemplate的opsForValue可以存储对象,存储时会把对象转成字节数组来存储- @SpringBootTest
- public class SaveObjectTest {
- @Autowired
- private RedisTemplate redisTemplate;
- @Test
- public void saveTest(){
- Person person = new Person();
- person.setId(1);
- person.setName("zhangsan");
- person.setAge(20);
- //使用redisTemplate的opsForValue可以存储对象,存储时会把对象转成字节数组来存储
- redisTemplate.opsForValue().set("person"+person.getId(),person);
- Person person1 = (Person) redisTemplate.opsForValue().get("person1");
- System.out.println("person1 = " + person1);
- }
- }
复制代码 相比较与jedis存储对象,更加方便,去掉了我们自己自定义的将对象转为字符串或者字符数组的过程。redisTemplate会将对象转为字节数组来存储。
运行结果:
redisTemplate存储对象 8、redisTemplate管道操作
- 不使用管道存储10000个对象,用时约7158ms
- @SpringBootTest
- public class SaveObjectTest {
- @Autowired
- private RedisTemplate redisTemplate;
- @Test
- public void saveTest(){
- Person person = new Person();
- person.setId(1);
- person.setName("zhangsan");
- person.setAge(20);
- long start = System.currentTimeMillis();
- for (int i = 0; i < 10000; i++) {
- redisTemplate.opsForValue().set("person" + person.getId()+i, person);
- }
- System.out.println(System.currentTimeMillis()-start); //用时7158ms
- }
- }
复制代码- @SpringBootTest
- public class SaveObjectTest {
- @Autowired
- private RedisTemplate redisTemplate;
- @Test
- public void pipelineTest() {
- long start = System.currentTimeMillis();
- redisTemplate.executePipelined(new SessionCallback<String>() {
- @Override
- public String execute(RedisOperations operations) throws DataAccessException {
- Person person = new Person();
- person.setId(1);
- person.setName("zhangsan");
- person.setAge(20);
- long start = System.currentTimeMillis();
- for (int i = 1; i < 10000; i++) {
- operations.opsForValue().set("person" + i, "person:" + person);
- }
- System.out.println(System.currentTimeMillis()-start); //312ms
- return null;
- }
- });
- System.out.println(System.currentTimeMillis()-start);//2123ms
- }
- }
复制代码 管道存储10000个对象,用时约2123ms
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |