【Mongodb】后台主键_id自增(Java版本)
ObjectId的选择
创建MongoDB文档时,如果没有赋值ID,系统会自动帮你创建一个,通常会在客户端由驱动程序完成。得到的ObjectId类似于这种
ObjectId使用12字节的存储空间,每个字节两位十六进制数字,是一个24位的字符串。其含义分别代表时间戳、机器码、PID、计数器。时间戳是文档创建时的时间,只是从十进制转化成了十六进制。机器码是生成文档主机的ID,为了区分多主机而生成的。PID则是区分同主机下不同mongoDB进程产生的,同样防止冲突。前面的9个字节是保证了一秒内不同机器不同进程生成ObjectId不冲突,最后的3个字节是一个自动增加的计数器,用来确保在同一秒内产生的ObjectId也不会冲突,允许256的3次方等于16777216条记录的唯一性。
显然系统生成的ObjectID已经很严谨了,但是在选择系统创建还是程序创建id上,经过网上查找的一些资料,得到的结论是尽量采用程序创建的方式,速度、可读性、可维护性都要强于系统创建。
虽然ObjectId 设计成轻量型的,易于生成,但是毕竟生成的时候还是产生开销。在客户端生成体现了MongoDB 的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。这种理念背后的原因是,即便是像MongoDB 这样的可扩展数据库,扩展应用层也要比扩展数据库层容易得多。将事务交由客户端来处理,就减轻了数据库扩展的负担。
在客户端生成ObjectId,驱动程序能够提供更加丰富的API。例如,驱动程序可以有自己的insert 方法,可以返回生成的ObjectId,也可以直接将其插入文档。如果驱动程序允许服务器生成ObjectId,那么将需要单独的查询,以确定插入的文档中的"_id" 值。
设计思路
创建一个序列计数的文档,记录所有文档的名称和序列值,序列值设置默认0,每次进行插入操作的时候,序列值+1,作为本次操作的id。
程序实现
开发环境:IntelliJ IDEA+JAVA8+SpringBoot
1 创建序列计数类,用于存储各文档以及文档序列值。

2 自定义注解

3 定义实体类,自己要实现自增的实体类(get、set),与文档一一对应

4 定义监听类SaveEventListener。重写save方法。在每次存储时候进行主键自增

5.然后测试(中间的111113删除掉了)

注意
如果根据主键查询的话要进行转化:

到此,MongoDB的主键自增就完成了。
总结
经过测试,以上流程没有问题,会得到期望的结果,但是有以下几点需要注意:
(1)为什么我在Student类中为主键赋了一个默认值0L?
答:我在此自增方式原作者文章中发现这么一句,“注意自增ID的类型不要定义成Long这种包装类,mongotemplate的源码里面对主键ID的类型有限制”。测试后发现,如果ID定义为原生类型确实是没有问题的。当ID定义为包装类的情况下,如果在onBeforeConvert方法之前没有给ID设置值,是会报错的,我猜测可能是因为内部转换类型时如果ID是空值而无法转换引起的,因此,我赋了一个默认值,这样就不会报错了,包装类也可以使用(不过这样好像跟原生类型就没什么区别了,没什么意义)。
(2)这个监听器会不会影响修改操作?
答:测试发现,不会影响,水平有限,本人也不知作何解释,不要打我……
(3)这种方式会有并发问题吗?
答:不会的!根据官方文档说明,findAndModify一个原子性操作,不过有这么一句“When the findAndModify command includes the upsert: true option and the query field(s) is not uniquely indexed, the command could insert a document multiple times in certain circumstances.”,大概意思是说当查询和更新两个操作都存在时,如果查询的字段没有唯一索引的话,该命令可能会在某些情况下更新/插入 文档多次,参考链接:戳我戳我。以上演示的是只存储了集合所对应的实体类的短名称,短名称是会重复的,所以这种方法不妥,还是记录长名称吧
菜鸟程序员,若有需修正之处,望指正~
参考文章:[代码与酒]https://blog.csdn.net/qq_16313365/article/details/72781469
【Mongodb】后台主键_id自增(Java版本)的更多相关文章
- 支付宝小程序serverless---插入数据后获取数据的主键_id(mongodb)
支付宝小程序serverless---插入数据后获取数据的主键_id(mongodb) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除, ...
- SqlServer 不是主键 如何自增
SqlServer 不是主键 如何自增:INSERT INTO dbo.表 VALUES('14-19周',0,(select COUNT(1) from dbo.表)+1) (select COUN ...
- SQL语句获取数据库中的表主键,自增列,所有列
SQL语句获取数据库中的表主键,自增列,所有列 获取表主键 1:SELECT TABLE_NAME,COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_U ...
- powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键
转自:https://www.cnblogs.com/CoffeeHome/archive/2014/06/04/3767501.html 这里powerdesigner连接的数据库是以mysql为例 ...
- 修改mysql表结构,添加一个主键索引自增字段,修改原来的主字段为普通字段
原来有一个字段id,为自增,主键,索引.现在要新增一个字段s_id为自增,主键,索引.同时把原来的主字段改成普通字段,默认值为0. Alter table e_diamond_jhds change ...
- EF 实体字段设置主键和自增
[Key] //主键 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] //设置自增 public int id { get; set; } ...
- SQL server 获得 表的主键,自增键
主键: @tableName --表名 @id ---表对应的id SELECT SYSCOLUMNS.name FROM SYSCOLUMNS,SYSOBJECTS,SYSINDEXES,SYSIN ...
- sqlserver修改主键为自增
使用PowerDesigner创建一张表, 拷贝建表语句发现ID不是自增的, 以下是修改语句: ALTER TABLE USER_JOB_EXE_REC DROP COLUMN id; , ); 注: ...
- sql server sql查询数据库的表,字段,主键,自增,字段类型等信息
1.查询数据表的属性(名称.说明.是否主键.数据类型.是否自增) SELECT t1.name columnName,case when t4.id is null then 'false' else ...
随机推荐
- JS 使用xlsx.core.js 数据导出到excel
/* 通用导出数据 需要引入 xlsx.core.js * data:数据 * th:表头 * filename:导出表格名称 */ var data = []; var th = [ [" ...
- 这次我让你彻底弄懂 RESTful
微信搜 「yes的练级攻略」干货满满,不然来掐我,回复[123]一份20W字的算法刷题笔记等你来领.欢迎分享,转载请保留出处. 本文已收录至 https://github.com/yessimida/ ...
- 老猿学5G:融合计费场景的Nchf_ConvergedCharging_Create、Update和Release融合计费消息交互过程
☞ ░ 前往老猿Python博文目录 ░ 一.Nchf_ConvergedCharging_Create交互过程 Nchf_ConvergedCharging_Create 服务为CTF向CHF请求提 ...
- 什么是Python迭代器?
迭代器(Iterator):迭代器可以看作是一个特殊的对象,每次调用该对象时会返回自身的下一个元素,从实现上来看,一个迭代器对象必须是定义了__iter__()方法和next()方法的对象. Pyth ...
- SpringCloud Alibaba学习笔记
目录 目录 目录 导学 为什么学 学习目标 进阶目标 思路 Spring Cloud Alibaba的重要组件 环境搭建 Spring Boot必知必会 Spring Boot特性 编写第一个Spri ...
- aspnetcore webapi 解决发布以后每隔一段时间请求变缓慢
项目:netcore webapi 3.1 平台:windows server 2008 r2 服务器:IIS 7.5 项目发布到IIS以后第一次请求特别慢大概7.8秒,然后每隔5分钟请求一次大概2. ...
- 【题解】AcWing 389. 直径
原题链接 题目描述 共两个问题,第一问求树的直径长度,第二问求直径的必须边 思路 第一问很好求,lyd书里有,就不再赘述. 这里建议使用两次bfs的方法,因为关系到第二问的路径,这么做比较方便. 然后 ...
- Codeforces Edu Round 55 A-E
A. Vasya and Book 简单的取余运用. #include <iostream> #include <cstdio> #include <limits.h&g ...
- 题解-洛谷P4139 上帝与集合的正确用法
上帝与集合的正确用法 \(T\) 组数据,每次给定 \(p\),求 \[\left(2^{\left(2^{\left(2^{\cdots}\right)}\right)}\right)\bmod p ...
- Linux文件权限问题
更改权限命令 chmod 常用参数 -R, --recursive change files and directories recursively (以递归的方式对目前目录下的所有档案与子目录进 ...