SpringBoot Mongodb重新封装自增ID(数值)

目的是还原JpaRepository中的自增ID设置

1、自定义注解:@GeneratedValue

2、定义枚举GenerationType, 用于选择ID赋值的类型(本文章并未真正使用,可作为拓展功能)

3、重写监听事件里面的方法,而进行某些处理,该类需要继承AbstractMongoEventListener类,

注意这里定义的集合中Id默认都是数值类型, 如果需要使用ObjectId则需要过滤集合。

@Slf4j
@Configuration
@RequiredArgsConstructor
public class NosqlIdConfig extends AbstractMongoEventListener<Object> {

    private final MongoTemplate mongoTemplate;

    @PostConstruct
    public void init(){
        log.info("文档型数据库开始初始化所有集合Id......");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Set<String> collectionNames = mongoTemplate.getCollectionNames();
                for (String collectionName : collectionNames) {
                    long count = mongoTemplate.count(new Query(), collectionName);
                    Long id = 0L;
                    if (count > 0){
                        List<Map> maps = mongoTemplate.findAll(Map.class, collectionName);
                        for (Map map : maps) {
                            Long src = (Long) map.get("_id");
                            if (src.longValue() > id.longValue()){
                                id = src;
                            }
                        }
                    }
                    identity.put(collectionName, id);
                }
                log.info("文档型数据库所有集合Id初始化成功: {}", identity);
            }
        });
        thread.setName("Document");
        thread.start();
    }

    @PreDestroy
    public synchronized void destory(){
        identity.clear();
    }

    private static Map<String, Long> identity = new LinkedHashMap<>();

    @Override
    public synchronized void onBeforeConvert(BeforeConvertEvent<Object> event) {
        Object source = event.getSource();
        Class<?> sourceClass = source.getClass();
        if (!sourceClass.isAnnotation()){
            super.onBeforeConvert(event);
        }
        Document document = sourceClass.getAnnotation(Document.class);
        if (null != source) {
            ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
                @Override
                public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                    ReflectionUtils.makeAccessible(field);
                    if (field.isAnnotationPresent(GeneratedValue.class)) {
                        Object value = field.get(source);
                        if (value == null) {
                            field.set(source, getAutoId(document.collection()));
                        }else {
                            field.set(source, value);
                        }
                    }
                }
            });
        }
    }

    private Long getAutoId(String collectionName){
        Long id = 0L;
        boolean exist = identity.containsKey(collectionName);
        if (exist){
            id = identity.get(collectionName) + 1L;
        }else {
            id = 1L;
        }
        identity.put(collectionName, id);
        return id;
    }

}
4、自定义注解:@EnableMongodb
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({NosqlIdConfig.class})
public @interface EnableMongodb {

}

5、在工程中应用只需使用注解@EnableMongodb便可将自定义配置生效,注意需要在文档对象的Id字段上加上@GeneratedValue方可生效

@EnableMongodb
@EnableMinio
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值