010、使用redis

本文详细介绍了如何在Spring Boot项目中使用Redis,包括使用Jedis和spring-boot-starter-data-redis两种方式的配置和调用示例。同时,文章还深入探讨了序列化特殊类型数据的处理方法。

一、使用Jedis

1. 引入依赖

		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</dependency>

 

2. 配置

# application.properties

# jedis 使用
jedis.host=129.28.120.219
jedis.maxTotal=5
jedis.maxIdle=5
jedis.testOnBorrow=true

 

3. 配置Bean

package com.example.redis;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisConfig {
	
	@Bean
	@ConfigurationProperties(prefix = "jedis")
	public JedisPoolConfig jedisPoolConfig() {
		return new JedisPoolConfig();
	}
	
	@Bean
	public JedisPool jedisPool(@Value("${jedis.host}") String host) {
		return new JedisPool(jedisPoolConfig(), host);
	}

}

 

4. 调用

    @Autowired
	private JedisPool jedisPool;

	private void jedis() {
		log.info("jedisPoolConfig: {}", jedisPoolConfig);
		
		Student student = studentMapper.findById(1);
		
		log.info("student: {}", student);
		
		try (Jedis jedis = jedisPool.getResource()) {
			
			Long hset = jedis.hset("student-money", student.getName(), student.getMoney().getAmountMajorInt() + "");
			log.info("hset: {}", hset);
			
			Map<String, String> hgetAll = jedis.hgetAll("student-money");
			log.info("hgetAll: {}", hgetAll);
			
		}
	}

 

二、使用 spring-boot-starter-data-redis

1. 引入依赖

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

        <!--  json序列化 转换用  -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
		</dependency>

 

2. 配置

# application.properties

spring.redis.host=129.28.120.219
spring.redis.lettuce.pool.max-active=5
spring.redis.lettuce.pool.max-idle=5

 

3. redis bean 配置

package com.example.redis;

import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.example.redis.model.Student;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.lettuce.core.ReadFrom;

@Configuration
public class RedisConfig {

	@Primary
	@Bean
	public RedisTemplate<String, Student> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

		RedisTemplate<String, Student> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(redisConnectionFactory);

		return redisTemplate;

	}

	@Bean(name = "redisTemplateJson")
	public RedisTemplate<String, Student> redisTemplateJson(RedisConnectionFactory redisConnectionFactory) {

		RedisTemplate<String, Student> redisTemplate = new RedisTemplate<>();
		redisTemplate.setConnectionFactory(redisConnectionFactory);

		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
				Object.class);
		ObjectMapper mapper = new ObjectMapper();
		mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		
		jackson2JsonRedisSerializer.setObjectMapper(mapper);

		redisTemplate.setKeySerializer(new StringRedisSerializer());
		redisTemplate.setStringSerializer(new StringRedisSerializer());
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

		return redisTemplate;

	}
	
	@Bean
	public LettuceClientConfigurationBuilderCustomizer customizer() {
		return new LettuceClientConfigurationBuilderCustomizer() {

			@Override
			public void customize(LettuceClientConfigurationBuilder clientConfigurationBuilder) {
				clientConfigurationBuilder.readFrom(ReadFrom.MASTER_PREFERRED);
			}
		};
	}

}

 

4. 序列化特殊类型的处理

上面的bean redisTemplateJson 在序列化 Student的时候,Money类有点问题,反序列化会失败。所以,在序列化和反序列化的时候,针对Money作特殊处理。

package com.example.redis.model;

import java.io.IOException;
import java.io.Serializable;
import java.util.Date;

import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class Student implements Serializable {

	private static final long serialVersionUID = -1976946780360524613L;

	private Integer id;

	private String name;

    // 这里特殊处理json序列化
	@JsonSerialize(using = MoneyJsonSerializer.class)
	@JsonDeserialize(using = MoneyJsonDeserializer.class)
	private Money money;

	private Date createTime;

	private Date updateTime;

	@Data
	@Accessors(chain = true)
	@NoArgsConstructor
	@AllArgsConstructor
	private static class MoneyInner {
		private String code;
		private int amount;
	}

	private static class MoneyJsonSerializer extends JsonSerializer<Money> {
		@Override
		public void serialize(Money value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
			gen.writeObject(new MoneyInner(value.getCurrencyUnit().getCode(), value.getAmountMinorInt()));
		}
	}

	private static class MoneyJsonDeserializer extends JsonDeserializer<Money> {
		@Override
		public Money deserialize(JsonParser p, DeserializationContext ctxt)
				throws IOException, JsonProcessingException {
			MoneyInner moneyInner = ctxt.readValue(p, MoneyInner.class);
			return Money.ofMinor(CurrencyUnit.of(moneyInner.code), moneyInner.amount);
		}
	}

}

 

5. 调用

    private Student findStudent2(String name) {
		
		ValueOperations<String, Student> opsForValue = redisTemplateJson.opsForValue();
		
		Student student = opsForValue.get(name);
		
		if (student != null) {
			log.info("get [" + name + "] from redis");
			return student;
		}
		
		log.info("get [" + name + "] from h2");
		student = studentMapper.findByName(name);
		opsForValue.set(name, student);
		
		return student;
		
	}

 

源码

Fork me on Gitee

 

转载于:https://my.oschina.net/tita/blog/3061387

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值