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); //不推荐
    }
相关推荐
CC呢5 分钟前
基于单片机的智能婴儿床监护系统多功能婴儿床摇篮系统
数据库·mongodb
苹果醋326 分钟前
React系列(八)——React进阶知识点拓展
运维·vue.js·spring boot·nginx·课程设计
海绵波波10743 分钟前
flask后端开发(1):第一个Flask项目
后端·python·flask
等一场春雨2 小时前
springboot 3 websocket react 系统提示,选手实时数据更新监控
spring boot·websocket·react.js
荆州克莱3 小时前
Golang的性能监控指标
spring boot·spring·spring cloud·css3·技术
AI人H哥会Java3 小时前
【Spring】控制反转(IoC)与依赖注入(DI)—IoC容器在系统中的位置
java·开发语言·spring boot·后端·spring
凡人的AI工具箱3 小时前
每天40分玩转Django:Django表单集
开发语言·数据库·后端·python·缓存·django
赖龙3 小时前
springboot restful mybatis连接mysql返回日期格式不对
spring boot·mybatis·restful
自律的kkk3 小时前
SpringBoot中使用AOP切面编程实现登录拦截
java·spring boot·aop·切面编程·登录拦截
奔跑草-3 小时前
【数据库】SQL应该如何针对数据倾斜问题进行优化
数据库·后端·sql·ubuntu