springboot操作mongodb(MongoTemplate)

环境:

springboot:2.7

mongodb:4.0

 

1.项目结构

image

 

2.pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.hxl</groupId>
  <artifactId>springboot_mongo</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springboot_mongo</name>
  <url>http://maven.apache.org</url>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>


  <dependencies>
    <!-- SpringBoot Web 可选,用于测试接口 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- SpringBoot MongoDB 核心依赖 【必引】 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <!-- lombok 简化实体类代码 可选 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>16</source>
          <target>16</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

 

3.配置文件application.yml

spring:
  # MongoDB配置
  data:
    mongodb:
      # 连接格式:mongodb://用户名:密码@ip地址:端口号/数据库名?认证参数
      uri: mongodb://hxl:hxl123@192.168.1.139:28001/hxl_test?authSource=admin&authMechanism=SCRAM-SHA-1
      # 数据库名(和uri中的数据库名一致即可)
      database: hxl_test

 

4.各java文件

MongoConfig.java

package org.hxl.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
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;

@Configuration
public class MongoConfig {

    @Bean(name = "mongoTemplate")
    public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDatabaseFactory, MongoMappingContext mongoMappingContext) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDatabaseFactory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
        //去掉_class字段
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return new MongoTemplate(mongoDatabaseFactory,mappingConverter);
    }
}

 

ProductController.java

package org.hxl.controller;

import org.hxl.entity.Product;
import org.hxl.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;

    // 新增单个商品
    @PostMapping("/save")
    public Product save(@RequestBody Product product) {
        return productService.save(product);
    }

    // 批量新增商品
    @PostMapping("/batchSave")
    public Boolean batchSave(@RequestBody List<Product> productList) {
        return productService.batchSave(productList);
    }

    // 根据ID修改商品
    @PutMapping("/update/{id}")
    public Boolean updateById(@PathVariable String id, @RequestBody Product product) {
        return productService.updateById(id, product);
    }

    // 根据ID删除商品
    @DeleteMapping("/delete/{id}")
    public Boolean deleteById(@PathVariable String id) {
        return productService.deleteById(id);
    }

    // 根据分类删除商品
    @DeleteMapping("/delete/category/{category}")
    public Boolean deleteByCategory(@PathVariable String category) {
        return productService.deleteByCategory(category);
    }

    // 根据ID查询商品
    @GetMapping("/{id}")
    public Product getById(@PathVariable String id) {
        return productService.getById(id);
    }

    // 查询所有商品
    @GetMapping("/list")
    public List<Product> findAll() {
        return productService.findAll();
    }

    // 根据分类查询商品
    @GetMapping("/list/category/{category}")
    public List<Product> findByCategory(@PathVariable String category) {
        return productService.findByCategory(category);
    }

    // 价格区间查询
    @GetMapping("/list/price")
    public List<Product> findByPriceRange(@RequestParam BigDecimal min, @RequestParam BigDecimal max) {
        return productService.findByPriceRange(min, max);
    }

    // 商品名称模糊查询
    @GetMapping("/list/like/{keyword}")
    public List<Product> findByProductNameLike(@PathVariable String keyword) {
        return productService.findByProductNameLike(keyword);
    }

    // 分页+排序查询
    @GetMapping("/list/page")
    public List<Product> findByPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
        return productService.findByPage(pageNum, pageSize);
    }

    // 统计分类下商品数量
    @GetMapping("/count/{category}")
    public Long countByCategory(@PathVariable String category) {
        return productService.countByCategory(category);
    }
}

 

Product.java

package org.hxl.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 商品实体类 - 映射MongoDB的product集合
 * @Document 指定集合名称,不存在自动创建
 * @Id 对应MongoDB的主键 _id 自动生成唯一ObjectId
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "product")
public class Product {
    /**
     * 主键ID,MongoDB自动生成 全局唯一的ObjectId字符串
     */
    @Id
    private String id;
    /** 商品名称 */
    private String productName;
    /** 商品价格 */
    private BigDecimal price;
    /** 商品库存 */
    private Integer stock;
    /** 商品分类 */
    private String category;
    /** 创建时间 */
    private Date createTime;
}

 

ProductRepository.java

package org.hxl.repository;

import org.hxl.entity.Product;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 继承 MongoRepository<实体类, 主键类型>
 * 无需写任何实现,自动拥有CRUD、分页、排序等基础方法
 */
@Repository
public interface ProductRepository extends MongoRepository<Product, String> {

    // ====================== 自定义条件查询(支持方法名自动解析,无需写SQL) ======================
    /**
     * 根据商品分类查询所有商品
     * Spring Data 自动解析方法名生成查询条件
     */
    List<Product> findByCategory(String category);

    /**
     * 根据价格区间查询商品
     */
    List<Product> findByPriceBetween(Double min, Double max);
}

 

ProductService.java

package org.hxl.service;

import org.hxl.entity.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

@Service
public class ProductService {

    // 核心:注入MongoTemplate,无需任何配置,直接使用
    @Autowired
    private MongoTemplate mongoTemplate;

    // ======================== 一、基础新增 ========================
    /**
     * 新增单个商品
     */
    public Product save(Product product) {
        product.setCreateTime(new Date()); // 赋值创建时间
        // insert:主键id为空时新增,有id会报错(推荐新增用insert)
        mongoTemplate.insert(product);
        return product;
    }

    /**
     * 批量新增商品
     */
    public boolean batchSave(List<Product> productList) {
        productList.forEach(item -> item.setCreateTime(new Date()));
        mongoTemplate.insert(productList, Product.class);
        return true;
    }

    // ======================== 二、基础修改 ========================
    /**
     * 根据ID修改商品(指定字段修改,效率最高)
     */
    public boolean updateById(String id, Product product) {
        // 1. 构造查询条件:根据主键id查询
        Query query = Query.query(Criteria.where("id").is(id));
        // 2. 构造修改内容:只修改传入的非空字段
        Update update = new Update();
        if (product.getProductName() != null) {
            update.set("productName", product.getProductName());
        }
        if (product.getPrice() != null) {
            update.set("price", product.getPrice());
        }
        if (product.getStock() != null) {
            update.set("stock", product.getStock());
        }
        if (product.getCategory() != null) {
            update.set("category", product.getCategory());
        }
        // 3. 修改操作:updateFirst 只修改匹配到的第一条
        mongoTemplate.updateFirst(query, update, Product.class);
        return true;
    }

    /**
     * 全量修改:根据id覆盖整个文档(慎用,会覆盖所有字段)
     */
    public Product updateWhole(Product product) {
        product.setCreateTime(new Date());
        // save方法:有id=修改,无id=新增,会覆盖整个文档
        return mongoTemplate.save(product);
    }

    // ======================== 三、基础删除 ========================
    /**
     * 根据ID删除单个商品
     */
    public boolean deleteById(String id) {
        Query query = Query.query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, Product.class);
        return true;
    }

    /**
     * 条件删除:删除指定分类下的所有商品
     */
    public boolean deleteByCategory(String category) {
        Query query = Query.query(Criteria.where("category").is(category));
        mongoTemplate.remove(query, Product.class);
        return true;
    }

    // ======================== 四、基础查询 ========================
    /**
     * 根据ID查询单个商品
     */
    public Product getById(String id) {
        return mongoTemplate.findById(id, Product.class);
    }

    /**
     * 查询所有商品
     */
    public List<Product> findAll() {
        return mongoTemplate.findAll(Product.class);
    }

    // ======================== 五、复杂条件查询【重点高频】 ========================
    /**
     * 1. 等值查询:根据分类查询商品列表
     */
    public List<Product> findByCategory(String category) {
        Query query = Query.query(Criteria.where("category").is(category));
        return mongoTemplate.find(query, Product.class);
    }

    /**
     * 2. 范围查询:查询价格区间内的商品 (大于等于min,小于等于max)
     */
    public List<Product> findByPriceRange(BigDecimal minPrice, BigDecimal maxPrice) {
        Query query = Query.query(Criteria.where("price").gte(minPrice).lte(maxPrice));
        return mongoTemplate.find(query, Product.class);
    }

    /**
     * 3. 模糊查询:根据商品名称模糊匹配(最常用,类似MySQL的like %xxx%)
     */
    public List<Product> findByProductNameLike(String keyword) {
        // 构建正则表达式,忽略大小写
        Pattern pattern = Pattern.compile("^.*" + keyword + ".*$", Pattern.CASE_INSENSITIVE);
        Query query = Query.query(Criteria.where("productName").regex(pattern));
        return mongoTemplate.find(query, Product.class);
    }

    /**
     * 4. 多条件组合查询:分类+价格区间 组合查询
     * 例:查询 手机分类 且 价格在3000-8000之间的商品
     */
    public List<Product> findByCondition(String category, BigDecimal minPrice, BigDecimal maxPrice) {
        // 构建组合条件:and 连接多个条件
        Criteria criteria = new Criteria();
        criteria.and("category").is(category);
        criteria.and("price").gte(minPrice).lte(maxPrice);
        Query query = Query.query(criteria);
        return mongoTemplate.find(query, Product.class);
    }

    // ======================== 六、排序 + 分页【开发必备】 ========================
    /**
     * 分页+排序查询:按价格降序,分页查询商品
     * pageNum: 页码(从1开始),pageSize: 每页条数
     */
    public List<Product> findByPage(Integer pageNum, Integer pageSize) {
        Query query = new Query();
        // 1. 设置排序规则:按price降序(-1=降序,1=升序),也可以按createTime排序
        query.with(Sort.by(Sort.Direction.DESC, "price"));
        // 2. 设置分页参数:skip(跳过条数),limit(每页条数)
        query.skip((pageNum - 1) * pageSize).limit(pageSize);
        return mongoTemplate.find(query, Product.class);
    }

    // ======================== 七、统计计数 ========================
    /**
     * 统计指定分类下的商品总数
     */
    public long countByCategory(String category) {
        Query query = Query.query(Criteria.where("category").is(category));
        return mongoTemplate.count(query, Product.class);
    }

    /**
     * 统计所有商品总数
     */
    public long countAll() {
        return mongoTemplate.count(new Query(), Product.class);
    }
}

 

App.java

package org.hxl;

/**
 * Hello world!
 *
 */
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
        System.out.println("===== Spring Boot 启动成功 =====");
    }
}

 

5.调用

http://localhost:8080/product/save

image

 

MongoDB服务器查看

 

image

 

 

posted @ 2026-01-12 15:44  slnngk  阅读(0)  评论(0)    收藏  举报