MongoDB自增长主键,批量操作,distinct记录,条件组合查询

一,创建自增长主键

在 mongodb 的命令行终端,创建一个 collection 比如 sequence,然后插入一条记录:

MongoDB Enterprise > db.sequence.insert({_id:"userseq",seq:0})
WriteResult({ "nInserted" : 1 })

创建一个Service, 调用 mongodb 的一个 API,修改这个 sequence 里面的对象,并返回更改后的值作为程序即将保存的对象的 ID。

@Service
public class SequenceService {
	private Logger logger = LoggerFactory.getLogger(SequenceService.class);
	
	private static final String SEQ_COLLECTION = "sequence";
	private static final String PRIMARY_KEY = "_id";
	private static final String SEQUENCE_FIELD = "seq";
	
	@Autowired
	private MongoTemplate temp;
	
	public Integer getNextUserSeq(){
		Integer seq = getNextSequence("userseq");
		logger.info("getNextUserSeq() 的下一个值 ::: " + seq);
		return seq;
	}
	
	private Integer getNextSequence(String name) {
		DBObject ret = temp.getCollection(SEQ_COLLECTION).findAndModify(
				Query.query(Criteria.where(PRIMARY_KEY).is(name)).getQueryObject(), null, null, false,
				new Update().inc(SEQUENCE_FIELD, 1).getUpdateObject(), true, false);
		return ((Double) ret.get(SEQUENCE_FIELD)).intValue();
	}
}

注意, findAndModify 这个方法是重载的,如果 public DBObject findAndModify(final DBObject query, final DBObject update) 这个接口,将会返回修改前的值,比如值已经被这个接口从 4 改到 5 了,但是返回的却是 4,不是最新的 5。所以我程序里使用的是更多参数的接口,其倒是第二个参数设为 true, 意思是返回修改后的值。

还有一个就是这个返回值的类型是 Double 型的,最终返回前做一下类型转换。


最后,程序在保存对象的时候,调用 SequenceService.getNextUserSeq() 返回的值作为 ID 的值。

public void createUser(User user){
	encryptPassword(user);
	user.setId(seqService.getNextUserSeq());
	userDao.insert(user);
}

二,使用 BulkOperations 类可以批量增删改对象。

	public int enableUsers(List<String> userIds){
		BulkOperations bulkOps = temp.bulkOps(BulkMode.ORDERED, User.class);
		bulkOps.updateMulti(Query.query(Criteria.where("id").in(userIds)), Update.update("enabled", "1"));
		bulkOps.execute();
		return 1;
	}

三, distinct 获取记录的唯一字段数据

public List<String> getLoginNames(String mobile) {
	return (List<String>)temp.getCollection("user")
			.distinct("loginName", Query.query(Criteria.where("mobile").is(mobile)).getQueryObject());
}

但是如果希望通过 id 作为 Query 里的查询字段,那么注意了,不是我们定义的实体类比如这里 User 里的 id 字段,而应该是 MongoDB 保存 Collection 里面的的字段名,也就是 “_id”, 也就是说下面的语句才是可工作的:

public List<String> getLoginNames(Integer id) {
	return (List<String>)temp.getCollection("user").distinct("loginName", 
	Query.query(Criteria.where("_id").is(id)).getQueryObject());
}


四,条件组合查询,比如我们的查询是 : A  and (B or C), 可以使用 Criteria 的 andOperator / orOperator 接口实现:

public List<User> getUsersByNameLike(String keyword) {
	Query query = new Query();
	query.addCriteria(Criteria.where("loginName").ne("admin"))
		 .addCriteria(new Criteria()
				 .orOperator(Criteria.where("loginName").regex(keyword), 
							 Criteria.where("fullName").regex(keyword)));
	
	List<User> users = temp.find(query, User.class);
	return users;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值