SpringBoot+mongoDB实现id自增
这段时间给朋友做了一个微信小程序,顺便练习一下spring boot,虽然项目使用的是JPA+MySQL,但是好奇尝试了一下MongoDB实现自增ID,虽然MongoDB很少有自增ID的需求(在分布式环境中,多个机器同步一个自增ID不但费时且费力,MongoDB从一开始就是设计用来做分布式数据库的,处理多个节点是一个核心要求,而ObjectId在分片环境中要容易生成的多),但是需求是多变的,难免会遇到需要自增的需求。

MongoDB有默认的ObjectId,是一个12字节的 BSON 类型字符串。按照字节顺序,依次次代表:
- 4字节:UNIX时间戳
- 3字节:表示运行MongoDB的机器
- 2字节:表示生成此_id的进程
- 3字节:由一个随机数开始的计数器生成的值
Spring boot中可以使用MongoTemplate操作MongoDB,但是不能自增ID,只能手动实现:
1).自定义注解用于标识需要自增的Field.
package com.example.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIncKey {}
2).创建数据表存储当前的id号
id的自增进度需要一个数据表存储(只是存储当前id号数据,可以不用数据库而用其他形式)
@Document(collection = "inc")
public class IncInfo {
@Id
private String id;// 主键
@Field
private String collName;// 需要自增id的集合名称(这里设置为MyDomain)
@Field
private Integer incId;// 当前自增id值
// 省略getter、setter
3).实现监听类
监听器用于监听Mongo Event,该类继承AbstractMongoEventListener类,因为我们需要在JAVA对象转换成数据库对象的时候操作id字段实现id自增,所以覆盖onBeforeConvert方法(详见spring-data文档,https://docs.spring.io/spring-data/data-document/docs/current/reference/html/,5.11节)
package com.example.listener;
import java.lang.reflect.Field;
import com.example.annotation.AutoIncKey;
import com.example.domain.MyDomain;
import com.example.domain.IncInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
@Component
public class SaveEventListener extends AbstractMongoEventListener<Object>{
private static final Logger logger= LoggerFactory.getLogger(SaveEventListener.class);
@Autowired
private MongoTemplate mongo;
@Override
public void onBeforeConvert(BeforeConvertEvent<Object> event) {
logger.info(event.getSource().toString());
MyDomain source=(MyDomain)event.getSource();
if (source != null) {
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, getNextId(source.getClass().getSimpleName()));
}
}
});
}
}
private Integer getNextId(String collName) {
Query query = new Query(Criteria.where("collName").is(collName));
Update update = new Update();
update.inc("incId", 1);
FindAndModifyOptions options = new FindAndModifyOptions();
options.upsert(true);
options.returnNew(true);
IncInfo inc= mongo.findAndModify(query, update, options, IncInfo.class);
return inc.getIncId();
}
}
4).在我们的对象中id字段上添加注解
@Id
@AutoIncKey
private Integer id=0;
至此就实现了Mongodb的自增id。
SpringBoot+mongoDB实现id自增的更多相关文章
- SpringBoot+MongoDB实现物流订单系统
码字不易,点赞收藏,养成习惯!原创作者公众号:bigsai.更多精彩期待与您分享!项目收录在github的MongoDB案例中,文章收录在回车课堂中如果没基础请看看前两篇(墙裂推荐)MongoDB从立 ...
- 【第十二章】 springboot + mongodb(复杂查询)
简单查询:使用自定义的XxxRepository接口即可.(见 第十一章 springboot + mongodb(简单查询)) 复杂查询:使用MongoTemplate以及一些查询条件构建类(Bas ...
- 第十二章 springboot + mongodb(复杂查询)
简单查询:使用自定义的XxxRepository接口即可.(见 第十一章 springboot + mongodb(简单查询)) 复杂查询:使用MongoTemplate以及一些查询条件构建类(Bas ...
- mongodb的安装与增删改查
mongodb是一款分布式的文件存储的数据库,注意这两个词,分布式和文件存储.mongodb支持复制和分片,可以合理的运用空间的大小,也可以达到容灾的目的.另外文件存储也是一个特点,抛弃了传统的表的概 ...
- 十四:SpringBoot-配置MongoDB数据库,实现增删改查逻辑
SpringBoot-配置MongoDB数据库,实现增删改查逻辑 1.MongoDB数据库 1.1 MongoDB简介 1.2 MongoDB特点 2.SpringBoot整合MongoDB 2.1 ...
- 【pymongo】mongodb cursor id not valid error
参考来源: http://stackoverflow.com/questions/10298354/mongodb-cursor-id-not-valid-error http://stackover ...
- Oracle 给表添加主键和使ID自增、触发器、创建结构一样的表
1.关于主键:在建表时指定primary key字句即可:create table test( id number(6) primary key, name varchar2(30));如果是对于已经 ...
- phpmyadmin设置id自增(AUTO_INCREMENT)(转)
phpmyadmin设置id自增(AUTO_INCREMENT) 在A_I 前面打勾:如图 AUTO_INCREMENT =A_I 查看效果
- hibernate解决oracle的id自增?
以前做SSH项目时,涉及到的数据库是mySQL,只需将bean的配置文件id设为native 就可以实现表id的自增. 现在用到了Oracle,当然知道这样是不行的啦,那么用序列自增? 我在网络上搜索 ...
随机推荐
- pytest学习5-mark用例分类
使用Mark标记测试用例 通过使用pytest.mark你可以轻松地在测试用例上设置元数据.例如, 一些常用的内置标记: skip - 始终跳过该测试用例 skipif - 遇到特定情况跳过该测试用例 ...
- linq和扩展方法
c#的扩展方法 1.必须是在一个非嵌套.非泛型的静态类中的静态方法 2.至少一个参数,第一个参数附加this,不能有其他修饰符如out.ref 3.第一个参数不能是指针类型 上面例子是自定义的一个扩展 ...
- JS高级---函数作为返回值使用
函数作为返回值使用 function f1() { console.log("f1函数开始"); return function () { console.log("函数 ...
- 利用Python数据分析基础
一.Numpy的ndarray:一种多维数组 ndarray是一个通用的同构多维数据容器,其所有元素必须是相同的类型.每个数组都有一个shape(一个表示各维度的元组)和dtype(一个用于说明数据数 ...
- Vue(二)
---恢复内容开始--- 1.vue条件指令 可以运行加减运算 可以进行if判断 <!DOCTYPE html> <html> <head> <meta ch ...
- Django中间件,CSRF(跨站请求伪造),缓存,信号,BootStrap(模板)-响应式(栅格)+模板
Django中间件,CSRF(跨站请求伪造),缓存,信号,BootStrap(模板)-响应式(栅格)+模板 1.中间件(重要): 在Django的setting中有个MIDDLEWARE列表,里面的东 ...
- mysql 实践(例题)
MySQL安装见本博 安装成功后,开始菜单中找到 “MySQL 8.0 Command Line Client” 进行启动(启动后,可直接输入MySQL密码) 1. create database 数 ...
- 题解【SP1716】GSS3 - Can you answer these queries III
题目描述 You are given a sequence \(A\) of \(N (N <= 50000)\) integers between \(-10000\) and \(10000 ...
- 题解【洛谷P1038/CJOJ1707】[NOIP2003提高组]神经网络
[NOIP2003]神经网络 Description 问题背景:人工神经网络( Artificial Neural Network )是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款 ...
- 问题总结:mysql和javaweb工程连接的过程中容易产生的问题
问题背景:自己在本机的mysql8瘫痪了,将Oracle中的数据迁移到mysql之后,配置好javaweb工程和虚拟机上的远程Mysql连接的文件之后:遇见了无法访问的问题 具体的配置: dataso ...