Spring Data for MongoDB是Spring Data的一个子模块。 目标是为MongoDB提供一个相近的一致的基于Spring的编程模型。

Spring Data for MongoDB核心功能是映射POJO到Mongo的DBCollection中的文档,并且提供Repository 风格数据访问层。


特性:

1.可以通过@Configuration注解或者XML风格配置

2.MongoTemplate 辅助类 (类似JdbcTemplate),方便常用的CRUD操作

3.异常转换

4.丰富的对象映射

5.通过注解指定对象映射

6.持久化和映射声明周期事件

7.通过MongoReader/MongoWriter 定义底层的映射

8.基于Java的Query, Criteria, Update DSL

9.自动实现Repository,可以提供定制的查找

10.QueryDSL 支持类型安全的查询

11.跨数据库平台的持久化 - 支持JPA with Mongo

12.GeoSpatial 支持

13.Map-Reduce 支持

14.JMX管理和监控

15.CDI 支持

16.GridFS 支持


Spring Data for MongoDB提供了两种编程风格来应用MongoDB:

1.Spring Data Repository 风格

Spring Data提供了repository 抽象方式,可以极大的减少数据访问层千篇一律的类似的重复的代码。 基本DAO都会实现,find,findAll, findById, save, delete,update等方法,而且代码逻辑基本一致。Spring Data提供了简化方法,通过接口定义 Spring Data通过Proxy自动提供具体的实现。

2.MongoTemplate方式

Spring Data for MongoDB还提供了另外一种方式, 类似JdbcTemplate的方式。 这种方式你可以自己定义你的repository的编程方式。 这种方式让你感觉更灵活, 不被上面的各种约定束缚住。你可以通过XML或者JavaConfig方式配置MongoTemplate.

官网:http://projects.spring.io/spring-data-mongodb/

下面我们实例说明spring-data-mongodb的使用。

1.添加依赖jar包


<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.13.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>1.6.2.RELEASE</version>
		</dependency>


2.定义实体

spring-data-mongodb中的实体映射是通过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中取出的数据。


package cn.slimsmart.mongodb.demo.spring;

import java.util.Date;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "user") 
@CompoundIndexes({  
    @CompoundIndex(name = "birthday_idx", def = "{'name': 1, 'birthday': -1}")  
})  
public class User {
	
	@Id
	@Indexed(unique = true)
	private String id;
	@Indexed
	private String name;
	private Date birthday;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	@Override
	public String toString() {
		return "User[id="+id+",name="+name+",birthday="+birthday+"]";
	}
	
}

3.CRUD实现


package cn.slimsmart.mongodb.demo.spring;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.mongodb.DB;

@Repository
public class UserRepository {

	@Autowired
	private MongoTemplate mongoTemplate;

	public void test() {
		Set<String> colls = this.mongoTemplate.getCollectionNames();
		for (String coll : colls) {
			System.out.println("CollectionName=" + coll);
		}
		DB db = this.mongoTemplate.getDb();
		System.out.println("db=" + db.toString());
	}

	public void createCollection() {
		if (!this.mongoTemplate.collectionExists(User.class)) {
			this.mongoTemplate.createCollection(User.class);
		}
	}

	public List<User> findList(int skip, int limit) {
		Query query = new Query();
		query.with(new Sort(new Order(Direction.ASC, "id")));
		query.skip(skip).limit(limit);
		return this.mongoTemplate.find(query, User.class);
	}

	public List<User> findListByName(String name) {
		Query query = new Query();
		query.addCriteria(new Criteria("name").is(name));
		return this.mongoTemplate.find(query, User.class);
	}

	public User findOne(String id) {
		Query query = new Query();
		query.addCriteria(new Criteria("_id").is(id));
		return this.mongoTemplate.findOne(query, User.class);
	}

	public void insert(User entity) {
		this.mongoTemplate.insert(entity);

	}

	public void update(User entity) {
		Query query = new Query();
		query.addCriteria(new Criteria("_id").is(entity.getId()));
		Update update = new Update();
		update.set("birthday", entity.getBirthday());
		update.set("name", entity.getName());
		this.mongoTemplate.updateFirst(query, update, User.class);
	}
}


4.spring配置

mongodb.properties


monngo.host=192.168.36.61
monngo.port=23000

application-context.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"
	xsi:schemaLocation="
	http://www.springframework.org/schema/data/mongo 
	http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="cn.slimsmart.mongodb.demo.spring" />
	<context:property-placeholder location="classpath*:mongodb.properties" />

	<mongo:mongo id="mongo" host="${monngo.host}" port="${monngo.port}">
		<mongo:options connections-per-host="8"
			threads-allowed-to-block-for-connection-multiplier="4"
			connect-timeout="1000" max-wait-time="1500" auto-connect-retry="true"
			socket-keep-alive="true" socket-timeout="1500" slave-ok="true"
			write-number="1" write-timeout="0" write-fsync="true" />
	</mongo:mongo>
	<!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->
	<mongo:db-factory id="mongoDbFactory" dbname="User"
		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的映射 User -->
	<mongo:mapping-converter base-package="cn.slimsmart.mongodb.demo.spring" />

	<!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->
	<mongo:repositories base-package="cn.slimsmart.mongodb.demo.spring" />
	 <!-- To translate any MongoExceptions thrown in @Repository annotated classes --> 
	<context:annotation-config />

</beans>

部署几个Mongos,使用同一个配置库,问题解决,具体配置如下:



<mongo:mongo  id="mongo"replica-set="${mongodb.replica-set}">

        <mongo:options connections-per-host="${mongodb.connectionsPerHost}"

            threads-allowed-to-block-for-connection-multiplier="${mongodb.threads-allowed-to-block-for-connection-multiplier}"

            connect-timeout="${mongodb.connect-timeout}"max-wait-time="${mongodb.max-wait-time}"auto-connect-retry="${mongodb.auto-connect-retry}"

            socket-keep-alive="${mongodb.socket-keep-alive}"socket-timeout="${mongodb.socket-timeout}"slave-ok="${mongodb.slave-ok}"

            write-number="${mongodb.write-number}"write-timeout="${mongodb.write-timeout}"write-fsync="${mongodb.write-fsync}"/>

    </mongo:mongo>


其中,replica-set格式:ip1:port,ip2:port,...


5.测试


Test.java


package cn.slimsmart.mongodb.demo.spring;

import java.util.Date;
import java.util.UUID;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");  
		UserRepository userRepository = context.getBean(UserRepository.class);
		userRepository.test();
		userRepository.createCollection();
		User user = new User();
		user.setId(UUID.randomUUID().toString());
		user.setName("jack");
		user.setBirthday(new Date());
		userRepository.insert(user);
		System.out.println(userRepository.findListByName("jack"));;
	}
}

参考文档:

1.Spring Data for Mongo 介绍

2.详解Spring整合MongoDB 3.Spring Mongodb集成

4.使用Spring Data来操作MongoDB