前情

Springboot是最简单的使用Spring的方式,而MongoDB是最流行的NoSQL数据库。两者在分布式、微服务架构中使用率极高,本文将用实例介绍如何在Springboot中整合MongoDB的两种方法:MongoRepository和MongoTemplate。

1.MongoRepository

以Spring Date为中心的方法,基于所有Spring数据项目中众所周知的访问模式,提供更加灵活和复杂的api操作。

1.使用Spring Data MongoDb Repository可以使你不用写相关的查询组合语句,它会内部为我们实现这样的一个类。

2.只要你按规定定义好接口名就可以免去你写查询组合语句。

3.要有主键值才可以用save(有就更新,没有就插入)。所以就算没有ID也增加这个字段是好的。(id要是String才会自动为你生面ID号(保存时可以没有值),int 要你自己做惟一处理和输入值)

4.DATE不能作为主键使用。

Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法

public interface Repository<T, ID extends Serializable> { }
Spring Data可以让我们只定义接口,只要遵循 Spring Data的规范,就无需写实现类。
与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性,两种方式没有区别。

Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下:

Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 
PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 
MongoRepository: 继承 PagingAndSortingRepository,实现一组 mongodb规范相关的方法

自定义的 XxxxRepository 需要继承 MongoRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力(CURD的操作功能)。

/**
 * 使用过Spring Jpa的都清楚,Repository实际就是用于操作数据库的类。在非关系型数据库MongoDB的整合中,也是一样的。Spring会帮我们实现好对应接口的方法,
 * 开发人员连SQL都不用写,非常省心。代码如下:
 *
 * 注意MongoRepository后面接的泛型<User, String>第一个为实体类,第二个为主键ID。
 */
public interface ResourceCommentRepository extends MongoRepository<ResourceComment, String> {

}

缺陷:

MongoRepository的缺点是不够灵活,MongoTemplate可以用来补充,对mongodb本身熟悉的话,你会发现使用MongoTemplate更加游刃有余,它更加接近原生的mongodb命令。

2.MongoTemplate(跟Mybatis类似)

MongoTemplate 遵循Spring中的标准模板模式,并为底层持久性引擎提供准备就绪的基本API。如果开发者没有提供MongoTemplate,默认会注册一个MongoTemplate进入Spring容器,所以开发者可以直接使用MongoTemplate。
MongoTemplate是数据库和代码之间的接口,对数据库的操作都在它里面。
MongoTemplate核心操作类:Criteria和Query

Criteria类:封装所有的语句,以方法的形式查询。
Query类:将语句进行封装或者添加排序之类的操作。
.MongoTemplate实现了interface MongoOperations.MongoDB documents和domain classes之间的映射关系是通过实现了MongoConverter这个interface的类来实现的。

.MongoTemplate提供了非常多的操作MongoDB的方法。 它是线程安全的,可以在多线程的情况下使用。

.MongoTemplate实现了MongoOperations接口, 此接口定义了众多的操作方法如"find", "findAndModify", "findOne", "insert", "remove", "save", "update" and "updateMulti"等。
.MongoTemplate转换domain object为DBObject,缺省转换类为MongoMappingConverter,并提供了Query, Criteria, and Update等流式API。

springboot整合mongodb

项目准备

项目结构:

在这里插入图片描述

准备测试数据

db.getCollection('newUser').save({"name":"lgn","age":"22"})

在这里插入图片描述

启动MongoDB实例

查看前面的文章。

引入相关依赖

主要的依赖为Web和MongoDB的starter,把下面代码加入到pom.xml中即可:

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

配置数据库连接信息

与配置MySQL或Oracle一样,MongoDB也需要配置连接信息,配置在application.properties中如下:

spring:
  data:
    mongodb:
      uri: mongodb://lgn:123456@192.168.8.150:27017/runoob

创建数据模型实体

创建NewUser类如下:

package com.fhbean.springboot.mongodb.entity;
import org.springframework.data.annotation.Id;
import java.util.Date;
/**
 * @author lgn
 * @version 1.0
 * @date 2021/9/17 17:45
 */
public class NewUser {
    @Id
    private String userId;
    private String name;
    private Integer age;
    private Date createTime = new Date();

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

不需要在MongoDB中创建对应的Collections(表),当通过Web应用新增时会自动创建。

方式1:MongoRepository

定义数据访问层UserRepository

package com.fhbean.springboot.mongodb.reposistory;

import org.springframework.data.mongodb.repository.MongoRepository;
import com.fhbean.springboot.mongodb.entity.NewUser;

/**
 * 使用过Spring Jpa的都清楚,Repository实际就是用于操作数据库的类。在非关系型数据库MongoDB的整合中,也是一样的。Spring会帮我们实现好对应接口的方法,
 * 开发人员连SQL都不用写,非常省心。代码如下:
 *
 * 注意MongoRepository后面接的泛型<User, String>第一个为实体类,第二个为主键ID。
 */
public interface UserRepository extends MongoRepository<NewUser, String> {

}

实现Controller

package com.fhbean.springboot.mongodb.controller;
import com.fhbean.springboot.mongodb.reposistory.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.fhbean.springboot.mongodb.entity.NewUser;
import java.util.List;

/**
 * MongoRepository方式
 * @author lgn
 * @version 1.0
 * @date 2021/9/26 13:40
 */
@RestController
@RequestMapping("/userRepository")
public class UserRepositoryController {
    @Autowired
    private final UserRepository userRepository;

    public UserRepositoryController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping("/getAllUsers")
    public List<NewUser> getAllUsers() {
        return userRepository.findAll();
    }

    @GetMapping("/{userId}")
    public NewUser getByUserId(@PathVariable String userId) {
        return userRepository.findById(userId).orElse(new NewUser());
    }

    @PostMapping("")
    public NewUser addNewUser(@RequestBody NewUser user) {
        return userRepository.save(user);
    }

    @DeleteMapping("/{userId}")
    public String delete(@PathVariable String userId) {
        NewUser user = new NewUser();
        user.setUserId(userId);
        userRepository.deleteById(userId);
        return "deleted: " + userId;
    }

    @PutMapping("")
    public NewUser update(@RequestBody NewUser user) {
        return userRepository.save(user);
    }
}

测试

在这里插入图片描述
在这里插入图片描述

方式2:MongoTemplate

定义数据访问层UserDAL

先定义接口为:

package com.fhbean.springboot.mongodb.service;

import com.fhbean.springboot.mongodb.entity.NewUser;

import java.util.List;

/**
 * @author lgn
 * @version 1.0
 * @date 2021/9/17 17:34
 */
public interface UserDAL {
    List<NewUser> findAll();

    NewUser findById(String userId);

    NewUser save(NewUser user);

    void deleteById(String userId);
}

然后实现该接口如下:

package com.fhbean.springboot.mongodb.service.impl;
import com.fhbean.springboot.mongodb.entity.NewUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;

import com.fhbean.springboot.mongodb.service.UserDAL;
import org.springframework.stereotype.Repository;

/**
 * @author lgn
 * @version 1.0
 * @date 2021/9/17 17:35
 */
@Repository
public class UserDALImpl implements UserDAL {

    @Autowired
    private MongoTemplate template;

    @Override
    public List<NewUser> findAll() {
        return template.findAll(NewUser.class);
    }

    @Override
    public NewUser findById(String userId) {
        return template.findById(userId,NewUser.class);
    }

    @Override
    public NewUser save(NewUser user) {
        template.save(user);
        return user;
    }

    @Override
    public void deleteById(String userId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        template.remove(query, NewUser.class);
    }
}

实现另一个Controller

package com.fhbean.springboot.mongodb.controller;

import com.fhbean.springboot.mongodb.entity.NewUser;
import com.fhbean.springboot.mongodb.service.UserDAL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * https://www.cnblogs.com/larrydpk/p/12735620.html
 * MongoTemplate的方式
 * @author lgn
 * @version 1.0
 * @date 2021/9/17 17:33
 */
@RestController
@RequestMapping("/userTemplate")
public class UserTemplateController {
    @Autowired
    private final UserDAL userDAL;

    public UserTemplateController(UserDAL userDAL) {
        this.userDAL = userDAL;
    }


    @GetMapping("")
    public List<NewUser> getAllUsers() {
        return userDAL.findAll();
    }

    @GetMapping("/{userId}")
    public NewUser getByUserId(@PathVariable String userId) {
        return userDAL.findById(userId);
    }

    @PostMapping("/addNewUser")
    @ResponseBody
    public NewUser addNewUser(@RequestBody NewUser user) {
        return userDAL.save(user);
    }

    @DeleteMapping("/{userId}")
    public String delete(@PathVariable String userId) {
        NewUser user = new NewUser();
        user.setUserId(userId);
        userDAL.deleteById(userId);
        return "deleted: " + userId;
    }

    @PutMapping("")
    public NewUser update(@RequestBody NewUser user) {
        return userDAL.save(user);
    }
}

测试

![在这里插入图片描述](https://img-blog.csdnimg.cn/92b593c5bda4422bb2d138f299577b57.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5oq5在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐