注册

SpringBoot MongoDB与MongoDB GridFS基本使用

SpringBoot MongoDB与MongoDB GridFS基本使用

1. 前言

在开发过程中,我们经常需要使用到数据库进行数据的存储和管理。MongoDB是一个开源的,高性能,面向文档的NoSQL数据库。在Java中,我们可以使用SpringBoot框架来连接MongoDB数据库,并支持使用MongoDB的GridFS进行文件的存储和管理。

2. MongoDB的基本介绍

如果您对MongoDB还不了解,可以先了解一下MongoDB的基本概念。

MongoDB是一种文档导向数据库管理系统(Document-Oriented Database Management System,简称Document DBMS),由C++语言编写。MongoDB的数据结构是由文档(document)组成的,一个文档相当于一个数据记录,可以包含任意数量的字段。MongoDB的数据存储格式是BSON(Binary JSON),它是一种二进制格式的JSON(JavaScript Object Notation)。

3. MongoDB的安装与配置

这一部分不详细说明,仅在此做简要介绍,读者可自行查阅相关文献。

在MongoDB官网下载适合自己操作系统的版本,然后进行安装。

安装完成后,在MongoDB的bin目录下,启动mongod服务:mongod.exe --dbpath "D:\MongoDB\data"。

4. SpringBoot连接MongoDB

在SpringBoot中连接MongoDB,需要使用MongoDB的官方Java驱动包"mongodb-driver"。实现步骤如下:

  1. 添加依赖

在SpringBoot的pom.xml文件中添加以下依赖:


    org.mongodb
    mongodb-driver
    3.11.2

  1. 配置MongoDB连接信息

在SpringBoot的application.properties文件中,配置MongoDB的连接信息:

spring.data.mongodb.uri=mongodb://localhost:27017/test
  1. 编写Java代码

定义一个MongoDBRepository接口并继承MongoRepository,用于操作MongoDB中的数据。可以定义一些常用的操作方法,如下所示:

@Repository
public interface MongoDBRepository extends MongoRepository {

    User findByUsername(String username);

    List findByAgeGreaterThan(int age);
}

在SpringBoot的启动类中添加@ComponentScan注解,用于扫描MongoDBRepository接口所在的包。

然后,在需要操作MongoDB的地方,进行MongoDBRepository的注入,就可以使用MongoDB进行数据的存储和管理了。

5. MongoDB GridFS的基本介绍

MongoDB GridFS是一种MongoDB存储机制,用于存储大文件。

MongoDB GridFS将文件分为两个部分:元数据和数据。元数据保存在files集合中,数据保存在chunks集合中。元数据中保存了文件的名称、大小、上传日期、类型等信息。数据则是将文件切分为若干个chunk进行存储。

6. SpringBoot使用MongoDB GridFS

在SpringBoot中使用MongoDB GridFS,需要使用MongoDB的官方Java驱动包"mongodb-driver"和"mongodb-driver-core"。实现步骤如下:

  1. 添加依赖

在SpringBoot的pom.xml文件中添加以下依赖:


    org.mongodb
    mongodb-driver
    3.11.2


    org.mongodb
    mongodb-driver-core
    3.11.2

  1. 配置MongoDB连接信息

在SpringBoot的application.properties文件中,配置MongoDB的连接信息(同第4步)。

  1. 编写Java代码

使用以下代码,可以将一个文件保存到MongoDB GridFS中:

@Autowired
private GridFsTemplate gridFsTemplate;

public String storeFile(MultipartFile file) throws IOException {
    DBObject metaData = new BasicDBObject();
    metaData.put("userId", "12345");
    metaData.put("fileName", file.getOriginalFilename());
    metaData.put("fileType", file.getContentType());
    GridFSFile gridFSFile = gridFsTemplate.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType(), metaData);
    return gridFSFile.getId().toString();
}

使用以下代码,可以从MongoDB GridFS中读取一个文件:

@Autowired
private GridFsTemplate gridFsTemplate;

public Resource loadFile(String fileId) throws IOException {
    GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(fileId)));
    if (gridFSFile == null) {
        throw new FileNotFoundException("File not found with id " + fileId);
    }
    GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
    return resource;
}

注意:在使用GridFsTemplate时,需要先进行注入。

7. 示例说明

下面提供两个示例,用于展示SpringBoot MongoDB与MongoDB GridFS的基本使用方法。

示例一:使用MongoDB

在使用MongoDB的示例中,我们将定义一个User类,然后使用MongoDBRepository对User类进行操作。

  1. 定义User类

User类定义如下:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(collection="user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private Long id;
    private String username;
    private Integer age;
    private Date birthday;
}
  1. 编写操作类

在我们的操作类中,进行MongoDBRepository的注入。然后,我们定义了一些基本的操作方法:

@Service
public class MongoDBService {

    @Autowired
    private MongoDBRepository mongoDBRepository;

    public User saveUser(User user) {
        return mongoDBRepository.save(user);
    }

    public void deleteUser(Long id) {
        mongoDBRepository.deleteById(id);
    }

    public User getUserByUsername(String username) {
        return mongoDBRepository.findByUsername(username);
    }

    public List getUsersByAgeGreaterThan(int age) {
        return mongoDBRepository.findByAgeGreaterThan(age);
    }
}
  1. 编写测试类

在测试类中,我们进行了一些简单的测试:

@SpringBootTest
class MongoDBServiceTest {

    @Autowired
    private MongoDBService mongoDBService;

    @Test
    void saveUser() {
        User user = new User();
        user.setId(1L);
        user.setUsername("张三");
        user.setAge(20);
        user.setBirthday(new Date());
        mongoDBService.saveUser(user);
    }

    @Test
    void deleteUser() {
        mongoDBService.deleteUser(1L);
    }

    @Test
    void getUserByUsername() {
        User user = mongoDBService.getUserByUsername("张三");
        System.out.println(user);
    }

    @Test
    void getUsersByAgeGreaterThan() {
        List userList = mongoDBService.getUsersByAgeGreaterThan(15);
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

示例二:使用MongoDB GridFS

在使用MongoDB GridFS的示例中,我们将定义一个FileService类,用于操作MongoDB GridFS进行文件的上传和下载。

  1. 编写FileService类

在FileService类中,我们进行了GridFsTemplate的注入,并定义了进行文件上传和下载的方法:

@Service
public class FileService {

    @Autowired
    private GridFsTemplate gridFsTemplate;

    public String storeFile(MultipartFile file) throws IOException {
        DBObject metaData = new BasicDBObject();
        metaData.put("userId", "12345");
        metaData.put("fileName", file.getOriginalFilename());
        metaData.put("fileType", file.getContentType());
        GridFSFile gridFSFile = gridFsTemplate.store(file.getInputStream(), file.getOriginalFilename(), file.getContentType(), metaData);
        return gridFSFile.getId().toString();
    }

    public Resource loadFile(String fileId) throws IOException {
        GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(fileId)));
        if (gridFSFile == null) {
            throw new FileNotFoundException("File not found with id " + fileId);
        }
        GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
        return resource;
    }
}
  1. 编写控制器类

在控制器类中,我们进行了FileService的注入,并定义了文件上传和下载的接口:

@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileService fileService;

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        return fileService.storeFile(file);
    }

    @GetMapping("/download/{fileId}")
    public ResponseEntity downloadFile(@PathVariable String fileId) throws IOException {
        Resource resource = fileService.loadFile(fileId);
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(resource.getFilename()))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }
}
  1. 编写测试类

在使用MongoDB GridFS进行文件上传和下载的测试类中,代码如下:

@SpringBootTest
class FileControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void uploadFile() throws Exception {
        File file = new File("D:\\图片\\1.jpg");
        FileInputStream input = new FileInputStream(file);
        MockMultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", input);
        mockMvc.perform(MockMvcRequestBuilders.multipart("/file/upload")
                .file(multipartFile))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().string("60d8b807c8addb32c7cc74b5"));
    }

    @Test
    void downloadFile() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/file/download/60d8b807c8addb32c7cc74b5"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.header().exists(HttpHeaders.CONTENT_DISPOSITION));
    }
}

注意:在测试FileController类时,我们需要使用MockMvc来进行测试。在本例中,使用MockMultipartFile对象来模拟文件上传。