java中實現MongoDB主鍵自增
阿新 • • 發佈:2018-12-19
java中實現MongoDB主鍵自增
1.定義序列實體類SeqInfo: 儲存每個集合的ID記錄
//@Document 把一個java類宣告為mongodb的文件,可以通過collection引數指定這個類對應的文件
@Document(collection = "sequence")
public class SeqInfo {
@Id
private String id;//主鍵
private Long seqId;//序列值
private String collName;//集合名稱
...
...
2.自定義註解:AutoIncKey
//標識註解:標識主鍵ID需要自動增長
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIncKey {
}
3.定義自動增長ID的監聽器: 在儲存物件時,通過反射方式為其生成ID
//@Component泛指元件,把SaveEventListener 加入容器
@Component
public class SaveEventListener extends AbstractMongoEventListener<Object> {
@Autowired
MongoTemplate mongo;
@Override
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
final Object source = event.getSource();
if (source != null) {
ReflectionUtils.doWithFields(source.getClass(),new ReflectionUtils.FieldCallback(){
@Override
public void doWith(Field field)throwsIllegalArgumentException,
IllegalAccessException {
//將一個欄位設定為可讀寫,主要針對private欄位;
ReflectionUtils.makeAccessible(field);
// 如果欄位添加了我們自定義的AutoValue註解
if (field.isAnnotationPresent(AutoIncKey.class)
&& field.get(source) instanceof Number
&& field.getLong(source) == 0) {
// 設定自增ID
field.set(source, getNextAutoId(source.getClass().getSimpleName()));
}
}
});
}
}
/*1.8 以前實現方法如下
@Override
public void onBeforeConvert(final Object source) {
if (source != ) {
ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws
IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(field);
// 如果欄位添加了我們自定義的AutoIncKey註解
if (field.isAnnotationPresent(AutoIncKey.class)) {
// 設定自增ID
field.set(source, getNextAutoId(source.getClass().getSimpleName()));
}
}
});
}
}*/
// 獲取下一個自增ID
private Long getNextAutoId(String collName) {
Query query = new Query(Criteria.where("collName").is(collName));
Update update = new Update();
update.inc("seqId", 1);
FindAndModifyOptions options = new FindAndModifyOptions();
options.upsert(true);
options.returnNew(true);
SeqInfo seq = mongo
.findAndModify(query, update, options, SeqInfo.class);
return seq.getSeqId();
}
}
4.定義測試的實體類以及資料訪問類
@Document(collection = "user")
public class User {
@AutoIncKey
@Id
public long id;
@Field
public String name;
@Field
public int age;
public User(String name,int age){
this.name = name;
this.age = age;
}
...
public interface UserRepository extends MongoRepository<User, String> {
}
5.測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootMongodbApplicationTests {
@Autowired
UserRepository userRepository;
@Test
public void test(){
userRepository.deleteAll();
User user1 = new User("Helen", 18);
User user2 = new User("Steven", 18);
userRepository.save(user1);
userRepository.save(user2);
System.out.println("Helen的id: "+user1.getId());
System.out.println("Steven的id: "+user2.getId());
}
}
6.參考