MongoDB自动增长id实现、自定义函数调用、与Spring集成

来源:互联网 发布:iphone网络共享在哪里 编辑:程序博客网 时间:2024/06/01 18:34

昨天同事问实现MongoDB主键自动增长有什么好的办法,虽然喜欢MongoDB客户端驱动程序自动生成的id,不过还是来测试了一下,仅仅是测试哦


废话少说微笑


1、创建项目,添加依赖

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <dependencies>  
  2.     <dependency>  
  3.         <groupId>org.springframework.data</groupId>  
  4.         <artifactId>spring-data-mongodb</artifactId>  
  5.         <version>1.7.0.RELEASE</version>  
  6.     </dependency>  
  7.     <dependency>  
  8.         <groupId>org.springframework</groupId>  
  9.         <artifactId>spring-context</artifactId>  
  10.         <version>4.1.7.RELEASE</version>  
  11.     </dependency>  
  12.     <dependency>  
  13.         <groupId>org.springframework</groupId>  
  14.         <artifactId>spring-test</artifactId>  
  15.         <version>4.1.7.RELEASE</version>  
  16.     </dependency>  
  17.   
  18.     <dependency>  
  19.         <groupId>junit</groupId>  
  20.         <artifactId>junit</artifactId>  
  21.         <version>4.11</version>  
  22.     </dependency>  
  23.   
  24.     <dependency>  
  25.         <groupId>org.slf4j</groupId>  
  26.         <artifactId>slf4j-api</artifactId>  
  27.     </dependency>  
  28.     <dependency>  
  29.         <groupId>org.slf4j</groupId>  
  30.         <artifactId>slf4j-log4j12</artifactId>  
  31.     </dependency>  
  32.     <dependency>  
  33.         <groupId>log4j</groupId>  
  34.         <artifactId>log4j</artifactId>  
  35.     </dependency>  
  36. </dependencies>  

2、使用了spring-data-mongo,所以创建封装数据的演示类

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class User {  
  2.   
  3.     private long id;  
  4.   
  5.     private String name;  
  6.   
  7.     public User(long id, String name) {  
  8.         this.id = id;  
  9.         this.name = name;  
  10.     }  
  11.   
  12.     public long getId() {  
  13.         return id;  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     @Override  
  21.     public String toString() {  
  22.         return "User{" +  
  23.                 "id=" + id +  
  24.                 ", name='" + name + '\'' +  
  25.                 '}';  
  26.     }  
  27. }</span>  
3、创建资源配置文件app.properties

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. mongodb.host=localhost  
  2. mongodb.port=27017  

4、spring配置文件

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xmlns:mongo="http://www.springframework.org/schema/data/mongo"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd  
  8.        http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">  
  9.   
  10.     <context:property-placeholder location="classpath:app.properties"/>  
  11.   
  12.     <mongo:mongo-client id="mongoClient" host="${mongodb.host}" port="${mongodb.port}"/>  
  13.   
  14.     <mongo:db-factory id="dbFactory" dbname="script" mongo-ref="mongoClient"/>  
  15.   
  16.     <mongo:template id="mongoTemplate" db-factory-ref="dbFactory" converter-ref="mappingMongoConverter"/>  
  17.   
  18.     <bean id="dbRefResolver" class="org.springframework.data.mongodb.core.convert.DefaultDbRefResolver">  
  19.         <constructor-arg ref="dbFactory"/>  
  20.     </bean>  
  21.   
  22.     <bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext"/>  
  23.   
  24.     <bean id="defaultMongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">  
  25.         <constructor-arg name="typeKey">  
  26.             <null/>  
  27.         </constructor-arg>  
  28.     </bean>  
  29.   
  30.     <bean id="mappingMongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">  
  31.         <constructor-arg name="dbRefResolver" ref="dbRefResolver"/>  
  32.         <constructor-arg name="mappingContext" ref="mongoMappingContext"/>  
  33.         <property name="typeMapper" ref="defaultMongoTypeMapper"/>  
  34.     </bean>  
  35.   
  36. </beans>  

5、测试代码

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. import com.mongodb.BasicDBObject;  
  2. import com.mongodb.DB;  
  3. import org.junit.After;  
  4. import org.junit.Before;  
  5. import org.junit.Test;  
  6. import org.junit.runner.RunWith;  
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.data.mongodb.core.MongoTemplate;  
  9. import org.springframework.data.mongodb.core.ScriptOperations;  
  10. import org.springframework.data.mongodb.core.script.ExecutableMongoScript;  
  11. import org.springframework.data.mongodb.core.script.NamedMongoScript;  
  12. import org.springframework.test.context.ContextConfiguration;  
  13. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  14.   
  15. import static org.junit.Assert.assertEquals;  
  16. import static org.junit.Assert.assertTrue;  
  17. import static org.springframework.data.mongodb.core.query.Criteria.where;  
  18. import static org.springframework.data.mongodb.core.query.Query.query;  
  19. import static org.springframework.data.mongodb.core.query.Update.update;  
  20.   
  21. /** 
  22.  * (1) Test an auto-increment pattern for the _id field. 
  23.  * 
  24.  * (2) Test MongoDB Script and Spring Script Operations. 
  25.  * 
  26.  * Created by gaofu on 16-2-5. 
  27.  */  
  28. @RunWith(SpringJUnit4ClassRunner.class)  
  29. @ContextConfiguration(locations = "classpath:beans.xml")  
  30. public class AutoIncrementIdAndScriptTest {  
  31.   
  32.     @Autowired  
  33.     private MongoTemplate template;  
  34.   
  35.     @Before  
  36.     public void setUp() throws Exception {  
  37.         ScriptOperations scriptOps = template.scriptOps();  
  38.   
  39.         // 将JavaScript函数保存到MongoDB server,以便直接在客户端调用  
  40.         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}"));  
  41. //        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变成双精度浮点型  
  42.   
  43.         template.upsert(query(where("_id").is("userid")), update("seq", 0L), "counters");  
  44.     }  
  45.   
  46.   
  47.     @Test  
  48.     public void testClientScript() {  
  49.         final String origin = "Hello World";  
  50.         String script = "function(x){return x + \".\"}";  
  51.   
  52.         ExecutableMongoScript mongoScript = new ExecutableMongoScript(script);  
  53.   
  54.         ScriptOperations scriptOps = template.scriptOps();  
  55.   
  56.         Object result1 = scriptOps.execute(mongoScript, origin);  
  57.         // Spring使用String.format()方法对字符串进行了处理  
  58. //        System.out.println(result1);  
  59.         assertEquals(String.format("'%s'", origin) + '.', result1);  
  60.   
  61.         Object mongoEval = template.getDb().eval(script, origin);  
  62. //        System.out.println(mongoEval);  
  63.         assertEquals(origin + ".", mongoEval);  
  64.   
  65.         Object result2 = scriptOps.execute(mongoScript, 3);  
  66.         assertEquals("3.", result2);  
  67.     }  
  68.     @Test  
  69.     public void testAutoIncrementIdAndStoredScript() {  
  70.         ScriptOperations scriptOps = template.scriptOps();  
  71.   
  72.         boolean exists = scriptOps.exists("getNextSequence");  
  73.         assertTrue(exists);  
  74.   
  75.         // JavaScript返回的总是双精度浮点型数字,所以需要转换  
  76.         User jack = new User(((Number) scriptOps.call("getNextSequence""userid")).longValue(), "Jack");  
  77.         User rose = new User(((Number) scriptOps.call("getNextSequence""userid")).longValue(), "Rose");  
  78.         template.insert(jack);  
  79.         template.insert(rose);  
  80.   
  81.         assertEquals(1, jack.getId());  
  82.         assertEquals(2, rose.getId());  
  83.   
  84.         DB db = template.getDb();  
  85.         Object eval = db.eval("getNextSequence('userid')");  
  86.         // JavaScript返回的总是双精度浮点型数字  
  87.         assertEquals(3.0d, eval);  
  88.     }  
  89.   
  90.   
  91.     /** 
  92.      * 注释掉此方法可以查看数据库中的集合数据。 
  93.      */  
  94.     @After  
  95.     public void tearDown() throws Exception {  
  96.         template.dropCollection("counters");  
  97.         template.dropCollection(User.class);  
  98.         template.getCollection("system.js").remove(new BasicDBObject("_id""getNextSequence"));  
  99.     }  
  100. }  


6、spring需要日志输出,简单配置如下

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">  
  3.   
  4. <log4j:configuration>  
  5.     <appender name="default" class="org.apache.log4j.ConsoleAppender">  
  6.         <layout class="org.apache.log4j.PatternLayout">  
  7.             <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %40.40c:%4L - %m%n"/>  
  8.         </layout>  
  9.     </appender>  
  10.   
  11.     <root>  
  12.         <level value="info"/>  
  13.         <appender-ref ref="default"/>  
  14.     </root>  
  15. </log4j:configuration>  


备注:

(1)别忘了在本地启动MongoDB服务器。

(2)如果比较懒,想亲自动手测试,又懒得拷贝代码,可以下载源码。

0 0
原创粉丝点击