Spring 框架入门教程
1. 1. Spring 框架 2. 2. Spring 5 3. 3. Spring WebFlux 4. 4. 先介绍一下 Spring 5. 5. 什么是 Spring 依赖注入 6. 6. 什么是 Spring IoC 容器 和 Bean 7. 7. Spring Bean 的生命周期 8. 8. Spring REST 开发 9. 9. Spring REST XML 10. 10. Spring RestTemplate 开发 11. 11. Spring AOP 切面编程 12. 12. Spring AOP 方法调优 13. 13. Spring 注解详解 14. 14. Spring 核心注解之 @Autowired 15. 15. Spring 核心注解之 @RequestMapping 16. 16. Spring MVC 开发样例 17. 17. Spring MVC 开发指南 18. 18. Spring MVC 异常处理机制 19. 19. Spring MVC Validator 20. 20. Spring MVC 拦截器 21. 21. Spring MVC 文件上传 22. 22. Spring MVC 国际化(i18n) 23. 23. Spring MVC Hibernate MqSQL 24. 24. Spring ORM 25. 25. Spring ORM JPA 26. 26. Spring Data JPA 27. 27. Spring 事务管理 28. 28. 常用的 Spring JdbcTemplate 29. 29. Spring Security 简介 30. 30. Spring Security 教程 31. 31. Spring Security UserDetailsService 32. 32. Spring MVC 登录注销简单案例 33. 33. Spring Security Roles 34. 34. Spring Boot Tutorial 35. 35. Spring Boot Components 36. 36. Spring Boot CLI Hello World 37. 37. Spring Boot Initilizr Web 38. 38. Spring Boot Initilizr IDE 39. 39. Spring Boot Initilizr CLI 40. 40. Spring Boot Initilizr Tools 41. 41. Spring Boot MongoDB 42. 42. Spring Boot Redis Cache 43. 43. Spring Boot 常见面试问题 44. 44. Spring Batch 45. 45. Spring Batch 批处理示例 46. 46. Spring AMQP 47. 47. Spring RabbitMQ 48. 48. Spring AMQP RabbitMQ 49. 49. Apache ActiveMQ 安装与启动 50. 50. Spring ActiveMQ 教程 51. 51. Spring ActiveMQ 示例 52. 52. Spring JDBC 53. 53. Spring DataSource JNDI 54. 54. Spring Hibernate 55. 55. Spring Primefaces JPA 56. 56. Spring Primefaces MongoDB 57. 57. Spring Primefaces Hibernate 58. 58. SpringRoo Primefaces Hibernate 59. 59. Spring JSF 60. 60. Spring JDF Hibernate 61. 61. Spring Data MongoDB 62. 62. Spring 常见面试问题

61. Spring Data MongoDB

欢迎使用Spring Datamongodb示例。Spring Datamongodb是Spring集成项目之一Spring框架使用最广泛的NoSQL数据库蒙古达.

Spring数据MongoDB

使用Spring的一个主要好处是它提供了与企业应用程序中使用的大多数主要框架的集成。例如,Spring-ORM-Hibernate集成.

我们将在我们的示例项目中使用最新版本的Spring框架和Spring Datamongodb。我们最后的Spring Datamongodb示例项目将如下图所示。

Spring Datamongodb也可以在一个简单的应用程序中使用,不需要使用Spring框架。让我们用一个简单的springmongodb示例来看看这一点。为此,您需要在pom.xml文件文件,它将通过maven可传递依赖项自动包含兼容的MongoDB java驱动程序。


<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-mongodb</artifactId>
	<version>1.5.2.RELEASE</version>
</dependency>

Spring Datamongodb示例和模型Bean

我们将有一个简单的模型bean,其中一些变量将存储在MongoDB数据库中。

Person.java


package com.journaldev.spring.mongodb.model;

import org.springframework.data.annotation.Id;

public class Person {

	//id will be used for storing MongoDB _id
	@Id
	private String id;
	
	private String name;
	private String address;
	
	public Person(){}
	public Person(String i, String n, String a){
		this.id=i;
		this.name=n;
		this.address=a;
	}
	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 String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
	@Override
	public String toString(){
		return id+"::"+name+"::"+address;
	}
}

它是一个简单的javabean,但是有几点您应该知道。

  1. 我们知道MongoDB中的每个文档都需要有一个名为的主键_身份证,我们可以提供它,也可以由MongoDB为我们生成。我们可以利用org.springframework.data.annotation.Id annotation with a model bean variable to map it to _id field.
  2. 如果字段名是“;id”;那么我们不需要使用@id注解,但是使用它是最好的做法。在上面的类中,我们可以跳过@Id注解。
  3. bean中应该始终有id字段,否则它将不会映射到对象的任何属性,并且会丢失主键引用。

现在让我们看看如何使用Spring数据MongoDB在MongoDB数据库上执行CRUD操作。

SpringDataMongoDBMain.java


package com.journaldev.spring.mongodb.main;

import java.net.UnknownHostException;

import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.journaldev.spring.mongodb.model.Person;
import com.mongodb.MongoClient;

public class SpringDataMongoDBMain {

	public static final String DB_NAME = "journaldev";
	public static final String PERSON_COLLECTION = "Person";
	public static final String MONGO_HOST = "localhost";
	public static final int MONGO_PORT = 27017;

	public static void main(String[] args) {
		try {
			MongoClient mongo = new MongoClient(
					MONGO_HOST, MONGO_PORT);
			MongoOperations mongoOps = new MongoTemplate(mongo, DB_NAME);
			Person p = new Person("113", "PankajKr", "Bangalore, India");
			mongoOps.insert(p, PERSON_COLLECTION);

			Person p1 = mongoOps.findOne(
					new Query(Criteria.where("name").is("PankajKr")),
					Person.class, PERSON_COLLECTION);

			System.out.println(p1);
			
			mongoOps.dropCollection(PERSON_COLLECTION);
			mongo.close();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

}

现在,当我在上面运行Spring Datamongodb示例程序时,它会生成以下输出。


02:02:14.785 [main] DEBUG o.s.d.m.c.i.MongoPersistentEntityIndexCreator - Analyzing class class com.journaldev.spring.mongodb.model.Person for index information.
02:02:14.794 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Inserting DBObject containing fields: [_class, _id, name, address] in collection: Person
02:02:14.798 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:02:14.824 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "name" : "PankajKr"} fields: null for class: class com.journaldev.spring.mongodb.model.Person in collection: Person
02:02:14.826 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:02:14.826 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "name" : "PankajKr"} in db.collection: journaldev.Person
113::PankajKr::Bangalore, India
02:02:14.833 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:02:14.835 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Dropped collection [journaldev.Person]

从我们目前的学习中,我们可以总结出以下几点关于Spring Datamongodb。

  1. SpringDataMongoDB提供了MongoDB java驱动程序的包装器,内部使用MongoDB java驱动程序执行数据库操作。
  2. MongoOperations declares a lot of methods for different operations and most of the time, they are sufficient for us. MongoTemplate is the implementation class and it requires Mongo or MongoClient (for newer MongoDB java driver versions) or MongoDbFactory to initialize it. We also need to provide the database name which will be used.
  3. 如果数据库有密码保护,我们可以使用org.springframework.data.authentication.UserCredentials to pass the authentication username and password details.
  4. org.springframework.data.mongodb.core.query.Query and org.springframework.data.mongodb.core.query.Criteria classes are used to define the query used to find particular record or records.
  5. Spring Datamongodb的主要优点是我们不需要担心javabean到mongodbobject的转换,反之亦然,如我们在MongoDB Java示例.

现在让我们继续在Spring环境中使用Spring数据MongoDB。它非常简单,主要需要与配置相关的代码,这些代码可以通过XML、注解或java配置来实现。不过,我将在Spring Datamongodb示例中使用基于XML的配置。

这是我的期末考试pom.xml文件使用Spring框架和Spring数据MongoDB依赖关系。


<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples</groupId>
  <artifactId>SpringMongo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>

		<!-- Generic properties -->
		<java.version>1.6</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

		<!-- Spring -->
		<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
		<spring-data-mongodb.version>1.5.2.RELEASE</spring-data-mongodb.version>

		<!-- Logging -->
		<logback.version>1.0.13</logback.version>
		<slf4j.version>1.7.5</slf4j.version>

	</properties>
	
	<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		
		<dependency>
    		<groupId>org.springframework.data</groupId>
    		<artifactId>spring-data-mongodb</artifactId>
    		<version>${spring-data-mongodb.version}</version>
  		</dependency>
  
		<!-- Logging with SLF4J & LogBack -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${logback.version}</version>
			<scope>runtime</scope>
		</dependency>

	</dependencies>	
</project>

Spring数据MongoDB DAO类

我们将使用DAO模式来公开可以对Person对象执行的不同操作。

PersonDAO.java


package com.journaldev.spring.mongodb.dao;

import com.journaldev.spring.mongodb.model.Person;

public interface PersonDAO {

	public void create(Person p);
	
	public Person readById(String id);
	
	public void update(Person p);
	
	public int deleteById(String id);
}

下面是特定于MongoDB的实现类。

PersonDAOImpl.java


package com.journaldev.spring.mongodb.dao;

import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.journaldev.spring.mongodb.model.Person;
import com.mongodb.WriteResult;

public class PersonDAOImpl implements PersonDAO {

	private MongoOperations mongoOps;
	private static final String PERSON_COLLECTION = "Person";
	
	public PersonDAOImpl(MongoOperations mongoOps){
		this.mongoOps=mongoOps;
	}
	
	@Override
	public void create(Person p) {
		this.mongoOps.insert(p, PERSON_COLLECTION);
	}

	@Override
	public Person readById(String id) {
		Query query = new Query(Criteria.where("_id").is(id));
		return this.mongoOps.findOne(query, Person.class, PERSON_COLLECTION);
	}

	@Override
	public void update(Person p) {
		this.mongoOps.save(p, PERSON_COLLECTION);
	}

	@Override
	public int deleteById(String id) {
		Query query = new Query(Criteria.where("_id").is(id));
		WriteResult result = this.mongoOps.remove(query, Person.class, PERSON_COLLECTION);
		return result.getN();
	}

}

代码非常直接,所以我不想详细解释。

Spring数据MongoDB Bean配置文件

一如既往,这个应用程序最重要的部分将是Spring Bean配置文件。我们将把依赖项注入到不同的bean中并定义它们。

这是我们最后的Spring Bean配置文件。

spring.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="https://www.springframework.org/schema/context"
	xmlns:mongo="https://www.springframework.org/schema/data/mongo"
	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-4.0.xsd
		https://www.springframework.org/schema/data/mongo https://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd">

<mongo:mongo host="localhost" port="27017" id="mongo" />
<mongo:db-factory dbname="journaldev" mongo-ref="mongo" id="mongoDbFactory" />

<bean id="mongoTemplate">
	<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>

<bean id="personDAO">
	<constructor-arg name="mongoOps" ref="mongoTemplate"/>
</bean>
</beans>

应该提供的重要配置是–;Spring Datamongodb模式和MongoDB连接的Mongo实例。为了方便起见,我定义了MongoDbFactory实例,我们也可以像下面这样定义MongoTemplate bean,


<bean id="mongoTemplate">
	<constructor-arg name="mongo" ref="mongo" />
	<constructor-arg name="databaseName" value="journaldev" />
</bean>

Spring数据MongoDB测试程序

最后,让我们编写一个简单的测试程序,并在MongoDB数据库上运行一些CRUD操作。

SpringMongoDBXMLMain.java


package com.journaldev.spring.mongodb.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.journaldev.spring.mongodb.dao.PersonDAO;
import com.journaldev.spring.mongodb.model.Person;

public class SpringMongoDBXMLMain {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
		
		PersonDAO personDAO = ctx.getBean("personDAO", PersonDAO.class);
		
		Person p = new Person(null, "PankajKr", "Bangalore, India");
		
		//create
		personDAO.create(p);
		System.out.println("Generated ID="+p.getId());
		
		//read
		Person p1 = personDAO.readById(p.getId());
		System.out.println("Retrieved Person="+p1);
		
		//update
		p1.setName("David");p1.setAddress("SFO, USA");
		personDAO.update(p1);
		Person temp = personDAO.readById(p1.getId());
		System.out.println("Retrieved Person after update="+temp);
		
		//delete
		int count = personDAO.deleteById(p1.getId());
		System.out.println("Number of records deleted="+count);
		
		ctx.close();

	}

}

现在,当我运行上面的应用程序时,它会生成以下输出。


02:27:34.509 [main] DEBUG o.s.d.m.c.i.MongoPersistentEntityIndexCreator - Analyzing class class com.journaldev.spring.mongodb.model.Person for index information.
02:27:34.516 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Inserting DBObject containing fields: [_class, _id, name, address] in collection: Person
02:27:34.520 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
Generated ID=53f50bbe0364b65dbc0c4753
02:27:34.532 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : "53f50bbe0364b65dbc0c4753"} fields: null for class: class com.journaldev.spring.mongodb.model.Person in collection: Person
02:27:34.533 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:27:34.535 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : { "$oid" : "53f50bbe0364b65dbc0c4753"}} in db.collection: journaldev.Person
Retrieved Person=53f50bbe0364b65dbc0c4753::PankajKr::Bangalore, India
02:27:34.543 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Saving DBObject containing fields: [_class, _id, name, address]
02:27:34.543 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:27:34.545 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : "53f50bbe0364b65dbc0c4753"} fields: null for class: class com.journaldev.spring.mongodb.model.Person in collection: Person
02:27:34.545 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:27:34.546 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : { "$oid" : "53f50bbe0364b65dbc0c4753"}} in db.collection: journaldev.Person
Retrieved Person after update=53f50bbe0364b65dbc0c4753::David::SFO, USA
02:27:34.549 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[journaldev]
02:27:34.550 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Remove using query: { "_id" : { "$oid" : "53f50bbe0364b65dbc0c4753"}} in collection: Person.
Number of records deleted=1
02:27:34.553 [main] INFO  o.s.c.s.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@7a187814: startup date [Thu Aug 21 02:27:33 GMT+05:30 2014]; root of context hierarchy
02:27:34.553 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean "lifecycleProcessor"
02:27:34.553 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3f64b09c: defining beans [mongo,org.springframework.beans.factory.config.CustomEditorConfigurer#0,org.springframework.beans.factory.config.CustomEditorConfigurer#1,org.springframework.beans.factory.config.CustomEditorConfigurer#2,mongoDbFactory,mongoTemplate,personDAO]; root of factory hierarchy
02:27:34.554 [main] DEBUG o.s.b.f.s.DisposableBeanAdapter - Invoking destroy() on bean with name "mongoDbFactory"
02:27:34.554 [main] DEBUG o.s.b.f.s.DisposableBeanAdapter - Invoking destroy() on bean with name "mongo"

请注意,当Spring context关闭时,它也会负责关闭MongoDB连接,因此我们不需要担心这个问题。

另外,我在每个查询中都提供了MongoDB集合名,如果集合名符合java命名约定,我们可以跳过。例如,对于“;Person”;和“;PersonAddress”;对象,Spring MongoDB使用的默认集合名将分别为“;Person”;和“;PersonalAddress”。

我们也可以使用org.springframework.data.mongodb.core.mapping.Document annotation with Model class to define the collection name to be used for saving the document.

基于Spring数据MongoDB注解的配置

如果您想使用基于注解的配置,可以参考下面的配置类。

SpringMongoDBConfiguration.java


package com.journaldev.spring.mongodb.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
 
import com.mongodb.MongoClient;
 
@Configuration
public class SpringMongoDBConfiguration {
 
	public @Bean MongoDbFactory getMongoDbFactory() throws Exception {
		return new SimpleMongoDbFactory(new MongoClient("localhost",27017), "journaldev");
	}

	public @Bean MongoTemplate getMongoTemplate() throws Exception {
		MongoTemplate mongoTemplate = new MongoTemplate(getMongoDbFactory());
		return mongoTemplate;
	}
}

我们还需要其他配置来将mongotemplatebean注入到DAO实现类中,我将这部分留给您。

为MongoDB连接选项使用MongoOptions

我们可以利用MongoOptions to define MongoDB options in spring bean configuration file like below. There are some other configuration options too, that you can check for optimizing your connections.


<mongo:mongo host="localhost" port="27017">
    <mongo:options connections-per-host="4"
                   connect-timeout="1000"
                   max-wait-time="1500"
                   auto-connect-retry="true"
                   socket-keep-alive="true"
                   socket-timeout="1500"
                   write-fsync="true" />
  </mongo:mongo>

Spring数据MongoDB示例摘要

我希望本教程足够好,让您开始使用Spring Datamongodb,它不可能涵盖所有内容。您应该更多地研究查询、条件和MongoTemplate方法以了解更多信息。你可以从下面的链接下载最终的项目。