Spring Boot MongoDB入门

摘要: 原创出处 欢迎转载,保留摘要,谢谢!


1. 概述

官网介绍

Mongodb 是一个文档数据库,这意味着它将数据存储在类似 json 的文档中。 我们认为这是考虑数据最自然的方式,比传统的行 / 列模型更具表达能力和强大

1.1. 特点

1.1.1. 丰富的JSON文档

  • MongoDB都是以JSON格式存储数据

  • 支持数组和嵌套对象

  • 允许以灵活和动态的模式

1.1.2. 强大的查询语言

  • 丰富的表达式查询语言,允许按任何字段进行筛选和排序,无论该字段在文档中的嵌套程度如何。

  • 支持聚合和其他现代用例,如基于地理的搜索、图表搜索和文本搜索。

  • 查询本身就是 JSON,因此很容易组合,不需要连接字符串来动态生成 SQL 查询。

1.1.3. 支持所有关系型数据库的功能, 并且更强大

  • 所有ACID事务

  • 支持联接的方式查询

  • 以两种关系类型:引用和嵌套

贴一下人类语言的解释:-)

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

他支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。

Mongo 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

1.2. MongoDB和mysql参照

MySQL MongoDB
库 Database 库 Database
表 Table 集合 Collection
行 Row 文档 Document
列 Column 字段 Field
joins 嵌入文档或者链接

在早期,在项目中 MongoDB 的 ORM 框架使用 Morphia 较多。随着 Spring Data MongoDB 的日趋完善,更为主流。

在 Spring Data MongoDB 中,有两种方式进行 MongoDB 操作:

  • Spring Data Repository 方式

  • MongoTemplate

1.3. 安装

单机版安装方式基本傻瓜式 MongoDB4.2.5版官网下载链接

1.4. 快速入门

目录结构

.
├── pom.xml
├── spring-boot-mongo
│   ├── README.md
│   ├── pom.xml
│   ├── spring-boot-mongo.iml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │       └── shawn
│   │   │   │           ├── Application.java
│   │   │   │           ├── config
│   │   │   │           │   └── MongoDBConfig.java
│   │   │   │           ├── dataobject
│   │   │   │           │   └── UserDO.java
│   │   │   │           └── repository
│   │   │   │               └── UserRepository.java
│   │   │   └── resources
│   │   │       └── application.yml
│   │   └── test
│   │       └── java
│   │           └── UserRepositoryTest.java

示例代码

1.4.1. 引入依赖,由于我是一个子module,所以代码于此处有些出入



    
        spring-boot-study
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    spring-boot-mongo

    
        
        
            org.springframework.boot
            spring-boot-starter-data-mongodb
        
        
        
            org.projectlombok
            lombok
        
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    

1.4.2. 启动类

package com.shawn;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author gaoxiang
 * @description TODO
 * @date 2020/4/2 15:38
 */
@SpringBootApplication
public class Application {
    public static void main(String[] args) {

    }
}

1.4.3. 配置类

package com.shawn.config;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.Bean;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

/**
 * @author gaoxiang
 * @description MongoDB 配置类
 * @date 2020/4/2 16:11
 */
public class MongoDBConfig {
    // 目的,就是为了移除 _class field 。参考博客 https://blog.csdn.net/bigtree_3721/article/details/82787411
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,
                                                       MongoMappingContext context,
                                                       BeanFactory beanFactory) {
        // 创建 DbRefResolver 对象
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        // 创建 MappingMongoConverter 对象
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        // 设置 conversions 属性
        try {
            mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
        } catch (NoSuchBeanDefinitionException ignore) {
        }
        // 设置 typeMapper 属性,从而移除 _class field 。
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }
}
  • 通过在自定义 MappingMongoConverter Bean 对象,避免实体保存到 MongoDB 中时,会多一个 _class 字段,存储实体的全类名。

1.4.4. application.yml配置文件

spring:
  data:
    # MongoDB 配置项,对应 MongoProperties 类
    mongodb:
      host: 127.0.0.1
      port: 27017
      database: test
      # 上述属性,也可以只配置 uri

logging:
  level:
    org:
      springframework:
        data:
          mongodb:
            core: DEBUG # 打印 mongodb 操作的具体语句。生产环境下,不建议开启。

1.4.5. UserDO类, 我因为引入了lombok,所以此处get/set方法就不用写了

package com.shawn.dataobject;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * @author gaoxiang
 * @description UserDO.java
 * @date 2020/4/2 16:24
 */
@Document(collection = "User")
@Getter
@Setter
@ToString
public class UserDO {
    /**
     * 用户信息
     */
    @Getter
    @Setter
    @ToString
    public static class Profile {
        /**
         * 昵称
         */
        private String nickname;
        /**
         * 性别
         */
        private Integer gender;
    }
    @Id
    private Integer id;
    /**
     * 账号
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 用户信息
     */
    private Profile profile;
}
  • 在 UserDO 类中,我们内嵌了一个 profile 属性,它是 Profile 类。这里仅仅作为示例,实际场景下,还是建议把 User 和 Profile 拆分开。

  • 推荐阅读 《你应该知道的 MongoDB 最佳实践》 文章。对于初用 MongoDB 的开发者,往往错误的使用内嵌属性,需要去理解一下。

1.4.6 UserRepository.java

package com.shawn.repository;

import com.shawn.dataobject.UserDO;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * @author gaoxiang
 * @description MongoRepository.java
 * @date 2020/4/2 16:37
 */
public interface UserRepository extends MongoRepository {

}

  • 第一个泛型设置对应的实体是 UserDO ,第二个泛型设置对应的主键类型是 Integer 。

  • 因为实现了MongoRepository 接口, Spring Data MongoDB会自动生成对应的CRUD的代码

  • mongoRepository类图如下:

  • 其实和Spring Data JPA的使用方式基本一致.

1.4.7 简单测试

// UserRepositoryTest.java

import com.shawn.Application;
import com.shawn.dataobject.UserDO;
import com.shawn.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Date;
import java.util.Optional;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test // 插入一条记录
    public void testInsert() {
        // 创建 UserDO 对象
        UserDO user = new UserDO();
        user.setId(1); // 这里先临时写死一个 ID 编号,后面演示自增 ID 的时候,在修改这块
        user.setUsername("shawn");
        user.setPassword("1234");
        user.setCreateTime(new Date());
        // 创建 Profile 对象
        UserDO.Profile profile = new UserDO.Profile();
        profile.setNickname("shawn.nickname");
        profile.setGender(1);
        user.setProfile(profile);
        // 存储到 DB
        userRepository.insert(user);
    }

    // 这里要注意,如果使用 save 方法来更新的话,必须是全量字段,否则其它字段会被覆盖。
    // 所以,这里仅仅是作为一个示例。
    @Test // 更新一条记录
    public void testUpdate() {
        // 查询用户
        Optional userResult = userRepository.findById(1);
        Assert.isTrue(userResult.isPresent(), "用户一定要存在");
        // 更新
        UserDO updateUser = userResult.get();
        updateUser.setUsername("yutou");
        userRepository.save(updateUser);
    }

    @Test // 根据 ID 编号,删除一条记录
    public void testDelete() {
        userRepository.deleteById(1);
    }

    @Test // 根据 ID 编号,查询一条记录
    public void testSelectById() {
        Optional userDO = userRepository.findById(1);
        System.out.println(userDO.isPresent());
    }

    @Test // 根据 ID 编号数组,查询多条记录
    public void testSelectByIds() {
        Iterable users = userRepository.findAllById(Arrays.asList(1, 4));
        users.forEach(System.out::println);
    }

}

你可能感兴趣的:(Spring Boot MongoDB入门)