如何在 mongodb 中保存字母数字序列并从 MongoDB 中最后保存的序列开始生成
我有一种方法可以根据特定模式生成字母数字序列。我想保存生成的序列,当下次我想生成一个新的序列时,它应该从最后保存的序列开始。我对这种情况有疑问,因为它是字母数字的。另外,我想将生成的 ID 放入 Excel 文件中。
下面的这两个方法检查它是否已经存在,并尝试获取最后保存的项目。
public Optional<Terminal> findByGeneratedTerminalIDs(String id){
return Optional.ofNullable(this.collection.findOne(Filters.eq("generatedTerminalID", id)));
}
public Optional<FindIterable<Terminal>> findLastGeneratedTerminalID(String generatedTerminalID) {
return Optional.ofNullable(this.collection.find(Filters.eq("generatedTerminalID", generatedTerminalID)).
sort(Sorts.descending("generatedTerminalID")).limit(1));
}
这是更新后的存储库
private JacksonMongoCollection<Sequence> collection;
public SequenceRepository(JacksonMongoCollection<Sequence> collection) {
this.collection = collection;
}
public Sequence save(Sequence sequence) {
collection.save(sequence);
return sequence;
}
public Sequence findAllSequences(Sequence sequence) {
return collection.find(Filters.eq("generatedTerminalID", sequence.getGeneratedTerminalID())).first();
}
public BaseResponsegenerateTerminalIDs(TerminalIDDTOterminalDto) {
Sequence sequence = new Sequence();
sequence.setNext(0);
sequenceRepository.save(sequence);
int totalLength = 8;
int numberOfIds = terminalDto.getNumberOfTerminals();
int countRemainingSymbols = totalLength - START.length();
//there should be only 1 row at all times
sequence = this.sequenceRepository.findAllSequences(sequence);
int start = sequence.getNext();//start generation of sequences from the value of next
int next = start + numberOfIds;//this will be next value of sequence.next
for (int i = start; i < next; i++) {
StringBuilder end = new StringBuilder();
int current = i;
int remainder = current % ALPHANUMERIC.length();//the index of next character
do {
end.append(ALPHANUMERIC.charAt(remainder));
current /= ALPHANUMERIC.length();//update to check if we need to add more characters
remainder = current % ALPHANUMERIC.length();//update index, only used if more chars are needed
} while (current > 0);
int padCount = countRemainingSymbols - end.length();
StringBuilder result = new StringBuilder(START).append("-");//- is for easier debugging, remove it for your case
for (int j = 0; j < padCount; j++) {
result.append("0");
}
result.append(end.reverse());
log.info("These are the values {}", result);
}
//update next value and save in db
sequence.setNext(next);
sequenceRepository.save(sequence);
return BaseResponse.builder().status(true).message("TerminalIDs have been generated").build();
}
我希望在我上面发布的方法中保存并检查它是否存在。最好的方法是什么?
I have a method that generates an alphanumeric sequence based on a particular pattern. I want to save the generated sequence and when next I want to generate a new one, it should start from the last saved one. I am having an issue with this happening because it is alphanumeric. Also, I want to put the generated IDs in an excel file.
These two methods below check if it already exists and also try to fetch the last item saved.
public Optional<Terminal> findByGeneratedTerminalIDs(String id){
return Optional.ofNullable(this.collection.findOne(Filters.eq("generatedTerminalID", id)));
}
public Optional<FindIterable<Terminal>> findLastGeneratedTerminalID(String generatedTerminalID) {
return Optional.ofNullable(this.collection.find(Filters.eq("generatedTerminalID", generatedTerminalID)).
sort(Sorts.descending("generatedTerminalID")).limit(1));
}
Here is the updated repository
private JacksonMongoCollection<Sequence> collection;
public SequenceRepository(JacksonMongoCollection<Sequence> collection) {
this.collection = collection;
}
public Sequence save(Sequence sequence) {
collection.save(sequence);
return sequence;
}
public Sequence findAllSequences(Sequence sequence) {
return collection.find(Filters.eq("generatedTerminalID", sequence.getGeneratedTerminalID())).first();
}
public BaseResponse generateTerminalIDs(TerminalIDDTO terminalDto) {
Sequence sequence = new Sequence();
sequence.setNext(0);
sequenceRepository.save(sequence);
int totalLength = 8;
int numberOfIds = terminalDto.getNumberOfTerminals();
int countRemainingSymbols = totalLength - START.length();
//there should be only 1 row at all times
sequence = this.sequenceRepository.findAllSequences(sequence);
int start = sequence.getNext();//start generation of sequences from the value of next
int next = start + numberOfIds;//this will be next value of sequence.next
for (int i = start; i < next; i++) {
StringBuilder end = new StringBuilder();
int current = i;
int remainder = current % ALPHANUMERIC.length();//the index of next character
do {
end.append(ALPHANUMERIC.charAt(remainder));
current /= ALPHANUMERIC.length();//update to check if we need to add more characters
remainder = current % ALPHANUMERIC.length();//update index, only used if more chars are needed
} while (current > 0);
int padCount = countRemainingSymbols - end.length();
StringBuilder result = new StringBuilder(START).append("-");//- is for easier debugging, remove it for your case
for (int j = 0; j < padCount; j++) {
result.append("0");
}
result.append(end.reverse());
log.info("These are the values {}", result);
}
//update next value and save in db
sequence.setNext(next);
sequenceRepository.save(sequence);
return BaseResponse.builder().status(true).message("TerminalIDs have been generated").build();
}
I want the saving and checking if it exists to be done in this method I posted above. What is the best way to go about it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将新表添加到数据库中。由于它对于整个数据库必须是唯一的,因此该表将保存一行,用于跟踪用于 id 生成的下一个整数。
我假设您使用 spring 数据,那么您的实体可能是这样的:
存储库:
假设您正在使用问题标签中的 mongo。
next 的初始值应该为零。
在适当的时候初始化并保存在数据库中,也许是应用程序启动时。只需执行一次此初始化即可。
那么生成方法可能是这样的:
这里有一些假设,但这是您应该遵循的整体算法。
重要提示:此解决方案没有考虑可能同时访问表的情况,这可能会导致 id 重复。如果您有这样的用例,您可能需要考虑:
generateTerminalIDs
执行期间锁定表,从而强制其他想要访问 next 的线程等待,直到生成所有 id。编辑: SaveAndFlush 相当于创建或更新。在 Spring 中,它以这种方式实现 - 如果实体具有 id 属性(在本例中为
sequence.id != null
),则执行更新,否则执行创建(插入)。对于您的情况,在初始化新表时创建行,在创建 ids 时更新它。关于 findAll() - 它返回一个包含表中所有行/实体的列表。这里
repository.findAll()
将返回List
。repository.findAll().get(0)
将返回Sequence
,即表中的第一行也是唯一行。You could do it adding a new table to db. Since it has to be unique for entire db, this table will hold a single row, which keeps track of next integer to use for id generation.
I'll assume you use spring data, then your entity could be something like this:
The repository:
Assuming you are using mongo from question tag.
Initial value for next should be zero.
Initialise and save in db at appropriate time, maybe app startup. Just do this initialization only once.
Then generation method might be like this:
There are some assumptions here, but this is the overall algorithm you should follow.
Important: This solution does not take into account possible simultaneous access to the table, which may lead to duplicating ids. If you have such use cases, you might want to consider:
generateTerminalIDs
execution, thus forcing other threads who want access for next to wait until all ids are generated.Edit: SaveAndFlush is equivalent for create or update. In spring it's implemented in this way - if entity has id property(
sequence.id != null
in this case), do an update, otherwise do create(insert). For your case, create the row when initializing new table, update it when ids are created.About
findAll()
- it returns a list with all rows/entites from a table. Hererepository.findAll()
will returnList<Sequence>
.repository.findAll().get(0)
will returnSequence
, the first and only row in the table.