關於MongoDB的簡單理解(三)–Spring Boot篇

一、前言

  Spring Boot集成MongoDB非常簡單,主要為加依賴加配置編碼

二、說明

環境說明:

  • JDK版本為15(1.8+即可)
  • Spring Boot 2.4.1

三、集成步驟

3.1 添加依賴

<!-- //mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
    <version>2.4.1</version>
</dependency>

3.2添加配置

spring:
  # mongo連接
  data:
    mongodb:
      uri: mongodb://mydb:[email protected]:27017/mydb

四、案例

4.1 基於MongoRepository實現對MongoDB的操作

4.1.1 新建客戶實體類

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@NoArgsConstructor                 //無參構造
@AllArgsConstructor                 //有參構造
// 客戶
public class Customer {

    // 主鍵ID
    // 此種方式ID需要自己設定
    @Id
    private String id;

//    // 主鍵ID
//    // 採用此種方式會自動生成ID
//    private ObjectId id;

    // 名字
    private String firstName;

    // 姓氏
    private String lastName;
}

4.1.2 新建客戶倉庫並實現MongoDB倉庫

import com.ruiyicloud.bbfbusiness.entity.mongo.Customer;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;


public interface CustomerRepository extends MongoRepository<Customer, String> {

    /**
     * 根據名字查找客戶
     * @param firstName 名字
     * @return
     */
    Customer findByFirstName(String firstName);

    /**
     * 根據姓氏查找客戶
     * @param lastName 姓氏
     * @return
     */
    List<Customer> findByLastName(String lastName);

}

4.1.3 創建控制器,對接口方法進行測試

import com.ruiyicloud.bbfbusiness.entity.mongo.Customer;
import com.ruiyicloud.bbfbusiness.service.mongo.CustomerRepository;
import com.ruiyicloud.comm.result.Result;
import com.ruiyicloud.comm.result.ResultGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static com.ruiyicloud.comm.utils.check.CheckUtil.notNull;


/**
 * <p>
 * MongoDB相關操作
 * </p>
 *
 * @author wanggx_ruiyi
 * @since 2021-01-19
 */
@Api(description="MongoDB相關操作",tags={"MongoDB"})
@RestController
@RequestMapping("/api/v1/mongo/mongoTest")
public class MongoTestController {
    @Resource
    private CustomerRepository customerRepository;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 新增客戶信息
     * @param customer 客戶模型
     * @return
     */
    @ApiOperation(value="新增",notes = "新增")
    @PostMapping("/add")
    public Result<Customer> add(@ApiParam(name = "customer", value = "客戶模型", required = true) @RequestBody Customer customer) {

        notNull(customer, "輸入參數不能為空");

        return ResultGenerator.genSuccessResult(customerRepository.save(customer));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 批量新增客戶信息
     * @param customerList 客戶模型列表
     * @return
     */
    @ApiOperation(value="批量新增",notes = "批量新增")
    @PostMapping("/batchAdd")
    public Result<List<Customer>> batchAdd(
            @ApiParam(name = "customerList", value = "客戶模型", required = true) @RequestBody List<Customer> customerList) {

        notNull(customerList, "輸入參數不能為空");

        return ResultGenerator.genSuccessResult(customerRepository.saveAll(customerList));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 根據名字查找客戶
     * @param firstName 名字
     * @return
     */
    @ApiOperation(value="根據名字查找客戶",notes = "根據名字查找客戶")
    @PostMapping("/findByFirstName")
    public Result<Customer> findByFirstName(
            @ApiParam(name = "firstName", value = "名字", required = true) @RequestParam String firstName) {

        notNull(firstName, "輸入參數不能為空");

        return ResultGenerator.genSuccessResult(customerRepository.findByFirstName(firstName));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 根據姓氏查找客戶
     * @param lastName 姓氏
     * @return
     */
    @ApiOperation(value="根據姓氏查找客戶",notes = "根據姓氏查找客戶")
    @PostMapping("/findByLastName")
    public Result<List<Customer>> findByLastName(
            @ApiParam(name = "lastName", value = "姓氏", required = true) @RequestParam String lastName) {

        notNull(lastName, "輸入參數不能為空");

        return ResultGenerator.genSuccessResult(customerRepository.findByLastName(lastName));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 根據id查找客戶
     * @param id 數據id
     * @return
     */
    @ApiOperation(value="根據id查找客戶",notes = "根據id查找客戶")
    @PostMapping("/findById")
    public Result<Customer> findById(
            @ApiParam(name = "id", value = "數據ID", required = true) @RequestParam String id) {

        notNull(id, "輸入參數不能為空");

        Optional<Customer> customer = customerRepository.findById(id);
        return ResultGenerator.genSuccessResult(customer.isPresent() ? customer.get() : null);
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 根據id判斷客戶是否存在
     * @param id 數據id
     * @return
     */
    @ApiOperation(value="根據id判斷客戶是否存在",notes = "根據id判斷客戶是否存在")
    @PostMapping("/existsById")
    public Result<Boolean> existsById(
            @ApiParam(name = "id", value = "數據ID", required = true) @RequestParam String id) {

        notNull(id, "輸入參數不能為空");

        return ResultGenerator.genSuccessResult(customerRepository.existsById(id));
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 查找所有客戶
     * @return
     */
    @ApiOperation(value="查找所有客戶",notes = "查找所有客戶")
    @PostMapping("/findAll")
    public Result<List<Customer>> findAll() {

        return ResultGenerator.genSuccessResult(customerRepository.findAll());
    }

    /**
     * @create wanggx_ruiyi 2021-01-19 查找所有客戶(排序)
     * @return
     */
    @ApiOperation(value="查找所有客戶(排序)",notes = "查找所有客戶(排序)")
    @PostMapping("/findAllBySort")
    public Result<List<Customer>> findAllBySort() {

        return ResultGenerator.genSuccessResult(customerRepository.findAll(Sort.by("id")));
    }

}

4.2 基於通用MyBatis Mapper插件的Service接口的實現

4.2.1 創建MongonService接口

import org.springframework.data.domain.Pageable;
import java.util.List;

/**
* MongonService 層 基礎接口,其他有關mongo的Service 接口 請繼承該接口
*/
public interface MongonService<T> {
/**
* 持久化
* @param model
*/
void save(T model);

/**
* 批量持久化
* @param models
*/
void save(List<T> models);

/**
* 通過_id刪除
* @param id
*/
void deleteById(String id);

/**
* 批量刪除
* @param models
*/
void deleteAll(List<T> models);

/**
* 更新每個實體--需自己實現
* @param model
* @return
*/
int update(T model);

/**
* 通過ID查找
* @param id
* @return
*/
T findById(String id);

/**
* 獲取所有
* @return
*/
List<T> findAll();

/**
* 通過分頁查詢
* @param pageable
* @return
*/
List<T> findByPage(Pageable pageable);
}

4.2.2 創建AbstractMongoService抽象類實現MongonService接口

import com.ruiyicloud.bbfbusiness.service.mongo.MongonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;

import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 基於通用MyBatis Mapper插件的Service接口的實現
 */
public abstract class AbstractMongoService<T> implements MongonService<T> {

    /**
     * 由springboot自動注入,默認配置會產生mongoTemplate這個bean
     */
    @Autowired
    private MongoTemplate mongoTemplate;

    // 當前泛型真實類型的Class
    private Class<T> modelClass;

    public AbstractMongoService() {
        // 返回表示由該類對象表示的實體(類、接口、基元類型或void)的直接超類的類型
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        // 返回表示此類型的實際類型參數的類型對象數組。
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    /**
     * 插入一個集合
     */
    @Override
    public void save(List<T> models) {
        mongoTemplate.insertAll(models);
    }

    /**
     * 查找全部
     */
    @Override
    public List<T> findAll() {
        return mongoTemplate.findAll(modelClass);
    }

    /**
     * 根據id得到對象
     */
    @Override
    public T findById(String id) {
        return mongoTemplate.findById(id, modelClass);
//        return mongoTemplate.findOne(new Query(Criteria.where("_id").is(id)), modelClass);
    }

    /**
     * 插入
     */
    @Override
    public void save(T model) {
        mongoTemplate.insert(model);
    }

    /**
     * 根據id刪除
     */
    @Override
    public void deleteById(String id) {
        T model = findById(id);
        mongoTemplate.remove(model);
//        Criteria criteria = Criteria.where("_id").is(id);
//        Query query = new Query(criteria);
//        mongoTemplate.remove(query,modelClass);
    }

    /**
     * 批量刪除
     *
     * @param models
     */
    @Override
    public void deleteAll(List<T> models) {
        for (T model : models) {
            mongoTemplate.remove(model);
        }
    }

    /**
     * 分頁查找
     * pageable代表分頁bean
     */
    @Override
    public List<T> findByPage(Pageable pageable) {
        Query query = new Query();
        List<T> list = mongoTemplate.find(query.with(pageable), modelClass);
        return list;
    }
}

4.2.3 使用示例

// Service 示例代碼
public interface EmrFileInfoService extends MongonService<EmrFileInfo>{}
// Service impl 示例代碼 @Service public class EmrFileInfoServiceImpl extends AbstractMongoService<EmrFileInfo> implements EmrFileInfoService {}

五、總結

  總的來說,Spring Boot集成MongoDB非常簡單。