亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

具有復雜密鑰的 SpringData Redis 存儲庫

具有復雜密鑰的 SpringData Redis 存儲庫

慕森卡 2024-01-05 14:40:29
CrudRepository我們嘗試在項目中使用 Spring Data來為域對象提供持久性。首先,我選擇 REDIS 作為后端,因為在第一次實驗中CrudRepository<ExperimentDomainObject, String>,它的運行似乎很容易。當嘗試將其放入我們的生產代碼中時,事情變得更加復雜,因為這里我們的域對象不需要使用簡單類型作為密鑰,因此存儲庫是CrudRepository<TestObject, ObjectId>.現在我得到了例外:找不到能夠從類型 [...ObjectId] 轉換為類型 [byte[]] 的轉換器尋找這個異常,這個答案導致我對RedisTemplate配置進行了未經教育的實驗。(對于我的實驗,我使用的是 emdedded-redis)我的想法是,提供一個RedisTemplate<Object, Object>而不是RedisTemplate<String, Object>允許使用Jackson2JsonRedisSerializerkeySerializer 來完成工作。盡管如此,調用還是testRepository.save(testObject)失敗。請看我的代碼:為了簡潔起見,我有公共字段并省略了導入。如果需要它們(使其成為 MVCE),我將很樂意提供它們。請給我留言。依賴項:dependencies {    implementation 'org.springframework.boot:spring-boot-starter-data-redis'    implementation 'org.springframework.boot:spring-boot-starter-web'    compileOnly 'org.projectlombok:lombok'    annotationProcessor 'org.projectlombok:lombok'    implementation group: 'redis.clients', name: "jedis", version: '2.9.0'    implementation group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'}Redis配置:@Configuration@EnableRedisRepositoriespublic class RedisConfiguration {    @Bean    JedisConnectionFactory jedisConnectionFactory() {        return new JedisConnectionFactory();    }}不是想要的答案:當然,我可能會引入一些特殊的 ID,它是一種簡單的數據類型,例如我使用 jacksons ObjectMapper 手動構建的 JSON-String,然后使用CrudRepository<TestObject, String>.同時我也嘗試過:RedisTemplate<String, String>RedisTemplate<String, Object>自動裝配 aRedisTemplate并設置其默認序列化器注冊一個Converter<ObjectId, byte[]>到自動裝配的ConverterRegistry一個自動接線GenericConversionService,但顯然他們是錯誤的。
查看完整描述

1 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

基本上,Redis 存儲庫使用RedisKeyValueTemplate底層將數據存儲為鍵(Id)和值對。所以除非你直接使用它,否則你的配置RedisTemplate將不起作用。


因此,您的一種方法是RedistTemplate直接使用,這樣的東西對您有用。


@Service

public class TestService {


    @Autowired

    private RedisTemplate redisTemplate;


    public void saveIt(TestObject testObject){

        ValueOperations<ObjectId, TestObject> values = redisTemplate.opsForValue();

        values.set(testObject.testId, testObject);

    }


}

因此,上面的代碼將使用您的配置并使用 Jackson 作為鍵和值的映射器在 Redis 中生成字符串對。


但是,如果您想通過以下方式使用 Redis 存儲庫,則需要為from 和 toCrudRepository創建讀寫轉換器,并將它們注冊為自定義 Redis 轉換。ObjectIdStringbyte[]


ObjectId因此,讓我們為<->創建讀寫轉換器String


讀者


@Component

@ReadingConverter

@Slf4j

public class RedisReadingStringConverter implements Converter<String, ObjectId> {


    private ObjectMapper objectMapper = new ObjectMapper();


    @Override

    public ObjectId convert(String source) {

        try {

            return objectMapper.readValue(source, ObjectId.class);

        } catch (IOException e) {

            log.warn("Error while converting to ObjectId.", e);

            throw new IllegalArgumentException("Can not convert to ObjectId");

        }

    }

}

作家


@Component

@WritingConverter

@Slf4j

public class RedisWritingStringConverter implements Converter<ObjectId, String> {


    private ObjectMapper objectMapper = new ObjectMapper();


    @Override

    public String convert(ObjectId source) {

        try {

            return objectMapper.writeValueAsString(source);

        } catch (JsonProcessingException e) {

            log.warn("Error while converting ObjectId to String.", e);

            throw new IllegalArgumentException("Can not convert ObjectId to String");

        }

    }

}

以及 ObjectId <-> byte[] 的讀寫轉換器


作家


@Component

@WritingConverter

public class RedisWritingByteConverter implements Converter<ObjectId, byte[]> {


    Jackson2JsonRedisSerializer<ObjectId> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(ObjectId.class);


    @Override

    public byte[] convert(ObjectId source) {

        return jackson2JsonRedisSerializer.serialize(source);

    }

}

讀者


@Component

@ReadingConverter

public class RedisReadingByteConverter implements Converter<byte[], ObjectId> {


     Jackson2JsonRedisSerializer<ObjectId> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(ObjectId.class);


    @Override

    public ObjectId convert(byte[] source) {

        return jackson2JsonRedisSerializer.deserialize(source);

    }

}

最后添加 Redis 自定義對話。只需將代碼放入RedisConfiguration


@Bean

public RedisCustomConversions redisCustomConversions(RedisReadingByteConverter readingConverter,

                                                     RedisWritingByteConverter redisWritingConverter,

                                                     RedisWritingStringConverter redisWritingByteConverter,

                                                     RedisReadingStringConverter redisReadingByteConverter) {

    return new RedisCustomConversions(Arrays.asList(readingConverter, redisWritingConverter, redisWritingByteConverter, redisReadingByteConverter));

}

因此,現在在創建轉換器并將其注冊為自定義 Redis 轉換器后,您RedisKeyValueTemplate可以使用它們,并且您的代碼應該按預期工作。


查看完整回答
反對 回復 2024-01-05
  • 1 回答
  • 0 關注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號