SpringDataMongoDB-1

103 阅读3分钟

SpringDataMongoDB-1

有两种方式来操作MongoDB,使用它最原始的Client和使用SpringDataMongoDB来操作。这里主要介绍具体的使用方式。

MongoDB官方文档

MongoDB下载

SpringData-MongoDB官方文档

写在前面

Spring Data MongoDB 3.x的版本>=JDK1.8,Spring的版本>=5.3.19

下面的表格列出了SpringDataMongo、Driver、服务器版本的兼容性。

Spring Data Release TrainSpring Data MongoDBDriver VersionServer Version
2021.03.2.x4.1.x4.4.x
2020.03.1.x4.1.x4.4.x
Neumann3.0.x4.0.x4.4.x
Moore2.2.x3.11.x/Reactive Streams 1.12.x4.2.x
Lovelace2.1.x3.8.x/Reactive Streams 1.9.x4.0.x

文章中的例子是在SpringBoot中搭建的

环境搭建

pom文件

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

流程

大体的流程如下:

  1. 定义Repository接口。
  2. 定义查询方法。
  3. 创建Repository实例。(不是必须)
  4. 自己实现SpringData Repository(不是必须)

大多数的情况下,前面的两种就已经满足我们的开发了,Spring Data的目的是为了减少编码量。但要是自己需要自己自定义一些方法,就可以自己实现Repository。

快速开始

前提是已经把MongoDB搭建好了

  1. 实体类

    @Document
    @Data
    @Accessors(chain = true)
    @ToString
    public class Book {
        private String id;
        private String name;
        private String shortName;
        private Integer count;
        private Double price;
        private LocalDate publishTime;
    }
    
  2. BookRepository接口

    public interface BookRepository extends MongoRepository<Book, String> {
    }
    
  3. 测试类

    
    @SpringBootTest(classes = SpringdataMongodbApplication.class)
    public class BookTest {
        @Autowired
        BookRepository bookRepository;
        @Autowired
        MongoTemplate mongoTemplate;
    
        @Test
        public void testSaveBooks() {
            ArrayList<Book> param = new ArrayList<>();
            List<String> bookName = Arrays.asList("java", "go", "php", "c", "c++", "Mysql");
            ThreadLocalRandom current = ThreadLocalRandom.current();
            LocalDate today = LocalDate.now();
            for (int i = 0; i < 1000; i++) {
                String name = bookName.get(current.nextInt(bookName.size()));
                Book book = new Book().setCount(current.nextInt(1000))
                        .setName(name)
                        .setPrice(current.nextDouble(100))
                        .setPublishTime(today.minusDays(current.nextInt(30)))
                        .setCount(current.nextInt(1000))
                        .setShortName(name + ":" + name);
                param.add(book);
            }
            List<Book> books = bookRepository.saveAll(param);
            Assert.isTrue(books.size() == param.size());
        }
    }
    
  4. MongoDB中的结果

image-20220428104139719.png

  1. 说明

    • book类

      book类的属性对应数据库中的结果,@Document注解标注,表示他是一个文档,会被MongoDB处理。

      id对应的是数据库中的_id,也可以用@Id来显示标注,属性也和数据库的字段对应,可以通过@Field(name = "name_1")来指定映射关系。

    • BookRepository接口

      继承于 MongoRepository<T, ID>,T表示实体域(这个Repository是哪个对象相关的),ID表示的是_id的类型。MongoRepository提供了一些查询操作。继承他就可以直接的使用。

    • 结果

      在额外的字段还增加了_class字段。类的全路径类名。

核心概念

在Spring Data repository 中核心的接口是Repository,需要两个类型参数,域对象和_id类型,这个接口的主要的功能是发现他的子接口,从而生成代理对象。CrudReposity接口提供了一些CRUD的功能。

此外还提供了一些子接口JpaRepository,MongoRepository。这些接口拓展了CrudRepository,不同的持久化技术有不同的实现。上图的例子中继承了MongoRepositoryPagingAndSortingRepository继承了CrudRepository,提供了分页和排序的功能。

image-20220428115108763.png

基础的CRUD基本能满足功能,但是要想更加的灵活就需要自己写方法了,但是,这些方法不需要自己实现,只需要在接口中写方法签名就好了,SpringData会自动来实现,只要这些方法能满足语法规则。

在使用的时候,就像正常的Bean使用一样,注入就可以使用,自定义的Repository的子类是不需要用Component来声明的。

如果这些方法还不能满足业务需求,就需要自己动手写了,通过MongoTemplate来自定义实现。

也就是说在大多数的开发中:我们主要干下面的几个事情

  1. 写实体对象,提供get和set方法,标注@Document注解,确定id字段(字段的名字是id或者利用@Id字段做映射),确定属性和字段的映射关系(如果不满意可以通过@Field)。
  2. 写Repository接口,将实体类和id类型作为类型参数传递过去。
  3. 可以写SpringData语法的方法。SpringData会自动的实现。
  4. 如果不满足,就可以自定义Repository的实现类。
  5. 正常的使用作为Bean来使用。

在后面章节中,会详细的说明


关于博客这件事,我是把它当做我的笔记,里面有很多的内容反映了我思考的过程,因为思维有限,不免有些内容有出入,如果有问题,欢迎指出。一同探讨。谢谢。