淘先锋技术网

首页 1 2 3 4 5 6 7

MongoDB默认的ObjectId确实有其积极意义,但是有时候需求却需要我们自定义id生成规则。

本文使用AOP注解的方式来实现id的自定义规则。

如果声明在id字段上,那它就是自定义的id。也可以声明在其他字段上,与ObjectId并存。

本文由作者三汪首发于简书。

原理分析

Spring Data MongoDB是有生命周期的。通过继承org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener

类来实现监听。

本文中产生id的动作在监听到onBeforeConvert时触发。

7个生命周期列举如下:

onBeforeConvert
onBeforeSave
onAfterSave
onAfterLoad
onAfterConvert
onAfterDelete
onBeforeDelete

通过自定义注解标识根据自定义规则赋值的字段。通过org.springframework.util.ReflectionUtils提供的反射功能来获取被自定义注解标识的字段

实现根据数据库中已存在的id生成新的id(自增),使用单例控制并发。

示例

注意:

本例中自定义的id规则为:年月日+序号。如:2017112801,2017112899

示例中没有对自定义id的长度做控制。因此会出现20171128100的情况。

如果需要做控制,请自行在保存方法中做校验。

本文中自定义id的类型为String。

根据所参考的博文作者的说法,自增ID的类型不能定义成Long这种包装类。

Mongotemplate的源码里面对主键ID的类型有限制。只能定义为原生类型。

代码:

KalmanDefine.java(实体类)

@Document

@Getter

@Setter

@NoArgsConstructor

public class KalmanDefine {

    @Id

    @ProjectCode

    private String code;//code字段在数据库中还是会以_id的名字存在

    
    @Field(value="name")

    private String name;

    //其余字段略

}

KalmanDefine.java(自定义注解类)


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 KalmanDefine {

}