对于给定的id
这是我的主键,如果id
已经存在,我想将数据追加到List类型,如果不存在,那么我想创建新的List。
这是我的空中加薪模式-
Column1: columnname=id; columntype=Integer; columnconstraint=primarykey
Column2: columnname=mylist; columntype=List<String>
下面是我的POJO:
public class AeroSpikeModel {
@Id
private Integer id;
private List<String> myList = new ArrayList<>();
//getter and setter
}
这是我的DAO:
@Component
public class MyDAO {
@Autowired
private AerospikeRepository<AeroSpikeModel, Integer> aerospikeRepository;
public void save(List<AeroSpikeModel> model) {
aerospikeRepository.save(model);
}
public AeroSpikeModel get(Integer id) {
return aerospikeRepository.findOne(id);
}
}
问题是,每次我插入现有的id
时,它都会覆盖列表,而不是追加到现有列表中。我如何实现相同的目标,因为Aerospike原生支持追加到列表
@Document
注释的类别是用于将任何数据保存到存储中的通用实体,因此它不使用特定于数据类型的操作。
如果要直接使用列表,则应该暂时使用原始的Aerospike客户端API。这是一个如何在Java中完成此操作的示例:https://github.com/aerospike/aerospike-client-java/blob/master/examples/src/com/aerospike/examples/OperateList.java#L53
[还有另一种使用spring-data-aerospike
的解决方案,但是它不能像直接使用列表追加操作那样有效,因为您首先需要检索数据,对其进行修改然后保存。
import lombok.Builder;
import lombok.Data;
import org.springframework.data.aerospike.mapping.Document;
@Document
@Data
@Builder(toBuilder=true)
public static class MyDocument {
@Id
public final long id;
public final Set<String> items;
public final String someString;
// Stores document version in this field.
// In Aerospike terms it is referred to as generation.
// Without this field CAS (compare-and-set) algorithm won't take place in spring-data
@Version
public long version;
public static class MyDocumentBuilder {
public MyDocumentBuilder addItem(String item) {
this.items.add(item);
return this;
}
}
}
import org.springframework.data.aerospike.repository.AerospikeRepository;
public interface MyDocumentRepository extends AerospikeRepository<MyDocument, Long> {
}
import lombok.RequiredArgsConstructor;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.retry.annotation.Retryable;
@RequiredArgsConstructor
public class MyDocumentService {
private final MyDocumentRepository repo;
// in case version of the document was modified on server --
// we will need to retry our operation from the beginning
@Retryable(OptimisticLockingFailureException.class)
public boolean addToCollection(Long id, String itemToAdd) {
return repo.findById(id)
.map(found -> updateAndSave(found, itemToAdd))
.orElse(false);
}
private boolean updateAndSave(MyDocument existing, String itemToAdd) {
MyDocument updated = existing.toBuilder()
.addItem(itemToAdd)
.build();
repo.save(updated);
}
}
我添加了@Version
字段和@Retryable
,以便在服务器上同时运行多个更新的情况下,您不会丢失某些更新。该算法称为CAS(您可以在此处阅读有关此信息的更多信息:What is CAS in NoSQL and how to use it?)