您的位置:首页 > 数据库 > Mongodb

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)如果比较懒,想亲自动手测试,又懒得拷贝代码,可以下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: