MongoDB自动增长id实现、自定义函数调用、与Spring集成
2016-10-26 18:17
561 查看
昨天同事问实现MongoDB主键自动增长有什么好的办法,虽然喜欢MongoDB客户端驱动程序自动生成的id,不过还是来测试了一下,仅仅是测试哦
废话少说
1、创建项目,添加依赖
[html] view
plain copy
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
2、使用了spring-data-mongo,所以创建封装数据的演示类
[java] view
plain copy
public class User {
private long id;
private String name;
public User(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}</span>
3、创建资源配置文件app.properties
[plain] view
plain copy
mongodb.host=localhost
mongodb.port=27017
4、spring配置文件
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<context:property-placeholder location="classpath:app.properties"/>
<mongo:mongo-client id="mongoClient" host="${mongodb.host}" port="${mongodb.port}"/>
<mongo:db-factory id="dbFactory" dbname="script" mongo-ref="mongoClient"/>
<mongo:template id="mongoTemplate" db-factory-ref="dbFactory" converter-ref="mappingMongoConverter"/>
<bean id="dbRefResolver" class="org.springframework.data.mongodb.core.convert.DefaultDbRefResolver">
<constructor-arg ref="dbFactory"/>
</bean>
<bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext"/>
<bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey">
<null/>
</constructor-arg>
</bean>
<bean id="mappingMongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="dbRefResolver" ref="dbRefResolver"/>
<constructor-arg name="mappingContext" ref="mongoMappingContext"/>
<property name="typeMapper" ref="defaultMongoTypeMapper"/>
</bean>
</beans>
5、测试代码
[java] view
plain copy
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.ScriptOperations;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;
/**
* (1) Test an auto-increment pattern for the _id field.
*
* (2) Test MongoDB Script and Spring Script Operations.
*
* Created by gaofu on 16-2-5.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class AutoIncrementIdAndScriptTest {
@Autowired
private MongoTemplate template;
@Before
public void setUp() throws Exception {
ScriptOperations scriptOps = template.scriptOps();
// 将JavaScript函数保存到MongoDB server,以便直接在客户端调用
scriptOps.register(new NamedMongoScript("getNextSequence", "function(name){var ret=db.counters.findAndModify({query:{_id:name},update:{$inc:{seq:NumberLong(1)}},new:true});return ret.seq.floatApprox}"));
// scriptOps.register(new NamedMongoScript("getNextSequence", "function(name){var ret=db.counters.findAndModify({query:{_id:name},update:{$inc:{seq:1}},new:true});return ret.seq}")); // 这样就会把seq变成双精度浮点型
template.upsert(query(where("_id").is("userid")), update("seq", 0L), "counters");
}
@Test
public void testClientScript() {
final String origin = "Hello World";
String script = "function(x){return x + \".\"}";
ExecutableMongoScript mongoScript = new ExecutableMongoScript(script);
ScriptOperations scriptOps = template.scriptOps();
Object result1 = scriptOps.execute(mongoScript, origin);
// Spring使用String.format()方法对字符串进行了处理
// System.out.println(result1);
assertEquals(String.format("'%s'", origin) + '.', result1);
Object mongoEval = template.getDb().eval(script, origin);
// System.out.println(mongoEval);
assertEquals(origin + ".", mongoEval);
Object result2 = scriptOps.execute(mongoScript, 3);
assertEquals("3.", result2);
}
@Test
public void testAutoIncrementIdAndStoredScript() {
ScriptOperations scriptOps = template.scriptOps();
boolean exists = scriptOps.exists("getNextSequence");
assertTrue(exists);
// JavaScript返回的总是双精度浮点型数字,所以需要转换
User jack = new User(((Number) scriptOps.call("getNextSequence", "userid")).longValue(), "Jack");
User rose = new User(((Number) scriptOps.call("getNextSequence", "userid")).longValue(), "Rose");
template.insert(jack);
template.insert(rose);
assertEquals(1, jack.getId());
assertEquals(2, rose.getId());
DB db = template.getDb();
Object eval = db.eval("getNextSequence('userid')");
// JavaScript返回的总是双精度浮点型数字
assertEquals(3.0d, eval);
}
/**
* 注释掉此方法可以查看数据库中的集合数据。
*/
@After
public void tearDown() throws Exception {
template.dropCollection("counters");
template.dropCollection(User.class);
template.getCollection("system.js").remove(new BasicDBObject("_id", "getNextSequence"));
}
}
6、spring需要日志输出,简单配置如下
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="default" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %40.40c:%4L - %m%n"/>
</layout>
</appender>
<root>
<level value="info"/>
<appender-ref ref="default"/>
</root>
</log4j:configuration>
备注:
(1)别忘了在本地启动MongoDB服务器。
(2)如果比较懒,想亲自动手测试,又懒得拷贝代码,可以下载源码。
废话少说
1、创建项目,添加依赖
[html] view
plain copy
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
2、使用了spring-data-mongo,所以创建封装数据的演示类
[java] view
plain copy
public class User {
private long id;
private String name;
public User(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}</span>
3、创建资源配置文件app.properties
[plain] view
plain copy
mongodb.host=localhost
mongodb.port=27017
4、spring配置文件
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<context:property-placeholder location="classpath:app.properties"/>
<mongo:mongo-client id="mongoClient" host="${mongodb.host}" port="${mongodb.port}"/>
<mongo:db-factory id="dbFactory" dbname="script" mongo-ref="mongoClient"/>
<mongo:template id="mongoTemplate" db-factory-ref="dbFactory" converter-ref="mappingMongoConverter"/>
<bean id="dbRefResolver" class="org.springframework.data.mongodb.core.convert.DefaultDbRefResolver">
<constructor-arg ref="dbFactory"/>
</bean>
<bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext"/>
<bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey">
<null/>
</constructor-arg>
</bean>
<bean id="mappingMongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="dbRefResolver" ref="dbRefResolver"/>
<constructor-arg name="mappingContext" ref="mongoMappingContext"/>
<property name="typeMapper" ref="defaultMongoTypeMapper"/>
</bean>
</beans>
5、测试代码
[java] view
plain copy
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.ScriptOperations;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;
/**
* (1) Test an auto-increment pattern for the _id field.
*
* (2) Test MongoDB Script and Spring Script Operations.
*
* Created by gaofu on 16-2-5.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class AutoIncrementIdAndScriptTest {
@Autowired
private MongoTemplate template;
@Before
public void setUp() throws Exception {
ScriptOperations scriptOps = template.scriptOps();
// 将JavaScript函数保存到MongoDB server,以便直接在客户端调用
scriptOps.register(new NamedMongoScript("getNextSequence", "function(name){var ret=db.counters.findAndModify({query:{_id:name},update:{$inc:{seq:NumberLong(1)}},new:true});return ret.seq.floatApprox}"));
// scriptOps.register(new NamedMongoScript("getNextSequence", "function(name){var ret=db.counters.findAndModify({query:{_id:name},update:{$inc:{seq:1}},new:true});return ret.seq}")); // 这样就会把seq变成双精度浮点型
template.upsert(query(where("_id").is("userid")), update("seq", 0L), "counters");
}
@Test
public void testClientScript() {
final String origin = "Hello World";
String script = "function(x){return x + \".\"}";
ExecutableMongoScript mongoScript = new ExecutableMongoScript(script);
ScriptOperations scriptOps = template.scriptOps();
Object result1 = scriptOps.execute(mongoScript, origin);
// Spring使用String.format()方法对字符串进行了处理
// System.out.println(result1);
assertEquals(String.format("'%s'", origin) + '.', result1);
Object mongoEval = template.getDb().eval(script, origin);
// System.out.println(mongoEval);
assertEquals(origin + ".", mongoEval);
Object result2 = scriptOps.execute(mongoScript, 3);
assertEquals("3.", result2);
}
@Test
public void testAutoIncrementIdAndStoredScript() {
ScriptOperations scriptOps = template.scriptOps();
boolean exists = scriptOps.exists("getNextSequence");
assertTrue(exists);
// JavaScript返回的总是双精度浮点型数字,所以需要转换
User jack = new User(((Number) scriptOps.call("getNextSequence", "userid")).longValue(), "Jack");
User rose = new User(((Number) scriptOps.call("getNextSequence", "userid")).longValue(), "Rose");
template.insert(jack);
template.insert(rose);
assertEquals(1, jack.getId());
assertEquals(2, rose.getId());
DB db = template.getDb();
Object eval = db.eval("getNextSequence('userid')");
// JavaScript返回的总是双精度浮点型数字
assertEquals(3.0d, eval);
}
/**
* 注释掉此方法可以查看数据库中的集合数据。
*/
@After
public void tearDown() throws Exception {
template.dropCollection("counters");
template.dropCollection(User.class);
template.getCollection("system.js").remove(new BasicDBObject("_id", "getNextSequence"));
}
}
6、spring需要日志输出,简单配置如下
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="default" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %40.40c:%4L - %m%n"/>
</layout>
</appender>
<root>
<level value="info"/>
<appender-ref ref="default"/>
</root>
</log4j:configuration>
备注:
(1)别忘了在本地启动MongoDB服务器。
(2)如果比较懒,想亲自动手测试,又懒得拷贝代码,可以下载源码。
相关文章推荐
- MongoDB自动增长id实现、自定义函数调用、与Spring集成
- SpringBoot入门-17(springboot集成mybatis注解形式实现ID自动增长)
- mongodb 自定义函数—自增长id
- Mongodb 自动增长 自增id 实现 -1
- Mongodb 自动增长 自增id 实现 -2
- Spring 自定义HttpMessageConverter实现MongoDb自定义ObjectId对象为字符串
- Mongodb 自动增长 自增id 实现
- Mongodb 自动增长 自增id 实现
- Spring-boot mongodb ID自增长注解实现 适用于JDK 1.7和JDK 1.8
- Mongodb 自动增长 自增id 实现
- MySQL中自定义函数实现id自增长
- Mongodb 自动增长 自增id 实现 -3 PHP
- MongoDB 实现字段自动增长id Mongodb auto increment ID
- 一个通用的单元测试框架的思考和设计07-实现篇-自动管理测试数据-如何为自增长主键id赋值
- oracle实现自动记录存储过程、自定义函数执行错误
- 各种数据库自动增长主键Id的sql调用命令
- Oracle 表创建序列-触发 实现表ID自动增长
- Javascript 对象方式实现命名参数调用(下):自动包装偏函数
- oracle实现自动记录存储过程、自定义函数执行错误
- SQL Server中根据某个字段,ID字段自动增长的实现