spring4與mongodb的集成


新項目的輔助系統,需要用到mongo系統,今天再次將其使用環境進行了操作搭建。還是遇到一些問題,畢竟之前使用的場景和現在的不同。版本也不一樣了。

 

本次使用的環境:

mongo:3.4.4版本

OS: redhat7

java操作mongo庫

 

1. 首先,mongo數據庫的安裝

直接到mongodb官網下載mongodb-linux-x86_64-rhel70-3.4.4.tgz。解壓之后,運行mongod即可啟動服務。當然,我這里是為了項目開發用,第一步就啟用單實例。

看看我們的mongodb的配置:

#數據庫數據存放路徑
dbpath = /home/tkrobot/mongodb/data
#日志存放路徑 logpath
= /home/tkrobot/mongodb/logs/mongodb.log logappend = true port = 27017 fork = true
#啟動認證功能,要想連接到數據庫,必須經過用戶名密碼認證才可以 auth = true
#禁止http訪問數據庫 nohttpinterface = true
#連接數據庫時必須是這個ip bind_ip = 10.90.7.10 journal = true
#最大連接數 maxConns = 100

這里,需要在mongod啟動前,創建好/home/tkrobot/mongodb/data以及/home/tkrobot/mongodb/logs兩個目錄。

啟動mongod的腳本:

./mongod --config /etc/mongodb.conf

 

這樣,mongod就算啟動好了。下面有其啟動日志:

2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] MongoDB starting : pid=98891 port=27017 dbpath=/home/tkrobot/mongodb/data 64-bit host=localhost.localdomain
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] db version v3.4.4
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] git version: 888390515874a9debd1b6c5d36559ca86b44babd
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] modules: none
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] build environment:
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten]     distmod: rhel70
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten]     distarch: x86_64
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten]     target_arch: x86_64
2017-05-02T11:20:03.553+0800 I CONTROL  [initandlisten] options: { config: "/etc/mongodb.conf", net: { bindIp: "10.90.7.10", http: { enabled: false }, maxIncomingConnections: 100, port: 27017 }, security: { authorization: "enabled" }, st
orage: { dbPath: "/home/tkrobot/mongodb/data", journal: { enabled: true } }, systemLog: { destination: "file", logAppend: true, path: "/home/tkrobot/mongodb/logs/mongodb.log" } }
2017-05-02T11:20:03.553+0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=15438M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=jo
urnal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2017-05-02T11:20:03.567+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2017-05-02T11:20:03.567+0800 I CONTROL  [initandlisten]
2017-05-02T11:20:03.567+0800 I CONTROL  [initandlisten]
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] ** WARNING: You are running on a NUMA machine.
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] **          We suggest launching mongod like this to avoid performance problems:
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] **              numactl --interleave=all mongod [other options]
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten]
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten]
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-05-02T11:20:03.568+0800 I CONTROL  [initandlisten]
2017-05-02T11:20:03.571+0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/home/tkrobot/mongodb/data/diagnostic.data'
2017-05-02T11:20:03.575+0800 I INDEX    [initandlisten] build index on: admin.system.version properties: { v: 2, key: { version: 1 }, name: "incompatible_with_version_32", ns: "admin.system.version" }
2017-05-02T11:20:03.575+0800 I INDEX    [initandlisten]          building index using bulk method; build may temporarily use up to 500 megabytes of RAM
2017-05-02T11:20:03.576+0800 I INDEX    [initandlisten] build index done.  scanned 0 total records. 0 secs
2017-05-02T11:20:03.576+0800 I COMMAND  [initandlisten] setting featureCompatibilityVersion to 3.4
2017-05-02T11:20:03.576+0800 I NETWORK  [thread1] waiting for connections on port 27017

 

2. 接下來,我們操作一下,驗證數據庫部署的情況是否ok。

為了方便使用mongo客戶端指令,將解壓后的mongo配置到環境變量里面,方便操作。

export MONGODB_PATH=/home/tkrobot/mongodb-linux-x86_64-rhel70-3.4.4

export PATH=$JAVA_HOME/bin:$MONGODB_PATH/bin:$PATH

 

用mongo登錄操作數據庫:

[root@localhost bin]# mongo
MongoDB shell version v3.4.4
connecting to: mongodb://10.90.7.10:27017
MongoDB server version: 3.4.4
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        http://docs.mongodb.org/
Questions? Try the support group
        http://groups.google.com/group/mongodb-user
> show dbs;
2017-05-02T11:21:08.878+0800 E QUERY    [thread1] Error: listDatabases failed:{
        "ok" : 0,
        "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
        "code" : 13,
        "codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:769:19
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1

沒有權限,因為我們在mongod.conf里面指定要auth了。最簡單的辦法,就是將mongod.conf里面的auth注釋掉,重新啟動mongod,進行權限配置。

 

在沒有auth屬性的情況下,啟動mongod,然后再次mongo連接上數據庫,use指定的數據庫,創建一個專屬的用戶。

use robotkdb

指定數據庫robotkdb后,創建一個用戶robotassister。

db.createUser({
... user:"robotassister",
... pwd:"xxyyyxxxxx",
... roles:[{role:"dbOwner",db:"robotkdb“}]})

這樣,就相當於給指定的數據庫robotkdb創建了一個角色為dbOwener的用戶robotassister。

 

最后,將mongodb.conf中的auth重新放開,啟用auth,再啟動mongod,並進行指定數據庫和用戶名的方式連接到mongodb:

mongo --host 10.90.7.10 --port 27017 -u robotassister -p xxyyyxxxx robotdb

如此,一切都ok,單實例的mongod配置帶auth的啟動,客戶端通過credentials的方式連接到指定的庫,准備工作就緒。

 

3. spring集成mongodb。

安裝spring官方的文檔介紹,這個過程是比較簡單的。集成過程中需要用到的支持mongodb的jar包也不多。主要有:

mongo-java-driver-3.4.1.jar
spring-data-commons-1.10.0.RELEASE.jar
spring-data-commons-core-1.4.1.RELEASE.jar
spring-data-mongodb-1.7.0.RELEASE.jar

上述的jar是我的集成過程中用到的。

 

我在自己既有的spring mvc的web項目里面,添加了mongodb的支持。

首先看看mongodb的xml配置文件spring-mongo.xml:

<?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" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-3.2.xsd       
          http://www.springframework.org/schema/util 
          http://www.springframework.org/schema/util/spring-util-3.2.xsd" 
        default-lazy-init="default">
    
    <!--credentials的配置形式是:用戶名:密碼@默認數據庫-->
    <mongo:mongo-client id="mongoClient" host="${mongo.host}" port="${mongo.port}"    credentials="${mongo.username}:${mongo.password}@${mongo.dbname}">        
        <mongo:client-options  write-concern="SAFE"
            connections-per-host="${mongo.connectionsPerHost}" 
            threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}" 
            connect-timeout="${mongo.connectTimeout}" 
            max-wait-time="${mongo.maxWaitTime}" 
            socket-timeout="${mongo.socketTimeout}"/>        
    </mongo:mongo-client>
    
    <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongoClient" />
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>    
</beans>

其中的參數配置文件mongo.properties:

mongo.dbname=robotkdb
mongo.host=10.90.7.10
mongo.port=27017
mongo.username=robotassister
mongo.password=xxyyyxxxxx
#一個線程變為可用的最大阻塞數
mongo.connectionsPerHost=8
#線程隊列數,它以上面connectionsPerHost值相乘的結果就是線程隊列最大值
mongo.threadsAllowedToBlockForConnectionMultiplier=4
#連接超時時間(毫秒) 
mongo.connectTimeout=1500
#最大等待時間
mongo.maxWaitTime=1500
#自動重連
mongo.autoConnectRetry=true
#scoket保持活動
mongo.socketKeepAlive= true
#scoket超時時間
mongo.socketTimeout=1500
#讀寫分離
mongo.slaveOk=true

 

接下來,看看spring的配置文件applicationContext.xml:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:cache="http://www.springframework.org/schema/cache" 
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
   http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <bean id="configRealm" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
         <property name="locations">
            <list>
                <value>classpath:conf/internal.properties</value>
                <value>classpath:conf/jdbc.properties</value>
                <value>classpath:conf/redis.properties</value>
                <value>classpath:conf/session.properties</value>                
                <value>classpath:conf/mongo.properties</value>
            </list>
        </property>
    </bean>
     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
         <property name="properties" ref="configRealm"/>
    </bean>
    
    
    <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcacheManager"/>
    </bean>

    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:conf/ehcache.xml"/>
    </bean>

    <cache:annotation-driven cache-manager="springCacheManager"/>
    
    <import resource="spring-servlet.xml"/>     
    <import resource="spring-cache.xml"/>     
    <import resource="spring-dao.xml"/>    
    <import resource="spring-redis.xml"/>
    <import resource="spring-mongo.xml"/>
</beans>

 

ok,到此,所有的配置工作都完畢了,我們就啟動web項目,看看是否能正常啟動吧!遺憾,出了下面的錯誤!!!!!

五月 02, 2017 4:49:49 下午 org.apache.catalina.core.StandardContext listenerStart
嚴重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [spring-mongo.xml]
Offending resource: class path resource [conf/applicationContext.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 275 in XML document from class path resource [conf/spring-mongo.xml] is invalid; nested exception is org.xml.sax.SAXParseException; systemId: http://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd; lineNumber: 275; columnNumber: 63; src-resolve: 無法將名稱 'repository:auditing-attributes' 解析為 'attribute group' 組件。
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:76)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:274)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:199)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:147)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:101)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:495)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:542)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4811)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5251)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 275 in XML document from class path resource [conf/spring-mongo.xml] is invalid; nested exception is org.xml.sax.SAXParseException; systemId: http://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd; lineNumber: 275; columnNumber: 63; src-resolve: 無法將名稱 'repository:auditing-attributes' 解析為 'attribute group' 組件。
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:397)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:258)
    ... 28 more
Caused by: org.xml.sax.SAXParseException; systemId: http://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd; lineNumber: 275; columnNumber: 63; src-resolve: 無法將名稱 'repository:auditing-attributes' 解析為 'attribute group' 組件。
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4162)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4145)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1741)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDAttributeGroupTraverser.traverseLocal(XSDAttributeGroupTraverser.java:80)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDAbstractTraverser.traverseAttrsAndAttrGrps(XSDAbstractTraverser.java:643)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.processComplexContent(XSDComplexTypeTraverser.java:1122)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.traverseComplexTypeDecl(XSDComplexTypeTraverser.java:335)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDComplexTypeTraverser.traverseLocal(XSDComplexTypeTraverser.java:164)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(XSDElementTraverser.java:392)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseGlobal(XSDElementTraverser.java:242)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseSchemas(XSDHandler.java:1433)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:630)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:616)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.findSchemaGrammar(XMLSchemaValidator.java:2453)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1772)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:746)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:378)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2778)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347)
    at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:75)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:389)
    ... 31 more

這個,還真是折騰了我一段時間,最終找到原因:

上述這個錯誤,需要在spring-mongo.xml文件中添加下面的兩行內容
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository-1.7.xsd

 

采用基於mongo:mongo-client標簽進行安全配置,mongo要求spring-mongo.xsd必須是1.6及以上的版本。我們這里選用的是1.7.

 

ok,再次運行看看吧。。。。。。結果如何呢。。。。。。。。。

五月 02, 2017 6:03:55 下午 org.apache.catalina.core.StandardContext listenerStart
嚴重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate' defined in class path resource [conf/spring-mongo.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/objenesis/ObjenesisStd
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1077)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:981)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:938)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4811)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5251)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/objenesis/ObjenesisStd
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:121)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:277)
    ... 23 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/objenesis/ObjenesisStd
    at org.springframework.data.mongodb.core.convert.DefaultDbRefResolver.<init>(DefaultDbRefResolver.java:72)
    at org.springframework.data.mongodb.core.MongoTemplate.getDefaultMongoConverter(MongoTemplate.java:2029)
    at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:216)
    at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:201)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    ... 25 more
Caused by: java.lang.ClassNotFoundException: org.springframework.objenesis.ObjenesisStd
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1305)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1139)
    ... 34 more        

又出現了錯誤。。。看來不是很順利啊,再研究看root cause是什么呢???依據

爆出上述錯誤,經過查找原因,得知,sping-data-mongo要求spring-core必須是4.x的版本,也就是說spring4才行。

 

源頭是通過查找日志中紅色部分的錯誤信息,得知相關的jar依賴文件,在spring-core 4.x的版本中默認含有,於是,將項目中原來3.2的配置信息,全部更新為4.2的,並相應的將工程的lib中spring的版本更新到4.2.再次啟動應用。這次,一切都ok了。

 

最終能正常運行的applicationContext.xml的內容如下:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:cache="http://www.springframework.org/schema/cache" 
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
   http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <bean id="configRealm" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
         <property name="locations">
            <list>
                <value>classpath:conf/internal.properties</value>
                <value>classpath:conf/jdbc.properties</value>
                <value>classpath:conf/redis.properties</value>
                <value>classpath:conf/session.properties</value>                
                <value>classpath:conf/mongo.properties</value>
            </list>
        </property>
    </bean>
     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
         <property name="properties" ref="configRealm"/>
    </bean>
    
    
    <bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcacheManager"/>
    </bean>

    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:conf/ehcache.xml"/>
    </bean>

    <cache:annotation-driven cache-manager="springCacheManager"/>
    
    <import resource="spring-servlet.xml"/>     
    <import resource="spring-cache.xml"/>     
    <import resource="spring-dao.xml"/>    
    <import resource="spring-redis.xml"/>
    <import resource="spring-mongo.xml"/>
</beans>
View Code

最終能正常運行的spring-mongo.xml的內容如下:

<?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" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-4.2.xsd 
          http://www.springframework.org/schema/data/mongo 
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd 
          http://www.springframework.org/schema/data/repository
          http://www.springframework.org/schema/data/repository/spring-repository-1.7.xsd
          http://www.springframework.org/schema/util 
          http://www.springframework.org/schema/util/spring-util-4.2.xsd" 
        default-lazy-init="default">
    
    <!--credentials的配置形式是:用戶名:密碼@默認數據庫-->
    <mongo:mongo-client id="mongoClient" host="${mongo.host}" port="${mongo.port}"    credentials="${mongo.username}:${mongo.password}@${mongo.dbname}">        
        <mongo:client-options  write-concern="SAFE"
            connections-per-host="${mongo.connectionsPerHost}" 
            threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}" 
            connect-timeout="${mongo.connectTimeout}" 
            max-wait-time="${mongo.maxWaitTime}" 
            socket-timeout="${mongo.socketTimeout}"/>        
    </mongo:mongo-client>
    
    <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongoClient" />
    
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
    </bean>    
</beans>
View Code

 

4. 啟用一個測試,驗證一下spring和mongodb的集成是否成功吧

先構建一個javabean:

/**
 * @author "shihuc"
 * @date   2017年5月3日
 */
package com.roomdis.center.mongo.model;

import java.io.Serializable;

import org.ietf.jgss.Oid;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * @author chengsh05
 *
 */
@Document(collection="buzz_element")
public class BuzzElement implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private Oid _id;
    
    @Field(value="item_id")
    private String itemId;
    @Field(value="item_name")
    private String itemName;
    @Field(value="price")
    private String price;
    @Field(value="desc")
    private String desc;

    public Oid get_id() {
        return _id;
    }

    public void set_id(Oid _id) {
        this._id = _id;
    }

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public String toString() {
        return "ItemInfo [_id=" + _id + ", itemId=" + itemId + ", itemName="
                + itemName + ", price=" + price + ", desc=" + desc + "]";
    }
}

再創建工具類BeanUtil:

/**
 * @author "shihuc"
 * @date   2017年5月3日
 */
package com.roomdis.center.mongo.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

/**
 * @author chengsh05
 *
 */
public class BeanUtil {


    /**
     * 把實體bean對象轉換成DBObject
     * @param bean
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static <T> DBObject bean2DBObject(T bean) throws IllegalArgumentException,
        IllegalAccessException {
      if (bean == null) {
        return null;
      }
      DBObject dbObject = new BasicDBObject();
      // 獲取對象對應類中的所有屬性域
      Field[] fields = bean.getClass().getDeclaredFields();
      
      // 獲取所有注解
      for (Field field : fields) {
          org.springframework.data.mongodb.core.mapping.Field anno = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
        // 獲取屬性名
        String varName = field.getName();
        
        if("serialVersionUID".equals(varName) || "_id".equals(varName)){
            continue;
        }
        
        // 獲取注解的值
        varName = anno.value();
        // 修改訪問控制權限
        boolean accessFlag = field.isAccessible();
        if (!accessFlag) {
          field.setAccessible(true);
        }
        Object param = field.get(bean);
        if (param == null) {
          continue;
        } else if (param instanceof Integer) {//判斷變量的類型
          int value = ((Integer) param).intValue();
          dbObject.put(varName, value);
        } else if (param instanceof String) {
          String value = (String) param;
          dbObject.put(varName, value);
        } else if (param instanceof Double) {
          double value = ((Double) param).doubleValue();
          dbObject.put(varName, value);
        } else if (param instanceof Float) {
          float value = ((Float) param).floatValue();
          dbObject.put(varName, value);
        } else if (param instanceof Long) {
          long value = ((Long) param).longValue();
          dbObject.put(varName, value);
        } else if (param instanceof Boolean) {
          boolean value = ((Boolean) param).booleanValue();
          dbObject.put(varName, value);
        } else if (param instanceof Date) {
          Date value = (Date) param;
          dbObject.put(varName, value);
        }
        // 恢復訪問控制權限
        field.setAccessible(accessFlag);
      }
      
      return dbObject;
    }

    /**
     * 把DBObject轉換成bean對象
     * @param dbObject
     * @param bean
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    public static <T> T dbObject2Bean(DBObject dbObject, T bean) throws IllegalAccessException,
        InvocationTargetException, NoSuchMethodException {
      if (bean == null) {
        return null;
      }
      Field[] fields = bean.getClass().getDeclaredFields();
      for (Field field : fields) {
        String varName = field.getName();
        org.springframework.data.mongodb.core.mapping.Field anno = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
        if("serialVersionUID".equals(varName) || "_id".equals(varName)){
            continue;
        }
        
        String fieldName = anno.value();
        Object object = dbObject.get(fieldName);
        if (object != null) {
          BeanUtils.setProperty(bean, varName, object);
        }
      }
      return bean;
    }
}

再次,創建服務,進行操作數據庫,相當於dao層:

/**
 * @author "shihuc"
 * @date   2017年5月3日
 */
package com.roomdis.center.mongo.service;

import java.util.List;

import org.json.JSONObject;

import com.roomdis.center.mongo.model.BuzzElement;

/**
 * @author chengsh05
 *
 */
public interface IBuzzElementService {
    // 查詢
    public List<BuzzElement> getItemInfo(JSONObject json) throws Exception;
    
    // 保存
    public int save(BuzzElement itemInfo) throws Exception;
    
    // 更新
    public void update(BuzzElement intemInfo) throws Exception;
}
/**
 * @author "shihuc"
 * @date   2017年5月3日
 */
package com.roomdis.center.mongo.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.WriteResult;
import com.roomdis.center.mongo.model.BuzzElement;
import com.roomdis.center.mongo.service.IBuzzElementService;
import com.roomdis.center.mongo.util.BeanUtil;

/**
 * @author chengsh05
 *
 */
@Service("buzzElementService")
public class BuzzElementServiceImpl implements IBuzzElementService {
    
    @Autowired
    private MongoTemplate mongoTemplate;
    private final static String COLLECTION_NAME = "buzz_element"; 
    
    /* (non-Javadoc)
     * @see com.roomdis.center.mongo.service.IBuzzElementService#getItemInfo(org.json.JSONObject)
     */
    @Override
    public List<BuzzElement> getItemInfo(JSONObject json) throws Exception {
        List<BuzzElement> list = new ArrayList<BuzzElement>();
        // 判斷查詢的json中傳遞過來的參數
        DBObject query = new BasicDBObject();

        if(json.has("item_id")){            
            query.put("item_id", json.getString("item_id"));
        }else if(json.has("item_name")){
            query.put("item_name", json.getString("item_name"));
        }
        
        DBCursor results = mongoTemplate.getCollection(COLLECTION_NAME).find(query);
        if(null != results){
            Iterator<DBObject> iterator = results.iterator();
            while(iterator.hasNext()){
                BasicDBObject obj = (BasicDBObject) iterator.next();
                BuzzElement itemInfo = new BuzzElement();
                itemInfo = BeanUtil.dbObject2Bean(obj, itemInfo);
                list.add(itemInfo);
            }
        }
        
        
        return list;
    }

    /* (non-Javadoc)
     * @see com.roomdis.center.mongo.service.IBuzzElementService#save(com.roomdis.center.mongo.model.BuzzElement)
     */
    @Override
    public int save(BuzzElement itemInfo) throws Exception {      
        DBCollection collection = this.mongoTemplate.getCollection(COLLECTION_NAME);
        int result = 0;
        DBObject iteminfoObj = BeanUtil.bean2DBObject(itemInfo);
        
        //iteminfoObj.removeField("serialVersionUID");
        //result = collection.insert(iteminfoObj).getN();
        WriteResult writeResult = collection.save(iteminfoObj);
        result = writeResult.getN();
        return result;
    }

    /* (non-Javadoc)
     * @see com.roomdis.center.mongo.service.IBuzzElementService#update(com.roomdis.center.mongo.model.BuzzElement)
     */
    @Override
    public void update(BuzzElement intemInfo) throws Exception {
        DBCollection collection = this.mongoTemplate.getCollection(COLLECTION_NAME);
        BuzzElement queryItemInfo = new BuzzElement();
        queryItemInfo.setItemId(intemInfo.getItemId());
        DBObject itemInfoObj = BeanUtil.bean2DBObject(intemInfo);
        DBObject query =  BeanUtil.bean2DBObject(queryItemInfo);
        collection.update(query, itemInfoObj);        
    }
}

鄭重說明,上述的javabean以及BeanUtil還有服務程序類,是參照網絡資源,考慮到這些東西不是本博的重點,也不是關鍵,所以沒有花時間在這個上面。

 

最后,我們寫一個controller來模擬一下添加數據,查詢數據以及更新數據,看看工作流程是否順暢!

/**
 * @author "shihuc"
 * @date   2017年5月3日
 */
package com.roomdis.center.mongo.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.roomdis.center.mongo.model.BuzzElement;
import com.roomdis.center.mongo.service.IBuzzElementService;

/**
 * @author chengsh05
 *
 */
@Controller
@RequestMapping("/mongo")
public class MongoOpController {

    @Resource(name="buzzElementService")
    private IBuzzElementService bes;
    
    @RequestMapping("/save")
    @ResponseBody
    public String doSave(HttpServletRequest req){
        
        String itemName = req.getParameter("itemName");
        String price = req.getParameter("price");
        String desc = req.getParameter("desc");
        BuzzElement be = new BuzzElement();
        be.setItemName(itemName);
        be.setDesc(desc);
        be.setPrice(price);
        try {
            bes.save(be);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "Save OK";
    }
    
    @RequestMapping("/find")
    @ResponseBody
    public String doFind(HttpServletRequest req){
        
        String itemName = req.getParameter("itemName");        
        JSONObject json = new JSONObject();
        json.putOnce("item_name", itemName);
        List<BuzzElement> res = null;
        try {
            res = bes.getItemInfo(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return "Find OK: " + res.size() ;
    }
    
    @RequestMapping("/update")
    @ResponseBody
    public String doUpdate(HttpServletRequest req){
        
        String itemName = req.getParameter("itemName");
        String price = req.getParameter("price");
        String desc = req.getParameter("desc");
        
        BuzzElement be = new BuzzElement();
        be.setItemName(itemName);
        be.setDesc(desc);
        be.setPrice(price);
        
        try {
            bes.update(be);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        
        return "Update OK";
    }
}

 

好了,代碼都准備ok了,下面進行測試!

A.在瀏覽器地址欄執行:http://10.90.9.20:8080/RDcenter/mongo/save

數據庫得到的數據:

> show collections
buzz_element
user
> db.buzz_element.find()
{ "_id" : ObjectId("59092f3e0ef2eb286cd7410a") }

 

B. 添加一條數據。在瀏覽器地址欄里面輸入: http://10.90.9.20:8080/RDcenter/mongo/save?itemName=iphone7&price=7000&desc=good product, everyone loves it

數據庫得到的數據:

> db.buzz_element.find()
{ "_id" : ObjectId("59092f3e0ef2eb286cd7410a") }
{ "_id" : ObjectId("590930480ef2eb286cd7410b"), "item_name" : "iphone7", "price" : "7000", "desc" : "good product, everyone loves it" }

再次添加一條數據,在瀏覽器地址欄里面輸入: http://10.90.9.20:8080/RDcenter/mongo/save?itemName=S8&price=8000&desc=samsung new product

數據庫得到的數據:

> db.buzz_element.find()
{ "_id" : ObjectId("59092f3e0ef2eb286cd7410a") }
{ "_id" : ObjectId("590930480ef2eb286cd7410b"), "item_name" : "iphone7", "price" : "7000", "desc" : "good product, everyone loves it" }
{ "_id" : ObjectId("590933870ef2eb1bf8d04d70"), "item_name" : "S8", "price" : "8000", "desc" : "samsung new product" }

 

C.查詢數據,在瀏覽器地址欄輸入:http://10.90.9.20:8080/RDcenter/mongo/find?itemName=S8

最終,瀏覽器上得到的返回結果是:

 

D. 更新數據,在瀏覽器地址欄輸入:http://10.90.9.20:8080/RDcenter/mongo/update?itemName=S8&price=9000&desc=hope it is nice

更新前的數據庫數據:

> db.buzz_element.find()
{ "_id" : ObjectId("59092f3e0ef2eb286cd7410a"), "item_name" : "iphone7", "desc" : "not everyone will buy it" }
{ "_id" : ObjectId("590930480ef2eb286cd7410b"), "item_name" : "iphone7", "price" : "7000", "desc" : "good product, everyone loves it" }
{ "_id" : ObjectId("590933870ef2eb1bf8d04d70"), "item_name" : "S8", "price" : "8000", "desc" : "samsung new product" }

更新后的數據庫數據:

> db.buzz_element.find()
{ "_id" : ObjectId("59092f3e0ef2eb286cd7410a"), "item_name" : "S8", "price" : "9000", "desc" : "hope it is nice" }
{ "_id" : ObjectId("590930480ef2eb286cd7410b"), "item_name" : "iphone7", "price" : "7000", "desc" : "good product, everyone loves it" }
{ "_id" : ObjectId("590933870ef2eb1bf8d04d70"), "item_name" : "S8", "price" : "8000", "desc" : "samsung new product" }

從上面看,數據庫是更新了,但是貌似有點邏輯問題,將第一個更新了,我們希望是將既有的item_name為S8產品數據更新的,這個是業務邏輯問題,暫且不做修改了。。。

 

從上面的全部過程來看,基於spring+mongodb的集成工作,完美結束,也很簡單。

剩下來的,重點是mongodb的增刪改查相關的接口研究,是個熟悉的過程,各位朋友,建議去看官網的資料。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM