来自云龙湖轮廓分明的月亮 发表于 2024-7-30 16:23:50

MongoDB - 整合 SpringBoot 操纵全流程

目录
一、MongoDB 整合 SpringBoot
1.1、引入依赖
1.2、设置文件
1.3、集合操纵
1.4、相关注解
1.5、文档操纵
Tips:紧张提示
1.5.1、查询
1.5.2、分页查询 + 排序
1.5.3、更新
1.5.4、删除
1.6、事务

一、MongoDB 整合 SpringBoot

1.1、引入依赖

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

1.2、设置文件

spring:
data:
    mongodb:
      uri: mongodb://192.168.73.3:27017/demo
      field-naming-strategy: org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy # 自动转驼峰

#      mongodb 一般不设置密码
#      username: root
#      password: 1111
uri 格式为: mongodb://ip 地点:mongodb 端口号/集合名

1.3、集合操纵

   Ps:以 demo 集合为例
a)创建集合
      if(!mongoTemplate.collectionExists("demo")) {
            //不存在才能创建,如果以及存在再创建就会报错
            mongoTemplate.createCollection("demo");
      }

b)删除集合
      mongoTemplate.dropCollection("demo1");

1.4、相关注解

a)@Document


[*]修饰范围:在类上.
[*]作用:映射当前类的一个对象为 mongo 的一条文档.
[*]属性:value 和 collection 都是用来表示操纵的集合名.
b)@Id


[*]修饰范围:成员变量、方法.
[*]作用:将值映射成文档的 _id.
c)@Field


[*]修饰范围:成员变量、方法.
[*]作用:将值映射为文档中的一个 key 名称.
d)@Transient


[*]修饰范围:成员变量、方法.
[*]租用:指定值不参与文档序列化.
以 User 类为例:
@Document("demo") //表示当前文档属于哪个集合
public class User {

    @Id //当前类的 id 映射文档中的 _id
    private Integer id;
    private String name;
    private Integer age;
    @Field("work_day")//当前类的 workDay 映射文档中的 work_day
    private Date workDay;

    public User(Integer id, String name, Integer age, Date workDay) {
      this.id = id;
      this.name = name;
      this.age = age;
      this.workDay = workDay;
    }

    @Override
    public String toString() {
      return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", workDay=" + workDay +
                '}';
    }

    public Integer getId() {
      return id;
    }

    public void setId(Integer id) {
      this.id = id;
    }

    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 getWorkDay() {
      return workDay;
    }

    public void setWorkDay(Date workDay) {
      this.workDay = workDay;
    }
}

1.5、文档操纵

Tips:紧张提示

mongo 对类型有严格的要求.  比方根据 id 查询用户,你利用 String 类型的 id 作为 查询的参数,而 mongo 文档中保存的是 Long 类型的参数,此时你的查询记不起作用.
这点需要跟 MySQL 区分开!!!

1.5.1、查询

      //1.查询所有
      System.out.println("------------------------------------------------");
      List<User> users = mongoTemplate.findAll(User.class);
      users.forEach(System.out::println);

      //2.根据 id 查询指定文档
      System.out.println("------------------------------------------------");
      User byId = mongoTemplate.findById(1, User.class);
      System.out.println(byId);

      //3.根据查询条件进行查询(参数1: 查询条件, 参数2: 返回类型)
      System.out.println("------------------------------------------------");
//      mongoTemplate.find(new Query(), User.class);//没有查询条件就是查询所有
      //a) 等值查询
      System.out.println("------------------------------------------------");
      List<User> users1 = mongoTemplate.find(Query.query(Criteria.where("name").is("周杰伦")), User.class);
      users1.forEach(System.out::println);

      //b) > 查询: gt()、>= 查询: gte() 、 < 查询: lt()、<= 查询 lte() 查询
      //以 > 为例
      System.out.println("------------------------------------------------");
      List<User> users2 = mongoTemplate.find(Query.query(Criteria.where("age").gt(30)), User.class);
      users2.forEach(System.out::println);

      //4.and 查询
      System.out.println("------------------------------------------------");
      List<User> users3 = mongoTemplate.find(Query.query(Criteria.where("name").is("薛之谦").and("age").is(40)), User.class);
      users3.forEach(System.out::println);

      //5.or 查询
      System.out.println("------------------------------------------------");
      Criteria criteria = new Criteria();
      criteria.orOperator(
      Criteria.where("name").is("周杰伦"),
                Criteria.where("name").is("薛之谦")
      );
      List<User> users4 = mongoTemplate.find(Query.query(criteria), User.class);
      users4.forEach(System.out::println);

      //6.and 和 or
      System.out.println("------------------------------------------------");
      Criteria criteria1 = new Criteria();
      criteria1.and("age").is(40)
                .orOperator(
                        Criteria.where("name").is("周杰伦"),
                        Criteria.where("name").is("薛之谦")
                );
      List<User> users5 = mongoTemplate.find(Query.query(criteria1), User.class);
      users5.forEach(System.out::println);

      //7.sort
      System.out.println("------------------------------------------------");
      Query query = new Query();
      query.with(Sort.by(Sort.Order.desc("age"))); //desc 降序, asc 升序
      mongoTemplate.find(query, User.class);

      //8.分页: skip limit
      System.out.println("------------------------------------------------");
      Query queryPage = new Query();
      queryPage.with(Sort.by(Sort.Order.desc("age"))) //desc 降序, asc 升序
                .skip(0)
                .limit(3);
      mongoTemplate.find(queryPage, User.class);

      //9.总数
      System.out.println("------------------------------------------------");
      mongoTemplate.count(new Query(), User.class);

      //10.去重 distinct(参数1: 查询条件, 参数2: 去重字段, 参数3: 操作集合, 参数4: 返回类型)
      System.out.println("------------------------------------------------");
      List<String> name = mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);

      //11.json 字符串查询
      System.out.println("------------------------------------------------");
      Query queryJson = new BasicQuery("{name: '周杰伦', age: '20'}");
      List<User> users6 = mongoTemplate.find(queryJson, User.class);


1.5.2、分页查询 + 排序

    public List<MyDocument> findPaginated(int page, int size) {
      // 创建查询对象
      Query query = new Query();

      // 添加过滤条件,如果有的话
      // query.addCriteria(Criteria.where("fieldName").is("value"));

      // 添加排序条件,如果有的话
      // query.with(Sort.by(Sort.Direction.ASC, "fieldName"));

      // 计算跳过的文档数量
      long skip = (page - 1) * size;

      // 设置查询的起始位置和返回的数量
      query.skip(skip).limit(size);

      // 执行查询并返回结果
      return mongoTemplate.find(query, MyDocument.class, "collectionName");
    }
1.5.3、更新

更新指定字段的值.
      //1.更新条件
      Query query = Query.query(Criteria.where("name").is("周杰伦"));
      //2.更新内容
      Update update = new Update();
      update.set("age", 20);

      //a) 更新单条
      mongoTemplate.updateFirst(query, update, User.class);
      //b) 更新多条
      mongoTemplate.updateMulti(query, update, User.class);
      //c) 不存在就插入(存在就更新第一条)
      mongoTemplate.upsert(query, update, User.class);
指定某字段自增一,大概自减一.
            mongoTemplate.updateFirst(
                  Query.query(
                            Criteria
                                    .where("_id")
                                    .is(dto.getTargetId())
                  ),
                  new Update().inc("like_cnt", 1), //如果是 -1,就表示自减一
                  AlbumStatGO.class
            );
1.5.4、删除

      //1.删除所有
      mongoTemplate.remove(new Query(), User.class);
      //2.条件删除
      mongoTemplate.remove(Query.query(Criteria.where("name").is("林俊杰")), User.class);

1.6、事务

MongoDB 4.0 之后就支持事务了.
但是开启事务的前提如下:
a)开启集群模式(多副本集设置)
b)进行如下设置:
@Configuration
class MongoTransaction {

    @Bean
    fun transactionManager(factory: MongoDatabaseFactory): MongoTransactionManager {
      return MongoTransactionManager(factory)
    }

}
c)在需要回滚的地方加上 @Transactional 注解 
    @Transactional
    fun handler(dto: RegDto) {
      userIdentRepo.save(dto)
      throw AppException(ApiStatus.INVALID_PARAM, "这里故意触发异常,为了检验事务*-")
      userDetailRepo.save(dto.id!!)
    }
   Ps:如果没有进行副本集的设置,就会报如下错误:
https://i-blog.csdnimg.cn/blog_migrate/c732027d400bb12a96261f52d9365e98.png
https://i-blog.csdnimg.cn/blog_migrate/b1dd5ba183bb5752d7ee529ddf308226.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MongoDB - 整合 SpringBoot 操纵全流程