在本教程中,我们将向您展示如何在MongoDB + Spring Data环境中生成自动递增的序列ID。
该项目中使用的工具:
- Spring Data MongoDB 1.2.1.RELEASE
- MongoDB 2.4.5
- Eclipse 4.2
- Maven 3
在本教程的最后,如果保存了集合名称“主机”,则将分配一个新的自动递增序列ID。 以下是用于生成序列ID的Java代码段。
public long getNextSequenceId(String key) {
Query query = new Query(Criteria.where("_id").is(key));
Update update = new Update();
update.inc("seq", 1);
FindAndModifyOptions options = new FindAndModifyOptions();
options.returnNew(true);
SequenceId seqId =
mongoOperation.findAndModify(query, update, options, SequenceId.class);
return seqId.getSeq();
}
1.项目结构
查看项目目录结构(标准的Maven项目)。
2. Maven Pom
如果您对项目依赖项感兴趣。
pom.xml
<project ...>
<properties>
<jdk.version>1.6</jdk.version>
<spring.version>3.2.2.RELEASE</spring.version>
<mongojavadriver.version>2.11.1</mongojavadriver.version>
<springdata.version>1.2.1.RELEASE</springdata.version>
</properties>
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- need this for @Configuration -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Spring Data for MongoDB -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${springdata.version}</version>
</dependency>
<!-- Java MongoDB Driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>${mongojavadriver.version}</version>
</dependency>
</dependencies>
<build>
<finalName>SpringData</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.序列收集
我们创建一个集合名称“序列”来存储自动增加序列ID。 请参考下面的SequenceDaoImpl.java
,它向您显示了生成序列ID的代码。
注意
首先在您的MongoDB中创建“序列”集合!db.sequence.insert({_id: "hosting",seq: 0})
SequenceId.java
package com.mkyong.seq.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "sequence")
public class SequenceId {
@Id
private String id;
private long seq;
//get, set, toString...
}
SequenceDao.java
package com.mkyong.seq.dao;
import com.mkyong.seq.exception.SequenceException;
public interface SequenceDao {
long getNextSequenceId(String key) throws SequenceException;
}
SequenceDaoImpl.java
package com.mkyong.seq.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
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.Repository;
import com.mkyong.seq.exception.SequenceException;
import com.mkyong.seq.model.SequenceId;
@Repository
public class SequenceDaoImpl implements SequenceDao {
@Autowired
private MongoOperations mongoOperation;
@Override
public long getNextSequenceId(String key) throws SequenceException {
//get sequence id
Query query = new Query(Criteria.where("_id").is(key));
//increase sequence id by 1
Update update = new Update();
update.inc("seq", 1);
//return new increased id
FindAndModifyOptions options = new FindAndModifyOptions();
options.returnNew(true);
//this is the magic happened.
SequenceId seqId =
mongoOperation.findAndModify(query, update, options, SequenceId.class);
//if no id, throws SequenceException
//optional, just a way to tell user when the sequence id is failed to generate.
if (seqId == null) {
throw new SequenceException("Unable to get sequence id for key : " + key);
}
return seqId.getSeq();
}
}
SequenceException.java
package com.mkyong.seq.exception;
public class SequenceException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String errCode;
private String errMsg;
//get, set...
public SequenceException(String errMsg) {
this.errMsg = errMsg;
}
}
4.获取序列ID
要获取序列ID,请使用sequenceDao.getNextSequenceId("key")
。
HostingBo.java
package com.mkyong.hosting.bo;
import com.mkyong.seq.exception.SequenceException;
public interface HostingBo {
void save(String name) throws SequenceException;
}
HostingBoImpl.java
package com.mkyong.hosting.bo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mkyong.hosting.dao.HostingDao;
import com.mkyong.hosting.model.Hosting;
import com.mkyong.seq.dao.SequenceDao;
import com.mkyong.seq.exception.SequenceException;
@Service
public class HostingBoImpl implements HostingBo {
private static final String HOSTING_SEQ_KEY = "hosting";
@Autowired
private SequenceDao sequenceDao;
@Autowired
private HostingDao hostingDao;
@Override
public void save(String name) throws SequenceException {
Hosting hosting = new Hosting();
hosting.setId(sequenceDao.getNextSequenceId(HOSTING_SEQ_KEY));
hosting.setName(name);
hostingDao.save(hosting);
System.out.println(hosting);
}
}
5.测试
运行一个简单的测试。
package com.mkyong;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.mkyong.config.AppConfig;
import com.mkyong.hosting.bo.HostingBo;
import com.mkyong.seq.exception.SequenceException;
public class App {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
HostingBo hostingBo = (HostingBo) ctx.getBean("hostingBoImpl");
try {
hostingBo.save("cloud.google.com");
hostingBo.save("heroku.com");
hostingBo.save("cloudbees.com");
} catch (SequenceException e) {
System.out.println(e.getErrMsg());
}
}
}
输出– Java控制台
Hosting [id=1, name=cloud.google.com]
Hosting [id=2, name=heroku.com]
Hosting [id=3, name=cloudbees.com]
MongoDB控制台。
>mongo
> db.sequence.find()
{ "_id" : "hosting", "seq" : 3 }
> db.hosting.find()
{ "_id" : NumberLong(1), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "cloud.google.com" }
{ "_id" : NumberLong(2), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "heroku.com" }
{ "_id" : NumberLong(3), "_class" : "com.mkyong.hosting.model.Hosting", "name" : "cloudbees.com" }
>
6.常见问题
问:SequenceException –无法获取密钥的序列ID:托管?
答:请记住创建“序列”集合!
db.sequence.insert({_id: "hosting",seq: 0})
下载源代码
下载– SpringData-Auto-Sequence-Example.zip (24 KB)
参考文献
翻译自: https://mkyong.com/mongodb/spring-data-mongodb-auto-sequence-id-example/