spring-data-mongodb


【引入maven依賴】
<!-- mongodb spring -->
<dependency>
     <groupId>org.springframework.data</groupId> 
     <artifactId>spring-data-mongodb</artifactId> 
     <version>1.0.0.M5</version> 
</dependency>

【修改配置文件】
<?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/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/data/mongo
           http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
     <context:property-placeholder location="classpath*:META-INF/mongodb/mongodb.properties"/>

    <!-- 定義mongo對象,對應的是mongodb官方jar包中的Mongo,replica-set設置集群副本的ip地址和端口 -->
     <mongo:mongo id="mongo" replica-set="localhost:27017">
         <!-- 一些連接屬性的設置 -->
         <mongo:options 
              connections-per-host="${mongo.connectionsPerHost}"
              threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}" 
              connect-timeout="${mongo.connectTimeout}"
              max-wait-time="${mongo.maxWaitTime}"
              auto-connect-retry="${mongo.autoConnectRetry}"
              socket-keep-alive="${mongo.socketKeepAlive}"
              socket-timeout="${mongo.socketTimeout}"
              slave-ok="${mongo.slaveOk}"
              write-number="1"
              write-timeout="0"
              write-fsync="true"/>
     </mongo:mongo>

    <!-- mongo的工廠,通過它來取得mongo實例,dbname為mongodb的數據庫名,沒有的話會自動創建 -->
     <mongo:db-factory dbname="test" mongo-ref="mongo"/>

    <!-- mongodb的主要操作對象,所有對mongodb的增刪改查的操作都是通過它完成 -->
     <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
       <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
     </bean>

    <!-- 映射轉換器,掃描back-package目錄下的文件,根據注釋,把它們作為mongodb的一個collection的映射 --> 
     <mongo:mapping-converter base-package="com.xxx.xxx.domain" />

    <!-- mongodb bean的倉庫目錄,會自動掃描擴展了MongoRepository接口的接口進行注入 -->
     <mongo:repositories base-package="com.xxx.xxx.persist.mongodb"/>

    <!-- To translate any MongoExceptions thrown in @Repository annotated classes -->
     <context:annotation-config />

</beans> 

【實體映射】
MongoMappingConverter這個類實現的。它可以通過注釋把

java類轉換為mongodb的文檔。
它有以下幾種注釋:
@Id - 文檔的唯一標識,在mongodb中為ObjectId,它是唯一的,通過時間戳+機器標識+進程ID+自增計數器(確保同一秒內產生的Id不會沖突)構成。
@Document - 把一個java類聲明為mongodb的文檔,可以通過collection參數指定這個類對應的文檔。
@DBRef - 聲明類似於關系數據庫的關聯關系。ps:暫不支持級聯的保存功能,當你在本實例中修改了DERef對象里面的值時,單獨保存本實例並不能保存DERef引用的對象,它要另外保存,如下面例子的Person和Account。
@Indexed - 聲明該字段需要索引,建索引可以大大的提高查詢效率。
@CompoundIndex - 復合索引的聲明,建復合索引可以有效地提高多字段的查詢效率。
@GeoSpatialIndexed - 聲明該字段為地理信息的索引。
@Transient - 映射忽略的字段,該字段不會保存到mongodb。
@PersistenceConstructor - 聲明構造函數,作用是把從數據庫取出的數據實例化為對象。該構造函數傳入的值為從DBObject中取出的數據。

以下引用一個官方文檔的例子:
Person類
@Document(collection="person") 
@CompoundIndexes({ 
     @CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}") 
}) 
public class Person<T extends Address> {
  
   @Id 
   private String id; 
   @Indexed(unique = true) 
   private Integer ssn; 
   private String firstName; 
   @Indexed 
   private String lastName; 
   private Integer age; 
   @Transient 
   private Integer accountTotal; 
   @DBRef 
   private List<Account> accounts; 
   private T address; 

  public Person(Integer ssn) { 
     this.ssn = ssn; 
   } 

  @PersistenceConstructor 
   public Person(Integer ssn, String firstName, String lastName, Integer age, T address) {
     this.ssn = ssn; 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.age = age; 
     this.address = address; 
   }
}

Account類
@Document 
public class Account { 

  @Id 
   private ObjectId id; 
   private Float total; 

【MongoRepository實現增刪改查和復雜查詢】
與HibernateRepository類似,通過繼承MongoRepository接口,我們可以非常方便地實現對一個對象的增刪改查,要使用Repository的功能,先繼承MongoRepository<T, TD>接口,其中T為倉庫保存的bean類,TD為該bean的唯一標識的類型,一般為ObjectId。之后在service中注入該接口就可以使用,無需實現里面的方法,spring會根據定義的規則自動生成。

例:
public interface PersonRepository extends MongoRepository<Person, ObjectId>{ 
     //這里可以添加額外的查詢方法  

但是MongoRepository實現了的只是最基本的增刪改查的功能,要想增加額外的查詢方法,可以按照以下規則定義接口的方法。自定義查詢方法,格式為“findBy+字段名+方法后綴”,方法傳進的參數即字段的值,此外還支持分頁查詢,通過傳進一個Pageable對象,返回Page集合。

例:

public interface PersonRepository extends MongoRepository<Person, ObjectId>{ 
     //查詢大於age的數據   
     public Page<Product> findByAgeGreaterThan(int age,Pageable page) ; 

  
下面是支持的查詢類型,每三條數據分別對應:(方法后綴,方法例子,mongodb原生查詢語句)
GreaterThan(大於)
findByAgeGreaterThan(int age)
{"age" : {"$gt" : age}}

LessThan(小於)
findByAgeLessThan(int age)
{"age" : {"$lt" : age}}

Between(在...之間)
findByAgeBetween(int from, int to)
{"age" : {"$gt" : from, "$lt" : to}}

IsNotNull, NotNull(是否非空)
findByFirstnameNotNull()
{"age" : {"$ne" : null}}

IsNull, Null(是否為空)
findByFirstnameNull()
{"age" : null}

Like(模糊查詢)
findByFirstnameLike(String name)
{"age" : age} ( age as regex)

(No keyword) findByFirstname(String name)
{"age" : name}

Not(不包含)
findByFirstnameNot(String name)
{"age" : {"$ne" : name}}

Near(查詢地理位置相近的)
findByLocationNear(Point point)
{"location" : {"$near" : [x,y]}}

Within(在地理位置范圍內的)
findByLocationWithin(Circle circle)
{"location" : {"$within" : {"$center" : [ [x, y], distance]}}}

Within(在地理位置范圍內的)
findByLocationWithin(Box box)
{"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}}

盡管以上查詢功能已經很豐富,但如果還不能滿足使用情況的話可以用一下方法---基於mongodb原本查詢語句的查詢方式。
例:在原接口中加入
@Query("{ 'name':{'$regex':?2,'$options':'i'}, sales': {'$gte':?1,'$lte':?2}}") 
public Page<Product> findByNameAndAgeRange(String name,double ageFrom,double ageTo,Pageable page); 
注釋Query里面的就是mongodb原來的查詢語法,我們可以定義傳進來的查詢參數,通過坐標定義方法的參數。

還可以在后面指定要返回的數據字段,如上面的例子修改如下,則只通過person表里面的name和age字段構建person對象。
@Query(value="{ 'name':{'$regex':?2,'$options':'i'}, sales':{'$gte':?1,'$lte':?2}}",fields="{ 'name' : 1, 'age' : 1}")  
public Page<Product> findByNameAndAgeRange(String name,double ageFrom,double ageTo,Pageable page); 

【官方地址】
http://projects.spring.io/spring-data-mongodb/

【示例代碼】
https://github.com/snzigod/jdish/tree/master/spring/spring-data-mongodb

【參考資料】

clip_image001

clip_image002


免責聲明!

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



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