SpringBoot整合MongoDB文档相关操作

文章目录

SpringBoot整合MongoDB

  1. 创建项目,添加依赖,配置连接

    xml 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.32</version>
    </dependency>
    yaml 复制代码
    spring:
      data:
        mongodb:
    #      uri: mongodb://xxx:xxx@192.168.1.x:27017/database_name?authSource=admin
          host: 192.168.1.x
          port: 27017
          username: xxx
          password: xxx
          database: mydatabase_name
          authentication-database: admin
  2. 连接测试

    java 复制代码
     @Resource
    MongoTemplate mongoTemplate;
    
     	 /**
         * 连接测试
         */
    @Test
    public void testConnection(){
        MongoDatabase mongoDatabase = mongoTemplate.getDb();
        System.out.println("Connected to database: " + mongoDatabase.getName());
    
        // 获取所有集合的名称并打印
        mongoDatabase.listCollectionNames().forEach(collectionName -> {
            System.out.println("Collection: " + collectionName);
        });
    }
  3. 集合操作

    java 复制代码
    /**
     * 创建集合测试
     */
    @Test
    public void testCreateCollection(){
        boolean exists = mongoTemplate.collectionExists("emp");
        if (exists){
            mongoTemplate.dropCollection("emp");
        }
        mongoTemplate.createCollection("emp");
    }

文档操作

注解 描述 示例
@Document 标识一个类为MongoDB的文档,并指定集合名 @Document(collection="users")
@Id 标识一个字段为文档的唯一标识符(_id) @Id private String id;
@Field 指定字段在MongoDB中的名称 @Field("user_name") private String username;
@Indexed 为字段创建索引 @Indexed private String email;
@CompoundIndex 创建复合索引 @CompoundIndex(name="name_age", def="{'firstName': 1, 'age': -1}")
@TextIndexed 为字段创建文本索引 @TextIndexed private String description;
@Transient 标识字段不被持久化到数据库 @Transient private String tempField;
@DBRef 引用另一个文档 @DBRef private List<Role> roles;
@Version 用于乐观锁,自动处理版本控制 @Version private Long version;
@CreatedDate 自动记录文档的创建时间 @CreatedDate private Date createdDate;
@LastModifiedDate 自动记录文档的最后修改时间 @LastModifiedDate private Date lastModifiedDate;
  • 详细解说
  1. @Document

    • 用于标识一个Java类为MongoDB的文档,并可以指定集合名称。如果不指定集合名称,默认使用类名的小写形式。
    • 示例:@Document(collection="users")
  2. @Id

    • 用于标识一个字段为文档的唯一标识符(_id)。通常映射到MongoDB的_id字段。
    • 示例:@Id private String id;
  3. @Field

    • 用于指定字段在MongoDB中的名称。如果不使用此注解,字段名称默认与Java类中的字段名称一致。
    • 示例:@Field("user_name") private String username;
  4. @Indexed

    • 用于为字段创建索引,可以提高查询效率。可以通过参数指定索引类型和方向。
    • 示例:@Indexed private String email;
  5. @CompoundIndex

    • 用于创建复合索引,可以提高多字段查询的效率。
    • 示例:@CompoundIndex(name="name_age", def="{'firstName': 1, 'age': -1}")
  6. @TextIndexed

    • 用于为字段创建文本索引,支持全文搜索。
    • 示例:@TextIndexed private String description;
  7. @Transient

    • 用于标识字段不被持久化到数据库。
    • 示例:@Transient private String tempField;
  8. @DBRef

    • 用于引用另一个文档,类似于关系数据库的外键。
    • 示例:@DBRef private List<Role> roles;
  9. @Version

    • 用于乐观锁,自动处理版本控制。每次更新文档时,版本号会自动增加。
    • 示例:@Version private Long version;
  10. @CreatedDate

    • 自动记录文档的创建时间。
    • 示例:@CreatedDate private Date createdDate;
  11. @LastModifiedDate

    • 自动记录文档的最后修改时间。
    • 示例:@LastModifiedDate private Date lastModifiedDate;

添加文档

sql 复制代码
// 1. 选择数据库 (如使用 'test' 数据库)
use mydatabase

// 2. 创建 emp 集合并插入文档
db.emp.insertOne({
  _id:10,               
  name: "John Doe",
  age: 30,
  salary: 55000.00,
  birthday: new Date("1992-05-15")
})

// 3. 也可以插入多个文档
db.emp.insertMany([
  {
    _id:20
    name: "Jane Smith",
    age: 25,
    salary: 60000.00,
    birthday: new Date("1997-08-23")
  },
  {
    _id:30
    name: "Alice Johnson",
    age: 27,
    salary: 65000.00,
    birthday: new Date("1995-03-12")
  }
])

// 4. 查询集合中的所有文档以验证插入是否成功
db.emp.find().pretty()
  • insert方法返回值是新增的Document对象,里面包含了新增后id的值。如果集合不存在会自动创建集合。
  • 通过Spring Data MongoDB会给集合中多加一个class的属性,存储新增时Document对应Java中类的全限定路径。原因为了查询时能把Document转换为Java类型。
java 复制代码
@Document("emp") //对应emp集合中的一个文档
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    @Id
    private Integer id;
    @Field
    private String name;
    @Field
    private int age;
    @Field
    private Double salary;
    @Field
    private Date birthday;
}
java 复制代码
 /**
     * 添加文档
     */
    @Test
    public void testInsert(){
        Employee employee = new Employee(1, "小明", 30,10000.00, new Date());

        //insert:_id存在抛出异常 支持批量操作
        mongoTemplate.insert(employee);

        //sava:_id存在时更新数据
        mongoTemplate.save(employee);

        //插入多条数据
        List<Employee> list = Arrays.asList(
                new Employee(2,"张三", 21,5000.00, new Date()),
                new Employee(3,"李四",26,8000.00, new Date()),
                new Employee(4, "王五",22, 8000.00, new Date()),
                new Employee(5,"张龙",28,6000.00, new Date()),
                new Employee(6,"赵虎",24,7000.00, new Date()),
                new Employee(7,"赵六",28,12000.00, new Date())
        );

        Collection<Employee> employees = mongoTemplate.insert(list, Employee.class);
        System.out.println(employees);
    }

查询文档

  • Criteria是标准查询的接口,可以引l用静态的criteria.where的把多个条件组合在一起,就可以轻松地将多个方法标准和查询连接起来,方便操作查询语句

  • MongoDB 中 Criteria 查询标准的表格:

Criteria 语法 MongoDB 中的语法 说明
Criteria.where(String key) { key: ... } 创建一个以指定键为目标的查询条件。
Criteria.andOperator(Criteria... criteria) $and 创建一个并且(AND)组合查询条件。
Criteria.orOperator(Criteria... criteria) $or 创建一个或者(OR)组合查询条件。
Criteria.is(Object value) key: value 等于指定值。
Criteria.ne(Object value) key: { $ne: value } 不等于指定值。
Criteria.lt(Object value) key: { $lt: value } 小于指定值。
Criteria.lte(Object value) key: { $lte: value } 小于或等于指定值。
Criteria.gt(Object value) key: { $gt: value } 大于指定值。
Criteria.gte(Object value) key: { $gte: value } 大于或等于指定值。
Criteria.in(Object... values) key: { $in: [values...] } 在指定的值列表中。
Criteria.nin(Object... values) key: { $nin: [values...] } 不在指定的值列表中。
Criteria.regex(String regex) key: { $regex: regex } 匹配指定的正则表达式。
Criteria.exists(boolean exists) key: { $exists: exists } 检查字段是否存在。
Criteria.type(int type) key: { $type: type } 检查字段的 BSON 类型。
Criteria.elemMatch(Criteria criteria) key: { $elemMatch: {...} } 匹配数组中的元素。
Criteria.size(int size) key: { $size: size } 检查数组的长度。
Criteria.not() key: { $not: {...} } 否定条件。
Criteria.mod(Number value, Number remainder) key: { $mod: [value, remainder] } 按指定值取模。
Criteria.all(Object... values) key: { $all: [values...] } 数组包含所有指定的元素。
Criteria.within(Shape shape) key: { $geoWithin: {...} } 地理空间查询,检查点是否在指定的形状内。
Criteria.near(Point point) key: { $near: {...} } 地理空间查询,查找接近指定点的文档。
  • 示例解释:

  • Criteria.andOperator:

Criteria 语法:

java 复制代码
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("age").gt(25), Criteria.where("salary").lt(60000));

MongoDB 语法:

json 复制代码
{
  "$and": [
    { "age": { "$gt": 25 } },
    { "salary": { "$lt": 60000 } }
  ]
}
  • Criteria.orOperator:

Criteria 语法:

java 复制代码
Criteria criteria = new Criteria();
criteria.orOperator(Criteria.where("status").is("Active"), Criteria.where("status").is("Pending"));

MongoDB 语法:

json 复制代码
{
  "$or": [
    { "status": "Active" },
    { "status": "Pending" }
  ]
}

说明:

  • Criteria 类用于构建复杂的查询条件。
  • MongoDB 对应语法中,条件操作符通常以 $ 开头,例如 $and, $or, $gt, $lt 等。
  • 使用 Criteria 类可以链式调用,方便地组合多种条件,生成复杂的查询语句。
java 复制代码
 	/**
     * 查询文档
     */
    @Test
    public void SelectTest() {
        //查询所有数据
        List<Employee> all = mongoTemplate.findAll(Employee.class);
        System.out.println(all);

        //查询id=1的数据
        Employee employee = mongoTemplate.findById(1, Employee.class);
        System.out.println(employee);

        //无条件查询
        Employee one = mongoTemplate.findOne(new Query(), Employee.class);
        System.out.println(one);

        //查询薪资大于8000的员工
        Query condition1 = new Query(Criteria.where("salary").gte(8000));
        System.out.println(mongoTemplate.find(condition1, Employee.class));

        //查询姓张的员工
        Query condition2 = new Query(Criteria.where("name").regex("^张"));
        System.out.println(mongoTemplate.find(condition2, Employee.class));

        //查询姓张并且薪资大于5000的员工
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("name").regex("^张"),Criteria.where("salary").gt(5000));
        Query query = new Query(criteria);
        query.with(Sort.by(Sort.Order.asc("name")));
        List<Employee> employeeList = mongoTemplate.find(query, Employee.class);
        employeeList.forEach(System.out::println);
    }
java 复制代码
	@Test
    public void testFindBuJson(){

        String json="{name:'张三'}";
        BasicQuery query = new BasicQuery(json);
        mongoTemplate.find(query,Employee.class).forEach(System.out::println);

        String json2="{$or: [{age:{$gt:25}},{salary:{$gte:8000}}]}";
        BasicQuery query2 = new BasicQuery(json2);
        mongoTemplate.find(query2,Employee.class).forEach(System.out::println);
    }

更新文档

  • 在Mongodb中无论是使用客户端APl还是使用SpringData,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返回0。
  • updateFirst():只更新满足条件的第一条记录
  • updateMulti():更新所有满足条件的记录
  • upsert():没有符合条件的记录则插入数据
java 复制代码
	/**
     * 更新文档
     */
    @Test
    public void testUpdate(){
        //query设置查询条件
        Query query = new Query(Criteria.where("salary").gte(5000));
        System.out.println("更新前");
        List<Employee> employees = mongoTemplate.find(query, Employee.class);
        employees.forEach(System.out::println);

        //设置更新属性
        Update update = new Update();
        update.inc("salary",3000); //加工资
        //update.inc("salary",-3000); //减工资
        //只更新满足条件的第一条记录
        //mongoTemplate.updateFirst(query,update, Employee.class);
        //更新满足条件的多条记录
        mongoTemplate.updateMulti(query,update, Employee.class);

        //upsert 没有符合条件则插入数据

        Query query2 = new Query(Criteria.where("id").is(12));
        Update update2 = new Update();
        update2.setOnInsert("salary",8000);
        update2.setOnInsert("name","小龙");
        update2.setOnInsert("age",23);
        UpdateResult updateResult = mongoTemplate.upsert(query2, update2, Employee.class);
        //返回修改的记录数
        System.out.println(updateResult.getModifiedCount());
    }

删除文档

java 复制代码
	/**
     * 删除文档
     */
    @Test
    public void testDelete(){
        //条件删除
        Query query = new Query(Criteria.where("id").is(12));
        mongoTemplate.remove(query,Employee.class);
        //删除所有文档
        mongoTemplate.dropCollection("emp"); //推荐
        //mongoTemplate.remove(new Query(), Employee.class); //不推荐
    }
相关推荐
前端Hardy24 分钟前
一个时代结束了:npm 终于对 install 脚本下手了
前端·javascript·后端
damaoyou26 分钟前
Cog3DRangeImagePlaneEstimatorTool完全指南
后端
Nturmoils1 小时前
分页别写太顺手,LIMIT 背后还有排序和边界
数据库·后端
神奇小汤圆1 小时前
国产版“Codex”初体验,智谱ZCode很强啊!
后端
站大爷IP1 小时前
Python里的“赋值”到底是什么意思?
后端
鹅城剑仙1 小时前
Spring Boot 微服务架构设计与最佳实践
spring boot·后端·微服务
心之伊始2 小时前
Spring Boot Actuator + Micrometer 实战:自定义业务指标并接入 Prometheus 观测接口耗时
java·spring boot·prometheus·actuator·micrometer
Full Stack Developme2 小时前
Spring Integration 教程
java·后端·spring
爱勇宝2 小时前
AI 时代,前端工程师的话语权正在下降?
前端·后端
kymjs张涛2 小时前
一个月,纯VibeCoding,全平台云笔记APP
前端·javascript·后端