Spring Data MongoDB

用途

快速集成 MongoDB,不用写一行 MongoDB 的 CRUD 语句。而是使用 Spring Data 独有的方法命名方式定义数据库操作,并且可以方便地替换各种数据库,比如 MySQL。

快速开始

(0)开始之前

确保已有可连接的 MongoDB

(1)依赖引入

build.gradle 中添加如下依赖。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-mongodb")
}

(2)配置 MongoDB 连接

这里配置了 MongoDB 的连接地址和使用的数据库,还配置了扫描 Repositories 的位置。Repositories 我们后面会讲到是什么。

@Configuration
@EnableMongoRepositories(basePackages = "com.example.dao")
public class MongoConfig {

  @Bean
  public MongoOperations mongoTemplate() throws UnknownHostException {
    return new MongoTemplate(mongoDbFactory());
  }

  @Bean
  public MongoDbFactory mongoDbFactory() throws UnknownHostException {
    return new SimpleMongoDbFactory(new MongoClientURI("mongodb://localhost:27017/test"));
  }

}

(3)定义一个简单的实体类

实体类是一个 POJO,不过会多一些注解。简单介绍下这些注解吧:

  1. @Document ,用于自定义 MongoDB 中 Collection 的名称,默认情况下 collection 值为空,使用类名的小写形式作为 Collection 的名称
  2. @Id ,用于指定 MongoDB 内部使用字段 _id 的值,如果不指定,则使用自动生成的值。
  3. @Field ,用于指定字段存储时的名称,如果不指定,则直接使用字段名。如果字段名为id,那么一定要使用该注解,否则会读取时使用系统的_id作为 id 的值
  4. @Indexed,用于为指定字段添加索引,会调用 MongoDB 的 createIndex 方法。值得注意的是:必须 @Document 注解,否则不会自动生成索引
@Document(collection = "Customer")
public class Customer {
    @Id
    public String id;

    @Indexed
    @Field("first_name")
    public String firstName;

    @Field("last_name")
    public String lastName;

    public Customer() {}

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

(4)定义一个 Repository

MongoRepository 中定义的基本的 CRUD 操作,你可以自定义查询方法,不过要遵守一定的规范,Spring Data MongoDB 会根据方法名和参数去执行数据库操作。这个规范参见下文 支持的查询方法关键字列表。此处只需要了解有 findByXx 的方法名即可。

public interface CustomerRepository extends MongoRepository<Customer, String> {

    public Customer findByFirstName(String firstName);
    public List<Customer> findByLastName(String lastName);
}

(5)让 Spring Boot 自动装配 CustomerRepository

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private CustomerRepository repository;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        repository.deleteAll();

        // save a couple of customers
        repository.save(new Customer("Alice", "Smith"));
        repository.save(new Customer("Bob", "Smith"));

        System.out.println("-------------------------------");

        // fetch an individual customer
        System.out.println(repository.findByFirstName("Alice"));
    }
}

(6)使用 MongoDB 命令行查询

$ mongo
> use test
> db.Customer.find({})

深入探讨

常用的匹配注解列表

Annotation Desc
@Id 用于指定 MongoDB 内部使用字段 _id 的值,如果不指定,则使用自动生成的值。
@Field 用于指定数据库中存储的字段名。
@Document 用于指定该类的实例对应 MongoDB 的某个指定 Collection 下的 Document。
@Indexed 用于为指定字段添加索引。@Indexed(unique = true) 可注解唯一键
@CompoundIndex 用于指定复合索引。
@Transient 用于将某些字段排除,不与数据库匹配。
@Version 用于指定字段的版本,默认值为 0,在每次更新字段后自增。

复合索引用例:

@Document
@CompoundIndexes({
    // lastName 升序,age 降序的复合索引,名称为 age_idx。
    @CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")
})
public class Person<T extends Address> {
    //...
}

支持的查询方法关键字列表

Keyword Sample Logical result
After findByBirthdateAfter(Date date) {"birthdate" : {"$gt" : date}}
GreaterThan findByAgeGreaterThan(int age) {"age" : {"$gt" : age}}
GreaterThanEqual findByAgeGreaterThanEqual(int age) {"age" : {"$gte" : age}}
Before findByBirthdateBefore(Date date) {"birthdate" : {"$lt" : date}}
LessThan findByAgeLessThan(int age) {"age" : {"$lt" : age}}
LessThanEqual findByAgeLessThanEqual(int age) {"age" : {"$lte" : age}}
Between findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" : to}}
In findByAgeIn(Collection ages) {"age" : {"$in" : [ages…]}}
NotIn findByAgeNotIn(Collection ages) {"age" : {"$nin" : [ages…]}}
IsNotNull, NotNull findByFirstnameNotNull() {"firstname" : {"$ne" : null}}
IsNull, Null findByFirstnameNull() {"firstname" : null}
Like, StartingWith, EndingWith findByFirstnameLike(String name) {"firstname" : name} (name as regex)
NotLike, IsNotLike findByFirstnameNotLike(String name) {"firstname" : { "$not" : name }} (name as regex)
Containing on String findByFirstnameContaining(String name) {"firstname" : name} (name as regex)
NotContaining on String findByFirstnameNotContaining(String name) {"firstname" : { "$not" : name}} (name as regex)
Containing on Collection findByAddressesContaining(Address address) {"addresses" : { "$in" : address}}
NotContaining on Collection findByAddressesNotContaining(Address address) {"addresses" : { "$not" : { "$in" : address}}}
Regex findByFirstnameRegex(String firstname) {"firstname" : {"$regex" : firstname }}
(No keyword) findByFirstname(String name) {"firstname" : name}
Not findByFirstnameNot(String name) {"firstname" : {"$ne" : name}}
Near findByLocationNear(Point point) {"location" : {"$near" : [x,y]}}
Near findByLocationNear(Point point, Distance max) {"location" : {"$near" : [x,y], "$maxDistance" : max}}
Near findByLocationNear(Point point, Distance min, Distance max) {"location" : {"$near" : [x,y], "$minDistance" : min, "$maxDistance" : max}}
Within findByLocationWithin(Circle circle) {"location" : {"$geoWithin" : {"$center" : [ [x, y], distance]}}}
Within findByLocationWithin(Box box) {"location" : {"$geoWithin" : {"$box" : [ [x1, y1], x2, y2]}}}
IsTrue, True findByActiveIsTrue() {"active" : true}
IsFalse, False findByActiveIsFalse() {"active" : false}
Exists findByLocationExists(boolean exists) {"location" : {"$exists" : exists }}

Tip:将以上的 findBy 替换成 deleteBy 含义就变成了:查找后进行删除操作。

下面是一个使用示例:查询指定状态集合的 JobFlow。

// 方式一:使用 SqEL(Spring 表达式)
@Query("{ 'status': { $in: ?0 } }")
List<JobFlow> findByStatus(String... status);
// 方式二:使用 In
List<JobFlow> findByStatusIn(List<String> statusList);

save 的原理

// SimpleMongoRepository.java
public <S extends T> S save(S entity) {

    Assert.notNull(entity, "Entity must not be null!");

    if (entityInformation.isNew(entity)) {
        mongoOperations.insert(entity, entityInformation.getCollectionName());
    } else {
        mongoOperations.save(entity, entityInformation.getCollectionName());
    }

    return entity;
}

public <S extends T> List<S> save(Iterable<S> entities) {

    Assert.notNull(entities, "The given Iterable of entities not be null!");

    List<S> result = convertIterableToList(entities);
    boolean allNew = true;

    for (S entity : entities) {
        if (allNew && !entityInformation.isNew(entity)) {
            allNew = false;
        }
    }

    if (allNew) {
        mongoOperations.insertAll(result);
    } else {

        for (S entity : result) {
            save(entity);
        }
    }

    return result;
}
// AbstractEntityInformation.java
public boolean isNew(T entity) {

    ID id = getId(entity);
    Class<ID> idType = getIdType();

    if (!idType.isPrimitive()) {
        return id == null;
    }

    if (id instanceof Number) {
        return ((Number) id).longValue() == 0L;
    }

    throw new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType));
}

参考

  1. Spring Data MongoDB - Reference Documentation - spring.io
  2. Accessing Data with MongoDB - spring.io
  3. Working with Spring Data Repositories - spring.io

原文地址:https://www.cnblogs.com/lshare/p/11334476.html

时间: 2024-11-05 22:41:56

Spring Data MongoDB的相关文章

[Spring Data MongoDB]学习笔记--建立数据库的连接

1. 有了上一篇的Mongo后,连接数据库我们还需要更多的信息,比如数据库名字,用户名和密码等. 我们可以继续来配置MongoDbFactory的实例. public interface MongoDbFactory { DB getDb() throws DataAccessException; DB getDb(String dbName) throws DataAccessException; } 然后我们可以继续用MongoDbFactory来创建MongoTemplate的实例. pu

Spring Data MongoDB实战(上)

Spring Data MongoDB实战(上) 作者:chszs,版权所有,未经同意,不得转载.博主主页:http://blog.csdn.net/chszs 本文会详细展示Spring Data MongoDB是如何访问MongoDB数据库的.MongoDB是一个开源的文档型NoSQL数据库,而Spring Data MongoDB是Spring Data的模块之一,专用于访问MongoDB数据库.Spring Data MongoDB模块既提供了基于方法名的查询方式,也提供了基于注释的查询

Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)

Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 六: MongoDB查询(游标操作.游标信息)(三) 一.简介 SpringData  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的find的操作,我们上一篇介绍了基本文档的查询,我们今天介绍分页查询,分页查询是返回到匹配文档的游标,可以随意修改查询限制.跳跃.和排序顺序的功能. 我

[Spring Data MongoDB]学习笔记--牛逼的MongoTemplate

MongoTemplate是数据库和代码之间的接口,对数据库的操作都在它里面. 注:MongoTemplate是线程安全的. MongoTemplate实现了interface MongoOperations,一般推荐使用MongoOperations来进行相关的操作. MongoOperations mongoOps = new MongoTemplate(new SimpleMongoDbFactory(new Mongo(), "database")); MongoDB docu

[Spring Data MongoDB]学习笔记--注册一个Mongo实例

1. 通过Java based bean metadata @Configuration public class AppConfig { public @Bean Mongo mongo() throws UnknownHostExceptioin { return new Mongo("localhost"); } } 上面的方式包含异常处理,这并不是我们想要的. 所以,应该尽量用下面这种方式MongoFactoryBean,或者后面的xml方式. @Configuration p

[Spring Data MongoDB]学习笔记--_id和类型映射

_id字段的映射: MongoDB要求所有的document都要有一个_id的字段. 如果我们在使用中没有传入_id字段,它会自己创建一个ObjectId. { "_id" : ObjectId("53e0ff0b0364cb4a98ce3bfd"), "_class" : "org.springframework.data.mongodb.examples.hello.domain.Person", "name&q

Spring Data MongoDB 二:添加、删除操作

一.简介 Spring  Data  MongoDB 项目提供与MongoDB文档数据库的集成,Spring与Hibernate集成时,Spring提供了org.springframework.orm.hibernate3.HibernateTemplate实现了对数据的CRUD操作, Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,包括对集成的对象映射文件和PO

Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

一.简介 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我们介绍了对MongoDB的新增和删除, 今天我们要介绍Java代码实现对MongoDB实现查询操作. 我们回顾一下,我们在之前介绍了MongoDB的基本文档查询,MongoDB的查询语法: db.orders.find({{<field1>:<value1>,<field2>

Spring Data MongoDB example with Spring MVC 3.2

Spring Data MongoDB example with Spring MVC 3.2 Here is another example web application built with Spring MVC 3.2 and Spring Data 1.2, integrating with the MongoDB document database. STEP 1: Create new webapp project, I will use maven for this. (Note

[Spring Data MongoDB]学习笔记--MapReduce

mongodb的MapReduce主要包含两个方法:map和reduce. 举个例子,假设现在有下面3条记录 { "_id" : ObjectId("4e5ff893c0277826074ec533"), "x" : [ "a", "b" ] } { "_id" : ObjectId("4e5ff893c0277826074ec534"), "x"