Mongodb與spring集成(1)------配置html
這裏咱們用到的是spring-data中一個集成mongodb的項目,首先在maven中添加對它的依賴,這裏我用的是1.0.0.M5版本java
<!-- mongodb spring -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.0.0.M5</version>
</dependency>spring
而後是配置文件mongodb
<?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>數據庫
這樣基本配置就完成了,其它深刻操做將在後續文章中說明。app
spring-data-mongodb中的實體映射是經過dom
MongoMappingConverter這個類實現的。它能夠經過註釋把socket
java類轉換爲mongodb的文檔。
它有如下幾種註釋:
@Id - 文檔的惟一標識,在mongodb中爲ObjectId,它是惟一的,經過時間戳+機器標識+進程ID+自增計數器(確保同一秒內產生的Id不會衝突)構成。maven
@Document - 把一個java類聲明爲mongodb的文檔,能夠通ide
過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;
}
與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);