Spring Data MongoDB示例

时间:2020-02-23 14:35:51  来源:igfitidea点击:

欢迎使用Spring Data MongoDB示例。
Spring Data MongoDB是用于将Spring Framework与最广泛使用的NoSQL数据库MongoDB集成的Spring项目之一。

Spring Data MongoDB

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

对于示例项目,我们将使用最新版本的Spring Framework和Spring Data MongoDB。
我们最终的Spring Data MongoDB示例项目将如下图所示。

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

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

Spring Data MongoDB示例–模型Bean

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

Person.java

package com.theitroad.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;
	}
}

这是一个简单的Java Bean,但是您应该知道的一些要点。

  • 我们知道MongoDB中的每个文档都必须具有名称为_id的主键,我们可以提供它,也可以由MongoDB为其生成。
    我们可以将" org.springframework.data.annotation.Id"注释与模型bean变量一起使用,以将其映射到_id字段。

  • 如果字段名称是" id",则我们不需要使用@Id注释,但是最好的用法是使用它。
    在上面的类中,我们可以跳过@Id注释。

  • 您应该在bean中始终具有id字段,否则它将不会被映射到对象的任何属性,并且您将失去主键引用。

现在,让我们看看如何轻松地使用Spring Data MongoDB对MongoDB数据库执行CRUD操作。

SpringDataMongoDBMain.java

package com.theitroad.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.theitroad.spring.mongodb.model.Person;
import com.mongodb.MongoClient;

public class SpringDataMongoDBMain {

	public static final String DB_NAME = "theitroad";
	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", "hymanKr", "Bangalore, San Franceco");
			mongoOps.insert(p, PERSON_COLLECTION);

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

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

}

现在,当我在Spring Data MongoDB示例程序上方运行时,它将生成以下输出。

02:02:14.785 [main] DEBUG o.s.d.m.c.i.MongoPersistentEntityIndexCreator - Analyzing class class com.theitroad.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=[theitroad]
02:02:14.824 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "name" : "hymanKr"} fields: null for class: class com.theitroad.spring.mongodb.model.Person in collection: Person
02:02:14.826 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[theitroad]
02:02:14.826 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "name" : "hymanKr"} in db.collection: theitroad.Person
113::hymanKr::Bangalore, San Franceco
02:02:14.833 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[theitroad]
02:02:14.835 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - Dropped collection [theitroad.Person]

从我们的学习到现在,我们可以总结出Spring Data MongoDB的以下几点。

  • Spring Data MongoDB在MongoDB Java驱动程序上提供了包装,内部使用MongoDB Java驱动程序执行数据库操作。

  • MongoOperations声明了许多用于不同操作的方法,并且在大多数情况下,它们对我们来说已经足够了。
    MongoTemplate是实现类,它需要Mongo或者MongoClient(对于较新的MongoDB Java驱动程序版本)或者MongoDbFactory进行初始化。
    我们还需要提供将要使用的数据库名称。

  • 如果数据库受密码保护,我们可以使用org.springframework.data.authentication.UserCredentials传递身份验证用户名和密码详细信息。

  • org.springframework.data.mongodb.core.query.Query和org.springframework.data.mongodb.core.query.Criteria类用于定义用于查找特定记录的查询。

  • Spring Data MongoDB的主要好处在于,我们无需担心将Java bean转换为Mongo DBObject,反之亦然,就像在MongoDB Java Example中看到的那样。

现在,让我们继续在Spring环境中使用Spring Data MongoDB。
这非常简单,并且主要需要与配置相关的代码,我们可以通过XML,注释或者Java config来完成这些代码。
但是,对于Spring Data MongoDB示例,我将使用基于XML的配置。

这是我最后带有Spring Framework和Spring Data MongoDB依赖项的pom.xml。

<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 Data MongoDB DAO类

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

PersonDAO.java

package com.theitroad.spring.mongodb.dao;

import com.theitroad.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.theitroad.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.theitroad.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 Data 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="theitroad" mongo-ref="mongo" id="mongoDbFactory" 

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
	<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" 
</bean>

<bean id="personDAO" class="com.theitroad.spring.mongodb.dao.PersonDAOImpl">
	<constructor-arg name="mongoOps" ref="mongoTemplate"
</bean>
</beans>

应该存在的重要配置是–用于MongoDB连接的Spring Data MongoDB模式和Mongo实例。
为了方便起见,我已经定义了MongoDbFactory实例,我们也可以如下定义MongoTemplate bean,

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
	<constructor-arg name="mongo" ref="mongo" 
	<constructor-arg name="databaseName" value="theitroad" 
</bean>

Spring Data MongoDB测试程序

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

SpringMongoDBXMLMain.java

package com.theitroad.spring.mongodb.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.theitroad.spring.mongodb.dao.PersonDAO;
import com.theitroad.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, "hymanKr", "Bangalore, San Franceco");
		
		//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.theitroad.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=[theitroad]
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.theitroad.spring.mongodb.model.Person in collection: Person
02:27:34.533 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[theitroad]
02:27:34.535 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : { "$oid" : "53f50bbe0364b65dbc0c4753"}} in db.collection: theitroad.Person
Retrieved Person=53f50bbe0364b65dbc0c4753::hymanKr::Bangalore, San Franceco
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=[theitroad]
02:27:34.545 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : "53f50bbe0364b65dbc0c4753"} fields: null for class: class com.theitroad.spring.mongodb.model.Person in collection: Person
02:27:34.545 [main] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[theitroad]
02:27:34.546 [main] DEBUG o.s.data.mongodb.core.MongoTemplate - findOne using query: { "_id" : { "$oid" : "53f50bbe0364b65dbc0c4753"}} in db.collection: theitroad.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=[theitroad]
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上下文关闭时,它也将关闭MongoDB连接,因此我们不必为此担心。

另外,我在每个查询中都提供了MongoDB集合名称,如果集合名称符合Java命名约定,我们可以跳过它。
例如,对于" Person"和" PersonAddress"对象,Spring MongoDB使用的默认集合名称分别为" person"和" personAddress"。

我们还可以将" org.springframework.data.mongodb.core.mapping.Document"注释与Model类一起使用,以定义用于保存文档的集合名称。

基于Spring Data MongoDB注释的配置

如果要使用基于注释的配置,则可以使用下面的Configuration类作为参考。

SpringMongoDBConfiguration.java

package com.theitroad.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), "theitroad");
	}

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

我们还需要其他配置才能将MongoTemplate bean注入我们的DAO实现类中,这部分留给您。

对MongoDB连接选项使用MongoOptions

我们可以使用MongoOptions在Spring bean配置文件中定义MongoDB选项,如下所示。
还有其他一些配置选项,您可以检查这些选项以优化连接。

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