簡體   English   中英

使用 spring-data-redis 更新 redis 中的實體

[英]Update entity in redis with spring-data-redis

我目前正在將 Redis (3.2.100) 與 Spring data redis (1.8.9) 和 Jedis 連接器一起使用。 當我在現有實體上使用 save() 函數時,Redis 刪除我的實體並重新創建實體。

在我的情況下,我需要保留這個現有實體並且只更新實體的屬性。 (我有另一個線程同時讀取同一個實體)

在 Spring 文檔( https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis.repositories.partial-updates )中,我找到了部分更新功能。 不幸的是,文檔中的示例使用了 RedisTemplate 的 update() 方法。 但是這種方法不存在。

那么你有沒有使用過 Spring-data-redis 部分更新?

還有另一種方法可以在不刪除之前更新實體redis嗎?

謝謝

要獲取RedisKeyValueTemplate ,您可以執行以下操作:

@Autowired
private RedisKeyValueTemplate redisKVTemplate;

redisKVTemplate.update(實體)

您應該使用 RedisKeyValueTemplate 進行部分更新。

好吧,請考慮遵循文檔鏈接,並且彈簧數據測試( 鏈接)實際上對最終解決方案的貢獻為 0。

考慮以下實體

@RedisHash(value = "myservice/lastactivity")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class LastActivityCacheEntity implements Serializable {
    @Id
    @Indexed
    @Size(max = 50)
    private String user;
    private long lastLogin;
    private long lastProfileChange;
    private long lastOperation;
}

讓我們假設:

1) 我們不想在每次更新時都進行復雜的讀寫練習。

entity = lastActivityCacheRepository.findByUser(userId);
lastActivityCacheRepository.save(LastActivityCacheEntity.builder()
.user(entity.getUser())
.lastLogin(entity.getLastLogin())
.lastProfileChange(entity.getLastProfileChange())
.lastOperation(entity.getLastOperation()).build());

如果會彈出大約 100 行怎么辦? 然后在每個更新實體都必須獲取並保存,效率很低,但仍然可以解決。

2)我們實際上並不想要復雜的練習,使用opsForHash + ObjectMapper + 配置 bean 方法 - 很難實現和維護(例如鏈接

所以我們將使用類似的東西:

@Autowired
private final RedisKeyValueTemplate redisTemplate;

void partialUpdate(LastActivityCacheEntity update) {
  var partialUpdate = PartialUpdate
      .newPartialUpdate(update.getUser(), LastActivityCacheEntity.class);
  if (update.getLastLogin() > 0)
      partialUpdate.set("lastlastLogin", update.getLastLogin());
  if (update.getLastProfileChange() > 0)
      partialUpdate.set("lastProfileChange", update.getLastProfileChange());
  if (update.getLastOperation() > 0)
    partialUpdate.set("lastOperation", update.getLastOperation());
  redisTemplate.update(partialUpdate);
}

問題是 - 它不適用於這種情況。

也就是說,值得到更新,但您不能稍后通過存儲庫實體查找查詢新屬性:某些lastActivityCacheRepository.findAll()將返回未更改的屬性。

這是解決方案:

LastActivityCacheRepository.java

@Repository
public interface LastActivityCacheRepository extends CrudRepository<LastActivityCacheEntity, String>, LastActivityCacheRepositoryCustom {
    Optional<LastActivityCacheEntity> findByUser(String user);
}

LastActivityCacheRepositoryCustom.java

public interface LastActivityCacheRepositoryCustom {
    void updateEntry(String userId, String key, long date);
}

LastActivityCacheRepositoryCustomImpl.java

@Repository
public class LastActivityCacheRepositoryCustomImpl implements LastActivityCacheRepositoryCustom {
    @Autowired
    private final RedisKeyValueTemplate redisKeyValueTemplate;

    @Override
    public void updateEntry(String userId, String key, long date) {
        redisKeyValueTemplate.update(new PartialUpdate<>(userId, LastActivityCacheEntity.class)
            .set(key, date));
    }
}

最后工作示例:

void partialUpdate(LastActivityCacheEntity update) {
  if ((lastActivityCacheRepository.findByUser(update.getUser()).isEmpty())) {
      lastActivityCacheRepository.save(LastActivityCacheEntity.builder().user(update.getUser()).build());
  }
  if (update.getLastLogin() > 0) {
      lastActivityCacheRepository.updateEntry(update.getUser(),
          "lastlastLogin",
          update.getLastLogin());
  }
  if (update.getLastProfileChange() > 0) {
      lastActivityCacheRepository.updateEntry(update.getUser(),
          "lastProfileChange",
          update.getLastProfileChange());
  }
  if (update.getLastOperation() > 0) {
      lastActivityCacheRepository.updateEntry(update.getUser(),
          "lastOperation",
          update.getLastOperation());
}

所有功勞都歸功於Chris Richardson和他的src

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM