当前位置: 首页 > news >正文

SpringBoot整合MongoDB

一、环境准备

1、添加 SpringData 依赖:

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

2、配置 yml 文件

  • 方式一:
spring:data:mongodb:uri: mongodb://root:123456@1.15.76.95:27017/library?authSource=admin
  • 方式二:
spring:data:mongodb:username: rootpassword: 123456host: 1.15.76.95port: 27017database: libraryauthentication-database: admin

3、直接注入 MongoTemplate 进行操作

@Resource
MongoTemplate mongoTemplate;

二、集合操作

@Test
public void testCollection(){boolean exists = mongoTemplate.collectionExists("borrow");if(exists) {// 删除集合mongoTemplate.dropCollection("borrow");}else {// 创建集合mongoTemplate.createCollection("borrow");}Set<String> collectionNames = mongoTemplate.getCollectionNames();System.out.println(collectionNames.toString());  // [borrow, book, user]
}

三、文档操作

3.1 实体类

  • @Document
    • 修饰范围:用在类上。
    • 作用:用来映射这个类的一个对象为 Mongo 中一条文档数据。
    • 属性:(value 、collection) 用来指定操作的集合名称。
  • @MongoId
    • 修饰范围:用在成员变量、方法上。
    • 作用:用来将成员变量的值映射为文档的 _id 的值。
  • @Field
    • 修饰范围:用在成员变量、方法上。
    • 作用:用来将成员变量及其值映射为文档中一个 key:value 对。
    • 属性:(name , value) 用来指定在文档中 key 的名称,默认为成员变量名。
  • @Transient
    • 修饰范围:用在成员变量、方法上。
    • 作用:用来指定此成员变量不参与文档的序列化。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("user")
public class User {@MongoIdprivate Integer uid;@Fieldprivate String name;@Fieldprivate String password;@Fieldprivate Integer age;
}

3.2 添加文档

insert 方法返回值是新增的 Document 对象,里面包含了新增后 id 的值。如果集合不存在会自动创建集合。

@Test
public void test1() {// _id存在时更新数据mongoTemplate.save(new User(1, "aaa", "123456", 20));// _id存在时抛出异常mongoTemplate.insert(new User(2, "bbb", "113456", 21));List<User> list = Arrays.asList(new User(3, "ccc", "124266", 22),new User(4, "ddd", "136521", 23),new User(5, "eee", "147258", 24));// 批量插入mongoTemplate.insert(list, User.class);
}

3.3 查询文档

  • Query 类作为查询条件的容器,用于放置 Criteria 条件接口。
  • Criteria 是标准查询的接口,可以引用静态的 Criteria.where() 将字段和条件组合在一起进行查询。
@Test
public void test1() {System.out.println("==========查询所有文档===========");List<User> list = mongoTemplate.findAll(User.class);list.forEach(System.out::println);System.out.println("==========根据_id查询===========");User user = mongoTemplate.findById(3, User.class);System.out.println(user);System.out.println("==========findOne返回第一个文档===========");User one = mongoTemplate.findOne(new Query(), User.class);System.out.println(one);
}
@Test
public void test2() {System.out.println("==========条件查询===========");// 查询name为"eee"的用户Query query1 = new Query(Criteria.where("name").is("eee"));// 查询 age<23 的用户Query query2 = new Query(Criteria.where("age").lt(23));// 查询 21<=age<24 的用户Query query3 = new Query(Criteria.where("age").gte(21).lt(24));// 模糊查询Query query4 = new Query(Criteria.where("password").regex("123"));System.out.println("==========多条件查询===========");// 查询 age<24 且 密码包含"123" 的用户Criteria criteria1 = new Criteria();criteria1.andOperator(Criteria.where("age").lt(24),Criteria.where("password").regex("123"));Query query5 = new Query(criteria1);// 查询 age>23 或 密码包含"456" 的用户Criteria criteria2 = new Criteria();criteria2.orOperator(Criteria.where("age").gt(23), Criteria.where("password").regex("456"));Query query6 = new Query(criteria2);List<User> list = mongoTemplate.find(query6, User.class);list.forEach(System.out::println);
}
@Test
public void test3() {System.out.println("==========排序===========");Query query1 = new Query();query1.with(Sort.by(Sort.Order.desc("age")));System.out.println("==========分页===========");Query query2 = new Query();query2.skip(0).limit(3);List<User> list = mongoTemplate.find(query2, User.class);list.forEach(System.out::println);
}
  • 使用 JSON 字符串方式查询:
@Test
public void testFindByJson() {// 等值查询Query query1 = new BasicQuery("{name:'eee'}");// 多条件查询Query query2 = new BasicQuery("{age:{$lt:24}, password:{$regex:'123'}}");Query query3 = new BasicQuery("{$or:[{age:{$gt:23}}, {password:{$regex:'456'}}]}");List<User> list = mongoTemplate.find(query3, User.class);list.forEach(System.out::println);
}

3.4 修改文档

在 Mongodb 中无论是使用客户端 API 还是使用 Spring Data,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返回 0。

  • updateFirst():只更新满足条件的第一条记录。
  • updateMulti():更新所有满足条件的记录。
  • upsert():没有符合条件的记录则插入数据。
@Test
public void test1() {Query query = new Query(Criteria.where("name").is("eee"));Update update = new Update();update.set("age", 25);// updateFirst() 只更新满足条件的第一条记录UpdateResult updateResult = mongoTemplate.updateFirst(query, update, User.class);System.out.println("返回修改的记录数: " + updateResult.getModifiedCount());
}
@Test
public void test2() {Query query = new Query(Criteria.where("age").gt(23));Update update = new Update();update.inc("age", 1);// updateMulti() 更新所有满足条件的记录UpdateResult updateResult = mongoTemplate.updateMulti(query, update, User.class);System.out.println("返回修改的记录数: " + updateResult.getModifiedCount());
}
@Test
public void test3() {// query查询结果不存在Query query = new Query(Criteria.where("name").is("ggg"));Update update = new Update();update.set("age", 28);update.setOnInsert("_id", 7); //不存在时插入// upsert() 没有符合条件的记录则插入数据UpdateResult updateResult = mongoTemplate.upsert(query, update, User.class);System.out.println("返回修改的记录数: " + updateResult.getModifiedCount());
}

3.5 删除文档

@Test
public void testDelete() {//删除所有文档, 不如用dropCollection()//mongoTemplate.remove(new Query(),Employee.class);//条件删除Query query = new Query(Criteria.where("name").is("fff"));mongoTemplate.remove(query, User.class);
}

四、聚合操作

4.1 使用 Aggregation 实现

用 Aggregation 集合接收聚合操作,用 MongoTemplate 对象直接调用 aggregate,传入聚合操作集合、表名、映射对象。

@Test
public void testAggregation() {// 1.先定义聚合操作MatchOperation match = Aggregation.match(Criteria.where("type").is("novel"));SortOperation sort = Aggregation.sort(Sort.Direction.ASC, "favCount");// 2.按顺序组合每一个聚合步骤TypedAggregation<Book2> typedAggregation = Aggregation.newAggregation(Book2.class, match, sort);// 3.执行聚合操作, 可以使用 Document、Map、自定义实体类 接收结果AggregationResults<Document> aggregate = mongoTemplate.aggregate(typedAggregation, Document.class);List<Document> results = aggregate.getMappedResults();results.forEach(System.out::println);
}

4.2 使用 Aggregates 实现

用 Aggregates 和 Bson 构建聚合操作对象,用预先生成的 MongoCollection 对象调用 aggregate 执行。

@Test
public void testAggregates(){// 1.先通过集合名拿到所有文档MongoCollection<Document> collection = mongoTemplate.getCollection("book2");// 2.Aggregates提供各种聚合操作符,返回一个Bson对象Bson matchBson = Aggregates.match(new Document("type", "travel"));
//	Bson matchBson = Aggregates.match(Filters.eq("type", "travel"));//Filters来实现过滤Bson sortBson = Aggregates.sort(Sorts.ascending("favCount"));
//	Bson sortBson = Aggregates.sort(new Document("favCount", 1));// 3.构建一个List<Bson>, 并把每一个聚合操作按顺序加进去List<Bson> bsonList = new ArrayList<>();bsonList.add(matchBson);bsonList.add(sortBson);// 4.最后传入aggregate方法中执行,并且接收结果集AggregateIterable<Document> resultList = collection.aggregate(bsonList);resultList.forEach(System.out::println);
}
  • 示例一:统计文档中的书籍总量、收藏总数、平均收藏量
@Test
public void test1() {MongoCollection<Document> collection = mongoTemplate.getCollection("book2");Bson groupBson = Aggregates.group(null,Accumulators.sum("bookCount", 1),Accumulators.sum("favCount", "$favCount"),Accumulators.avg("favAvg", "$favCount"));List<Bson> bsonList = new ArrayList<>();bsonList.add(groupBson);AggregateIterable<Document> resultList = collection.aggregate(bsonList);resultList.forEach(System.out::println);
}
  • 示例二:统计tag标签的热度排行 (根据favCount总量排行即为热度)
@Test
public void test4() {MongoCollection<Document> collection = mongoTemplate.getCollection("book2");Bson unwindBson = Aggregates.unwind("$tag");Bson groupBson = Aggregates.group("$tag", Accumulators.sum("favCount", "$favCount"));Bson sortBson = Aggregates.sort(new Document("favCount", -1));List<Bson> bsonList = new ArrayList<>();bsonList.add(unwindBson);bsonList.add(groupBson);bsonList.add(sortBson);AggregateIterable<Document> resultList = collection.aggregate(bsonList);resultList.forEach(System.out::println);
}

4.3 应用案例

  • 示例一:统计每个作者的每本book的收藏数
@Test
public void test1() {GroupOperation group = Aggregation.group("$author.name", "$title").sum("$favCount").as("favCount");TypedAggregation<Book2> typedAggregation = Aggregation.newAggregation(Book2.class, group);AggregationResults<Document> aggregate = mongoTemplate.aggregate(typedAggregation, Document.class);List<Document> mappedResults = aggregate.getMappedResults();mappedResults.forEach(System.out::println);
}
  • 示例二:每个作者的book的tag合集
@Test
public void test2() {UnwindOperation unwind = Aggregation.unwind("$tag");GroupOperation group = Aggregation.group("$author.name").addToSet("$type").as("types");TypedAggregation<Book2> typedAggregation = Aggregation.newAggregation(Book2.class, unwind, group);AggregationResults<Document> aggregate = mongoTemplate.aggregate(typedAggregation, Document.class);List<Document> mappedResults = aggregate.getMappedResults();mappedResults.forEach(System.out::println);
}
  • 示例三:联表查询用户以及对应的订单信息
@Test
public void test1() {LookupOperation lookup = Aggregation.lookup("order", "_id", "customerId", "order");TypedAggregation<Customer> orderTypedAggregation = Aggregation.newAggregation(Customer.class, lookup);AggregationResults<Document> aggregate = mongoTemplate.aggregate(orderTypedAggregation, Document.class);List<Document> mappedResults = aggregate.getMappedResults();mappedResults.forEach(System.out::println);
}
  • 示例四:联表查询订单信息以及对应的商品项
@Test
public void test2() {LookupOperation lookup = Aggregation.lookup("orderItem", "_id", "orderId", "orderItem");TypedAggregation<Order> orderItemTypedAggregation = Aggregation.newAggregation(Order.class, lookup);AggregationResults<Document> aggregate = mongoTemplate.aggregate(orderItemTypedAggregation, Document.class);List<Document> mappedResults = aggregate.getMappedResults();mappedResults.forEach(System.out::println);
}

相关文章:

  • 使用com组件编辑word
  • 【每日易题】Leetcode上Hard难度的动态规划题目——地下城游戏的实现
  • Android wifi 框架以及Enable流程
  • 第八节HarmonyOS @Component自定义组件的生命周期
  • ubuntu虚拟机设置跳不出来
  • 【Rust】所有权的认识
  • 华为 ArkTS 边框怎么设置,当边边框怎么设置(鸿蒙开发)
  • 模拟电路学习笔记(一)之芯片篇(持续更新)
  • postgreSQL 查询所有模式的语句
  • 2023年JetBrains开发调查:Java 8仍广泛使用
  • MyBatis查询优化:枚举在条件构建中的妙用
  • OA系统是什么,能用低代码开发吗?
  • 外包干了2个月,技术明显退步了...
  • Sequential Modeling Enables Scalable Learning for Large Vision Models
  • Spring Security 6.x 系列(7)—— 源码分析之Builder设计模式
  • Android优雅地处理按钮重复点击
  • JavaScript标准库系列——Math对象和Date对象(二)
  • JavaWeb(学习笔记二)
  • Laravel Mix运行时关于es2015报错解决方案
  • learning koa2.x
  • Less 日常用法
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • PHP的Ev教程三(Periodic watcher)
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • sessionStorage和localStorage
  • Spring框架之我见(三)——IOC、AOP
  • storm drpc实例
  • 代理模式
  • 聊聊flink的BlobWriter
  • 排序(1):冒泡排序
  • 巧用 TypeScript (一)
  • 设计模式走一遍---观察者模式
  • 使用 QuickBI 搭建酷炫可视化分析
  • 吐槽Javascript系列二:数组中的splice和slice方法
  •  一套莫尔斯电报听写、翻译系统
  • MPAndroidChart 教程:Y轴 YAxis
  • 数据库巡检项
  • ​linux启动进程的方式
  • ​queue --- 一个同步的队列类​
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • #Z0458. 树的中心2
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (02)vite环境变量配置
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (SpringBoot)第二章:Spring创建和使用
  • (阿里云万网)-域名注册购买实名流程
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (转载)虚函数剖析
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .form文件_一篇文章学会文件上传
  • .net core开源商城系统源码,支持可视化布局小程序