mongoDb是noSql数据库,对于一对多关系的建表我们要跳出关系型数据库的建表思路。

可以把多方的关系放在一方维护,那样查询效率会快很多。而维护的方式有两种,一种是嵌入式文档,另一种是数据库引用方式,即把另一文档作为一个集合,它们的_id放在一方形成数组,这样来维护一对多关系。如果关联的多方集合的文档数据太大,在一方的集合的一个文档要存放的数量过大,可能会超出单个文档的大小,就只能像关系型数据库那样维护一对多的关系。

//MongoDB 数据库引用的创建
db.user.createIndex({"_id":ObjectId("53402597d852426020000002"),"address": {"$ref": "address_home","$id": ObjectId("534009e4d852427820000002"),"$db": "runoob"},"contact": "987654321","dob": "01-01-1991","name": "Tom Benzamin"
})
//查找
db.user.find({"xxxx_ids" : DBRef("user", ObjectId("5d25d7bbd195eae596ec012e"))})
{ "_id" : ObjectId("5d25e580d195eae596ec0132"), "fsdfds" : "aaaaaa", "xxxx_ids" : DBRef("user", ObjectId("5d25d7bbd195eae596ec012e")) }
db.user.insertMany(
[
{"address": {"province": "HeNan","city": "ZhengZhou","pincode": "123"},"tags": ["music","cricket","blogs"],"name": "fly"
},
{"address": {"province": "HeBei","city": "HanDan","pincode": "234"},"tags": ["music","basket","blogs"],"name": "chen"
},
{"address": {"province": "ChongQing","city": "ChongQing","pincode": "456"},"tags": ["music","writing","running"],"name": "wang"
}
]
)

在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。

//创建数组索引
db.user.ensureIndex({"tags":1})
//为了验证我们使用使用了索引,可以使用 explain 命令
db.user.find({tags:"music"}).explain()
//查看创建了哪些索引
db.user.getIndexes()

可以看得出在数组字段上建立索引的代价比较大,因为每次的删除,更新都会对每一个索引进行刷新,太消耗服务器的资源;

可以针对数组字段中的某一个元素做具体的单独索引,减少索引的数量;

//在数组字段tags中的第1个元素上建立索引:
db.user.ensureIndex({"tags.0":1})

同样,只有精确匹配tags.0查询,上述索引才会起到索引的作用

索引子文档字段

假设我们需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。为子文档的三个字段创建索引,命令如下:

db.user.ensureIndex({"address.province":1,"address.city":1,"address.pincode":1})
//记住查询表达式必须遵循指定的索引的顺序。所以上面创建的索引将支持以下查询
db.user.find({"address.province":"HeNan","address.city":"ZhengZhou"})
//同样支持以下查询
db.user.find({"address.province":"HeNan","address.city":"ZhengZhou","address.pincode":"123"})

下面开始正式mongodb一对多springboot的编写

由于mongodb不存在级联操作,所以单集合的增删查改嵌套到1对多的关系里也就是1对多的增删查改。另外DBRef并不会检查外键,即使关联集合的主键不存在,也能插入。只不过查询时,如果DBRef关联的外键存在那么相应的子文档也会查询出来,否则查询的子文档为空,但不报错。

添加maven依赖如下

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

在application.properties配置mongodb连接地址

spring.data.mongodb.uri=mongodb://localhost:27017/smartheadset

添加Configuration

@Configuration
public class SpringMongoConfig {@Beanpublic MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);try {mappingConverter.setCustomConversions(beanFactory.getBean(MongoCustomConversions.class));} catch (NoSuchBeanDefinitionException ignore) {}// Don't save _class to mongomappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return mappingConverter;}
}

单方

package com.qctchina.headsetserver.entity;import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.List;/*** @author shuangyueliao* @creae 2019/7/16 10:04* @Version 0.1*/
@Document(collection = "listen_course")
@Data
public class ListenCourse {@Idprivate ObjectId listenCourseId;private String courseName;private String publisher;private String author;private String category;private String courseAbstract;private String courseDescription;@DBRefprivate List<ListenCourseItem> listenCourseItemList;
}

多方

package com.qctchina.headsetserver.entity;import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;/*** @author shuangyueliao* @creae 2019/7/16 10:05* @Version 0.1*/
@Data
@Document(collection = "listen_course_item")
public class ListenCourseItem {@Idprivate ObjectId listenCourseItemId;private Integer duration;private String audioName;private String audioOrder;private String audioText;private String format;private String audioMd5;
}

注入mongoTemplate

@Autowired
private MongoTemplate mongoTemplate;

增加

public ListenCourse addCourse(ListenCourse listenCourse) {listenCourse = mongoTemplate.insert(listenCourse);return listenCourse;}

分页查询

@Data
public class PageModel<T> {private int pageIndex;//当前页private long total;//记录数private int pageSize;//每页显示条数private int pages;//总页数private List<T> result;//结果集/*** 获取总页数** @return*/public int getPages() {return ((int) total + pageSize - 1) / pageSize;}/*** 取得首页** @return*/public int getTopPageNo() {return 1;}/*** 上一页** @return*/public int getPreviousPageNo() {if (pageIndex <= 1) {return 1;}return pageIndex - 1;}/*** 下一页** @return*/public int getNextPageNo() {if (pageIndex >= getBottomPageNo()) {return getBottomPageNo();}return pageIndex + 1;}/*** 取得尾页** @return*/public int getBottomPageNo() {return getPages();}
}
public PageModel<ListenCourse> queryCourse(PageParamBase pageParamBase) {long count = mongoTemplate.count(new Query(), ListenCourse.class);Query query = new Query();int skip = (pageParamBase.getPageNum() - 1) * pageParamBase.getPageSize();query.skip(skip).limit(pageParamBase.getPageSize());List<ListenCourse> listenCourses = mongoTemplate.find(query, ListenCourse.class);PageModel<ListenCourse> pageModel = new PageModel<>();pageModel.setPageSize(pageParamBase.getPageSize());pageModel.setPageIndex(pageParamBase.getPageNum());pageModel.setTotal(count);pageModel.setPages(pageModel.getPages());pageModel.setResult(listenCourses);return pageModel;}

查询,查询主键用listenCouseId或_id均可,在mongodb中存的是_id

@Overridepublic ListenCourse queryCourseById(String id) {Query query = new Query();ObjectId objectId = new ObjectId(id);query.addCriteria(Criteria.where("listenCourseId").is(objectId));ListenCourse listenCourse = mongoTemplate.findOne(query, ListenCourse.class);return listenCourse;}

更新

public boolean updateCourseById(String id) {Query query = new Query(Criteria.where("_id").is(new ObjectId(id)));Update update = Update.update("courseDescription", "change1");UpdateResult updateResult = mongoTemplate.updateFirst(query, update, ListenCourse.class);return updateResult.getModifiedCount() > 0;}

手动级联删除

public boolean deleteCourseById(String id) {ListenCourse listenCourse = mongoTemplate.findOne(new Query(Criteria.where("_id").is(new ObjectId(id))), ListenCourse.class);ListenCourseItem item = listenCourse.getListenCourseItemList().get(0);if (item != null) {DeleteResult remove1 = mongoTemplate.remove(item);}DeleteResult remove =  mongoTemplate.remove(listenCourse);return remove.getDeletedCount() > 0;}

mongoDb一对多之springboot demo相关推荐

  1. IDEA下载与配置,搭建springboot Demo

    1 idea下载 下载地址:https://www.jetbrains.com/idea/download/#section=windows 2 配置热部署插件JRebel 2.1先在idea上安装好 ...

  2. SpringBoot demo初始

    SpringBoot 初始 需求描述 通过spring boot搭建并配置简单的服务实例,通过访问http://localhost:8080/index显示 {"上海":" ...

  3. 【校招VIP】“推推”项目课程Java:SpringBoot demo的说明、入门和下载

    本课程涉及的Springboot商用多组件Maven框架DEMO,可关注[校招VIP]公众号,回复[9001],可自行下载. 大家好,我是校招VIP的大拿老师.那么我们继续开始推推课程的第二节,搭建商 ...

  4. mongodb常用语句以及SpringBoot中使用mongodb

    普通查询 某个字段匹配数组内的元素数量的,假如region只有一个元素的 db.getCollection('map').find({region:{$size:1}}) 假如region只有0个元素 ...

  5. Alibaba Dubbo 和 Apache Dubbo两个版本的SpringBoot Demo整合

    博主最近在学习微服务的相关框架,针对Dubbo+Zookeeper进行实操. Dubbo是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡 ...

  6. SpringBoot 集成 Spring Data Mongodb 操作 MongoDB 详解

    一.MongoDB 简介 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,且与关系数据库的最为相像的.它支持的数据结构非常松散,是类似 json 的 bso ...

  7. SpringBoot 利用MongoDB存储图片文件

    文件存储 -- 替代文件服务器 MongoDB 分片, 当你一台文件服务器硬盘不够的时候, 分片轻而易举解决这个问题 大批量文件, 图片, 视频, 音频 考虑采用 MongoDB gridfs pac ...

  8. SpringBoot与MongoDB的集成使用

    wshanshi:来自喵桑的叹息,周末马上过去了-还是睡不醒的状态- 一.MongoDB简介 1.1.什么是MongoDB? MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据 ...

  9. SpringBoot整合MongoDB 及 基本使用

    目录 1.MongoDB基本介绍 2.MongoDB的特点 3.MongoDB的体系结构 4.MongoDB的数据类型 5.SpringBoot整合MongoDB ** 1.导入依赖 2.启动Mong ...

  10. 四、Springboot连接mongodb

    Springboot连接mongodb博客 Springboot连接mongodb,mongodb是一个非关系型数据库,文档型数据库,存储的内容是JSON格式的文档,文档中可以包含各种类型的数据. S ...

最新文章

  1. Quartz使用示例总结
  2. 大数据在高校的应用场景_制造业人工智能8大应用场景
  3. python爬虫简单的添加代理进行访问
  4. 关于gitgithub的操作
  5. linux 目录sbit,linux中SUID,SGID与SBIT的奇妙用途详解
  6. win7c盘空间越来越小_电脑一分钟小技巧:如何更改电脑桌面路径?
  7. SpringBoot整合WebSocket实现前后端互推消息
  8. USB 3.1 与 Type-C 接口有什么关系呢
  9. 最想学 Go、Python,全栈开发者紧缺!分析了 11 万条程序员数据后有了这些发现...
  10. lumion自动保存_全是踩过的坑,20条新人必看的Lumion良好操作习惯
  11. Excel表格的35招必学秘技[配图]
  12. 计算机应用期刊投中难吗,计算机应用研究投稿水平高吗
  13. 切换电脑计算机名称软件,多电脑切换器
  14. 苹果内存不够怎么办_手机内存清理了还是不够用?不知道这些方法,真是太可惜了...
  15. python中label函数_python实现在函数图像上添加文字和标注的方法
  16. webservice二进制文件传输
  17. LL库下STM32使用安信可VB离线语音识别
  18. 一个简单的软件测试流程(附带流程详解)
  19. ubuntu20.04 日常办公
  20. 药店app的布局html,APP界面常用的8种页面布局

热门文章

  1. 802.11-2020协议学习__$12-Security__$12.3.2-WEP__1
  2. [研一上]人脸属性迁移文献梳理(1)
  3. 自己做的js甘特图插件
  4. Stressful Training(二分+贪心+优先队列)
  5. 地理信息系统名词解释大全(三)
  6. 计算机科学论文生成器,软件自动生成假论文:满篇废话
  7. 可视化图表告诉你,《人世间》《余生,请多指教》到底爆没爆?
  8. 初来乍到,请多多指教
  9. DNS-域名系统 【应用层】【计算机网络】
  10. php font 字体加粗,字体加粗(font-weight)