Mongodb与spring集成

这里咱们用到的是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

<?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>

这样基本配置就完成了mongodb


spring-data-mongodb中的实体映射是经过数据库

MongoMappingConverter这个类实现的。它能够经过注释把app

java类转换为mongodb的文档。
它有如下几种注释:
@Id - 文档的惟一标识,在mongodb中为ObjectId,它是惟一的,经过时间戳+机器标识+进程ID+自增计数器(确保同一秒内产生的Id不会冲突)构成。dom

@Document - 把一个java类声明为mongodb的文档,能够通socket

过collection参数指定这个类对应的文档。maven

@DBRef - 声明相似于关系数据库的关联关系。ps:暂不支持级联的保存功能,当你在本实例中修改了DERef对象里面的值时,单独保存本实例并不能保存DERef引用的对象,它要另外保存,以下面例子的Person和Account。函数

@Indexed - 声明该字段须要索引,建索引能够大大的提升查询效率。this

@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);
相关文章
相关标签/搜索