spring-data-mongodb之自增ID实现
时间:2022-05-06
本文章向大家介绍spring-data-mongodb之自增ID实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
来源:猿天地
链接:http://cxytiandi.com/blog/detail/1897
用了mongodb之后要是问我mongo和mysql的区别在哪里?第一点我就会想到的是没有自增ID,mongo里面是ObjectId。今天我们就自己来实现自增的ID。
像mysql这种数据库是内部实现了自增ID,今天我们要自己实现一个,不知道大家有没有具体的思路。
当然mongodb官网上也提供了一种实现的方法,就是自定义一个获取自增ID的方法,然后每次插入的时候就去获取下一个ID,再插入到集合中。
我们既然用了spring-data-mongodb这个框架,就要基于这个框架来实现一套逻辑,而且每次插入都要自己去手动的调用方法获取一次ID,是不是太繁琐了。
我们用的是监听的模式,在数据插入到集合之前,我们通过反射将ID设置到保存的对象中,来实现自动设置,对写代码的人来说完全透明。
首先我们定义一个用于存储每个集合的ID记录,记录每个集合的自增ID到了多少。
@Document(collection = "sequence")
public class SequenceId {
@Id
private String id;
@Field("seq_id")
private long seqId;
@Field("coll_name")
private String collName;
}
接下来定义我们测试的实体类,注意自增ID的类型不要定义成Long这种包装类,mongotemplate的源码里面对主键ID的类型有限制。
@Documentpublic class Student {
@GeneratedValue
@Id
private long id;
private String name;
}
下面我们定义个注解来标识此字段要自动增长ID,有些场景下可能不需要自动增长,需要自动增长的时候我们加上这个注解。
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface GeneratedValue {
}
接下来就是实现自动注入ID的监听器了,需要配置让spring管理
<bean class="com.cxytiandi.mongo.autoid.SaveMongoEventListener"></bean>
public class SaveMongoEventListener extends AbstractMongoEventListener<Object> {
@Resource
private MongoTemplate mongoTemplate; @Override
public void onBeforeConvert(final Object source) {
if(source != null) {
ReflectionUtils.doWithFields(source.getClass(),
new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { ReflectionUtils.makeAccessible(field); if (field.isAnnotationPresent(GeneratedValue.class)) { //设置自增ID
field.set(source, getNextId(source.getClass().getSimpleName()));
}
}
});
}
}
/**
* 获取下一个自增ID
* @author yinjihuan
* @param collName 集合名
* @return
*/
private Long getNextId(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);
SequenceId seqId = mongoTemplate.findAndModify(query, update, options, SequenceId.class); return seqId.getSeqId();
}
}
findAndModify()是原子操作,所以不用担心并发问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Vue之插槽Slot理解
- Docker六脉神剑 (三) 编写Dockerfile构建nginx镜像并推送到远程仓库给其他人使用
- 快速学习UML类图查看
- 设计模式 | 抽象工厂模式
- 设计模式 | 单例模式
- macOS 安装软件已损坏无法打开解决办法 (真好用!)
- nginx 配置反向代理
- ES6新特性速查表
- React-Native Android打包
- React-Native iOS打包
- Webpack+Babel手把手带你搭建开发环境(内附配置文件)
- Redux 异步解决方案2. Redux-Saga中间件
- Redux异步解决方案 1. Redux-Thunk中间件
- 深度学习Pytorch检测实战 - Notes - 第1&2章 基础知识
- Java多线程编程在JMeter中应用