MongoDB - 整合 SpringBoot 操作全流程

avatar
作者
筋斗云
阅读量:0

目录

一、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:如果没有进行副本集的配置,就会报如下错误:

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!