在 mongo 文档中创建一个自动递增字段
creating an auto increment field within a mongo document
在我的 Spring 引导应用程序中,我使用 Spring-Data MongoDB,并且我有一个代表用户的简单 POJO:
@EqualsAndHashCode
public class User implements Storable {
@Id
public ObjectId id;
@Getter @Setter public String firstName;
@Getter @Setter public String lastName;
@Getter @Setter public long userNum;
@DBRef(lazy = true)
@Getter @Setter public List<Section> sections = new ArrayList<Section>();
...
rest of class omitted
...
}
我的 UserController 看起来像这样:
@Controller
public class UserController {
@Autowired
UserRepository repository;
@ModelAttribute("allSections")
public List<Section> getSections() {
return sectionRepository.findAll();
}
@RequestMapping(value = "/users/new", method = RequestMethod.POST)
public String newUser(@ModelAttribute("user") User user) {
User newUser = new User();
newUser.userNum = user.userNum;
newUser.firstName = user.firstName;
newUser.lastName = user.lastName;
newUser.sections = user.sections;
newUser = repository.save(newUser);
for (Section section : newUser.sections) {
section.addToUsers(newUser);
sectionRepository.save(section);
}
return "redirect:/users";
}
... rest of controller omitted
}
请注意,我要自动生成的字段不是 ID 字段。
我希望 userNum
属性自动递增,这样创建并存储在数据库中的第一个用户对象从某个值开始...比如 9000,之后创建的每个用户都会递增1.
我有哪些选择可以做到这一点?我见过使用 JPA 的 @GeneratedValue 的示例,其他示例依赖于自定义 Mongo 查询来创建序列集合,但我都无法正常工作...
创建计数器集合:
public class Counter {
@Id
private String id;
private long seq;
public Counter(String id, long seq) {
this.id = id;
this.seq = seq;
}
// Getters and setters
}
然后是一个 MongoRepository:
@Repository
public interface CounterRepository extends MongoRepository<Counter, String> {}
还有一个Service/DAO:
@Service
public class CounterServiceImpl implements CounterService {
@Autowired
private CounterRepository counterRepository;
@Override
public long getNext(String sequenceId) {
Counter counter = counterRepository.findOne(sequenceId);
long id = counter.getSeq();
counter.setSeq(id + 1);
counterRepository.save(counter);
return id;
}
}
好的,我已经弄明白了,这就是我实现它的方式:
class for userNum,这是一个简单的POJO
public class UserNum {
@Id
private ObjectId id;
@Getter
@Setter
public long seq;
public UserNum(long seq) {
this.seq = seq;
}
}
UserNumRepository 有一个方法定义了 returns 保存到集合中的最后一个 UserNum
@Repository
public interface UserNumRepository extends MongoRepository<UserNum, String> {
UserNum findTopByOrderByIdDesc();
}
UserNumService 简单地找到序列中的最后一个数字并创建下一个数字,然后保存它和 returns 该数字。 UserNumService 是具有一个方法签名的接口。这创建了所有已创建和使用的 userNums 的集合。
@Service
public class UserNumServiceImpl implements UserNumService {
@Autowired
private UserNumRepository userNumRepository;
@Override
public long getNext() {
UserNum last = userNumRepository.findTopByOrderByIdDesc();
long lastNum = last.seq;
UserNum next = new UserNum(lastNum + 1);
userNumRepository.save(next);
return next.seq;
}
}
在 Application.java 中,您可以使用起始编号或从 mongo shell.
为集合播种
@Autowired UserNumRepository userNumRepository;
public void run(String... args) throws Exception {
userNumRepository.deleteAll();
// start the sequence at 9000
userNumRepository.save(new UserNum(9000));
}
现在您终于可以在需要发出新的 userNum 时简单地使用该服务,也许在构造函数中。
在我的 Spring 引导应用程序中,我使用 Spring-Data MongoDB,并且我有一个代表用户的简单 POJO:
@EqualsAndHashCode
public class User implements Storable {
@Id
public ObjectId id;
@Getter @Setter public String firstName;
@Getter @Setter public String lastName;
@Getter @Setter public long userNum;
@DBRef(lazy = true)
@Getter @Setter public List<Section> sections = new ArrayList<Section>();
...
rest of class omitted
...
}
我的 UserController 看起来像这样:
@Controller
public class UserController {
@Autowired
UserRepository repository;
@ModelAttribute("allSections")
public List<Section> getSections() {
return sectionRepository.findAll();
}
@RequestMapping(value = "/users/new", method = RequestMethod.POST)
public String newUser(@ModelAttribute("user") User user) {
User newUser = new User();
newUser.userNum = user.userNum;
newUser.firstName = user.firstName;
newUser.lastName = user.lastName;
newUser.sections = user.sections;
newUser = repository.save(newUser);
for (Section section : newUser.sections) {
section.addToUsers(newUser);
sectionRepository.save(section);
}
return "redirect:/users";
}
... rest of controller omitted
}
请注意,我要自动生成的字段不是 ID 字段。
我希望 userNum
属性自动递增,这样创建并存储在数据库中的第一个用户对象从某个值开始...比如 9000,之后创建的每个用户都会递增1.
我有哪些选择可以做到这一点?我见过使用 JPA 的 @GeneratedValue 的示例,其他示例依赖于自定义 Mongo 查询来创建序列集合,但我都无法正常工作...
创建计数器集合:
public class Counter {
@Id
private String id;
private long seq;
public Counter(String id, long seq) {
this.id = id;
this.seq = seq;
}
// Getters and setters
}
然后是一个 MongoRepository:
@Repository
public interface CounterRepository extends MongoRepository<Counter, String> {}
还有一个Service/DAO:
@Service
public class CounterServiceImpl implements CounterService {
@Autowired
private CounterRepository counterRepository;
@Override
public long getNext(String sequenceId) {
Counter counter = counterRepository.findOne(sequenceId);
long id = counter.getSeq();
counter.setSeq(id + 1);
counterRepository.save(counter);
return id;
}
}
好的,我已经弄明白了,这就是我实现它的方式:
class for userNum,这是一个简单的POJO
public class UserNum {
@Id
private ObjectId id;
@Getter
@Setter
public long seq;
public UserNum(long seq) {
this.seq = seq;
}
}
UserNumRepository 有一个方法定义了 returns 保存到集合中的最后一个 UserNum
@Repository
public interface UserNumRepository extends MongoRepository<UserNum, String> {
UserNum findTopByOrderByIdDesc();
}
UserNumService 简单地找到序列中的最后一个数字并创建下一个数字,然后保存它和 returns 该数字。 UserNumService 是具有一个方法签名的接口。这创建了所有已创建和使用的 userNums 的集合。
@Service
public class UserNumServiceImpl implements UserNumService {
@Autowired
private UserNumRepository userNumRepository;
@Override
public long getNext() {
UserNum last = userNumRepository.findTopByOrderByIdDesc();
long lastNum = last.seq;
UserNum next = new UserNum(lastNum + 1);
userNumRepository.save(next);
return next.seq;
}
}
在 Application.java 中,您可以使用起始编号或从 mongo shell.
为集合播种@Autowired UserNumRepository userNumRepository;
public void run(String... args) throws Exception {
userNumRepository.deleteAll();
// start the sequence at 9000
userNumRepository.save(new UserNum(9000));
}
现在您终于可以在需要发出新的 userNum 时简单地使用该服务,也许在构造函数中。