Spring data-mongodb ID自增长注解实现

作者 xqlee
浏览次数 81


1.创建一个文档。类似一个序列的作用

package com.leftso.autoid;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * 系统自增长表id存放表
 * 
 * @author xq
 *
 */
@Document(collection = "sys_sequence")
public class SequenceId {
	@Id
	private String id;

	@Field("seq_id")
	private long seqId;

	@Field("coll_name")
	private String collName;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public long getSeqId() {
		return seqId;
	}

	public void setSeqId(long seqId) {
		this.seqId = seqId;
	}

	public String getCollName() {
		return collName;
	}

	public void setCollName(String collName) {
		this.collName = collName;
	}

}

2.创建一个自定义注解用于处理需要自增长的ID

package com.leftso.autoid;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义自增长ID注解
 * 
 * @author xq
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface AutoValue {

}


3.重写新增的监听事件

注意:各大网站可能会有相似的代码。以下部分和spring data mongodb版本有关。下面代码中重写的public void onBeforeConvert(final Object source)方法在1.8版本开始就废弃了,不过官方推荐: Please use onBeforeConvert(BeforeConvertEvent),以下则为1.8以后版本的使用方法
package com.leftso.autoid;

import java.lang.reflect.Field;

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.BeforeSaveEvent;
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> {
	@Autowired
	private MongoTemplate mongo;

	@Override
	public void onBeforeSave(BeforeSaveEvent<Object> event) {
		Object source = event.getSource();
		if (source != null) {
			ReflectionUtils.doWithFields(source.getClass(), new ReflectionUtils.FieldCallback() {
				public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
					ReflectionUtils.makeAccessible(field);
					// 如果字段添加了我们自定义的AutoValue注解
					if (field.isAnnotationPresent(AutoValue.class) && field.get(source) instanceof Number
							&& field.getLong(source) == 0) {
						// field.get(source) instanceof Number &&
						// field.getLong(source)==0
						// 判断注解的字段是否为number类型且值是否等于0.如果大于0说明有ID不需要生成ID
						// 设置自增ID
						field.set(source, getNextId(source.getClass().getSimpleName()));

					}
				}
			});
		}
	}

	/**
	 * 获取下一个自增ID
	 * 
	 * @param collName
	 *            集合(这里用类名,就唯一性来说最好还是存放长类名)名称
	 * @return 序列值
	 */
	private Long getNextId(String collName) {
		Query query = new Query(Criteria.where("coll_name").is(collName));
		Update update = new Update();
		update.inc("seq_id", 1);
		FindAndModifyOptions options = new FindAndModifyOptions();
		options.upsert(true);
		options.returnNew(true);
		SequenceId seq = mongo.findAndModify(query, update, options, SequenceId.class);
		return seq.getSeqId();
	}
}


4.使用自定义注解完成ID自增长的实现

package com.leftso.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import com.leftso.autoid.AutoValue;

@Document
public class Student {
	@AutoValue
	@Id
	private long id;
	private String name;

	public Student(String name) {
		super();
		this.name = name;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

 
暂无评论
站内搜索
搜索
广而告之(广告说明)
加入QQ群(641395244)
qq group
支持博客发展
support
推荐博客
暂无推荐
分享本文