MongoDB - 聚合阶段 $group 的使用
文章目录
- 1. 构造测试数据
- 1. 示例 1
- 2. 示例2
- 3. 示例3
- 4. 示例4
- 5. 示例5
- 2. 构造测试数据
- 1. 示例1
- 2. 示例2
- 3. 示例3
在 MongoDB 中,$group 是聚合管道中的一个阶段,用于根据指定的条件对文档进行分组。
{$group: {_id: <expression>, // 分组的依据,可以是字段名或表达式<field1>: { <accumulator1> : <expression1> }, // 对字段进行聚合操作<field2>: { <accumulator2> : <expression2> },...}
}
_id 字段必填,指定了分组的键。如果指定的 _id 值为空值或任何其他常量值,$group 阶段将返回聚合所有输入文档值的单个文档。
<field1> 是要输出的字段名,可以是现有字段或新的计算字段。
<accumulator1> 是聚合操作符,用于对分组内的文档进行计算。
<expression1> 是要应用于每个分组的表达式,用于计算聚合操作的结果。
以下是一些常用的聚合操作符:
$sum:计算指定字段的总和。
$avg:计算指定字段的平均值。
$min:计算指定字段的最小值。
$max:计算指定字段的最大值。
$push:将指定字段的值添加到数组中。
$addToSet:将指定字段的唯一值添加到集合中。
$first:返回每个分组中指定字段的第一个值。
$last:返回每个分组中指定字段的最后一个值。
1. 构造测试数据
db.sales.drop()db.sales.insertMany([
{"_id": 1,"item": "abc","price": Decimal128("10"),"quantity": Int32("2"),"date": "2014-03-01"
},
{"_id": 2,"item": "jkl","price": Decimal128("20"),"quantity": Int32("1"),"date": "2014-03-01"
},
{"_id": 3,"item": "xyz","price": Decimal128("5"),"quantity": Int32("10"),"date": "2014-03-15"
},
{"_id": 4,"item": "xyz","price": Decimal128("5"),"quantity": Int32("20"),"date": "2014-04-04"
},
{"_id": 5,"item": "abc","price": Decimal128("10"),"quantity": Int32("10"),"date": "2014-04-04"
},
{"_id": 6,"item": "def","price": Decimal128("7.5"),"quantity": Int32("5"),"date": "2015-06-04"
},
{"_id": 7,"item": "def","price": Decimal128("7.5"),"quantity": Int32("10"),"date": "2015-09-10"
},
{"_id": 8,"item": "abc","price": Decimal128("10"),"quantity": Int32("5"),"date": "2016-02-06"
}
])
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "sales")
public class Sales {private ObjectId id;private String item;private Decimal128 price;private int quantity;private Date date;
}
1. 示例 1
按 item 字段对文档进行分组
db.sales.aggregate([{ $group: { _id: "$item" } }
])
{ "_id" : "abc" }
{ "_id" : "jkl" }
{ "_id" : "def" }
{ "_id" : "xyz" }
SpringBoot 整合 MongoDB实现上述操作:
@Data
@Document(collection = "sales")
public class Sales {@Idprivate String id;private String item;private Decimal128 price;private int quantity;private Date date;
}@Data
public class AggregationResult {private String id;
}
@Test
public void aggregateTest() {GroupOperation groupOperation = Aggregation.group("item");Aggregation aggregation = Aggregation.newAggregation(groupOperation);// aggregate():参数的顺序为聚合管道的定义、输入类型、输出类型AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Sales.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=xyz)//AggregationResult(id=jkl)//AggregationResult(id=def)//AggregationResult(id=abc)
}
2. 示例2
$group 阶段按 item 对文档进行分组,并计算返回每个一项的总销售额totalSaleAmount
db.sales.aggregate([// First Stage{$group :{_id : "$item",totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }}}])
// 1
{"_id": "xyz","totalSaleAmount": Decimal128("150")
}// 2
{"_id": "jkl","totalSaleAmount": Decimal128("20")
}// 3
{"_id": "def","totalSaleAmount": Decimal128("112.5")
}// 4
{"_id": "abc","totalSaleAmount": Decimal128("170")
}
SpringBoot 整合 MongoDB实现上述操作:
@Data
@Document(collection = "sales")
public class Sales {@Idprivate String id;private String item;private Decimal128 price;private int quantity;private Date date;
}@Data
public class AggregationResult {private String id;private Decimal128 totalSaleAmount;
}
@Test
public void aggregateTest() {GroupOperation groupOperation = Aggregation.group("item").sum(ArithmeticOperators.Multiply.valueOf("price").multiplyBy("quantity")).as("totalSaleAmount");Aggregation aggregation = Aggregation.newAggregation(groupOperation);// aggregate():参数的顺序为聚合管道的定义、输入类型、输出类型AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Sales.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=xyz, totalSaleAmount=150)//AggregationResult(id=jkl, totalSaleAmount=20)//AggregationResult(id=def, totalSaleAmount=112.5)//AggregationResult(id=abc, totalSaleAmount=170)
}
3. 示例3
第一个阶段:
$group 阶段按 item 对文档进行分组,以检索非重复的项值。此阶段返回每一项的 totalSaleAmount。
第二个阶段:
$match 阶段会对生成的文档进行筛选,从而只返回 totalSaleAmount 大于或等于 100 的项目。
db.sales.aggregate([// First Stage{$group :{_id : "$item",totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }}},// Second Stage{$match: { "totalSaleAmount": { $gte: 100 } }}])
// 1
{"_id": "xyz","totalSaleAmount": Decimal128("150")
}// 2
{"_id": "def","totalSaleAmount": Decimal128("112.5")
}// 3
{"_id": "abc","totalSaleAmount": Decimal128("170")
}
这个聚合操作相当于以下 SQL 语句:
SELECT item,Sum(( price * quantity )) AS totalSaleAmount
FROM sales
GROUP BY item
HAVING totalSaleAmount >= 100
SpringBoot 整合 MongoDB实现上述操作:
@Data
public class AggregationResult {private String id;private Decimal128 totalSaleAmount;
}
@Test
public void aggregateTest() {// 第一个阶段GroupOperation groupOperation = Aggregation.group("item").sum(ArithmeticOperators.Multiply.valueOf("price").multiplyBy("quantity")).as("totalSaleAmount");// 第二个阶段MatchOperation matchOperation = Aggregation.match(Criteria.where("totalSaleAmount").gte(100));Aggregation aggregation = Aggregation.newAggregation(groupOperation,matchOperation);// aggregate():参数的顺序为聚合管道的定义、输入类型、输出类型AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Sales.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=xyz, totalSaleAmount=150)//AggregationResult(id=def, totalSaleAmount=112.5)//AggregationResult(id=abc, totalSaleAmount=170)
}
4. 示例4
计算 2014 年每一天的总销售额、平均销售数量和销售数量:
第一个阶段:
$match 阶段会对这些文档进行筛选,仅将从 2014 年开始的文档传递到下一阶段。
第二个阶段:
$group 阶段按日期对文档分组,并计算每组文档的总销售金额、平均数量和总数。
第三个阶段:
$sort 阶段按每个组的总销售金额对结果进行降序排序。
db.sales.aggregate([// First Stage{$match : { "date": { $gte: "2014-01-01", $lt: "2015-01-01" } }},// Second Stage{$group : {_id : "$date",totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },averageQuantity: { $avg: "$quantity" },count: { $sum: 1 }}},// Third Stage{$sort : { totalSaleAmount: -1 }}])
// 1
{"_id": "2014-04-04","totalSaleAmount": Decimal128("200"),"averageQuantity": 15,"count": 2
}// 2
{"_id": "2014-03-15","totalSaleAmount": Decimal128("50"),"averageQuantity": 10,"count": 1
}// 3
{"_id": "2014-03-01","totalSaleAmount": Decimal128("40"),"averageQuantity": 1.5,"count": 2
}
这个聚合操作相当于以下 SQL 语句:
SELECT date,Sum(( price * quantity )) AS totalSaleAmount,Avg(quantity) AS averageQuantity,Count(*) AS Count
FROM sales
WHERE date >= '01/01/2014' AND date < '01/01/2015'
GROUP BY date
ORDER BY totalSaleAmount DESC
SpringBoot 整合 MongoDB实现上述操作:
@Data
public class AggregationResult {private String id;private Decimal128 totalSaleAmount;private Double averageQuantity;private Integer count;
}
@Test
public void aggregateTest() {// 第一个阶段MatchOperation matchOperation = Aggregation.match(Criteria.where("date").gte("2014-01-01").lte("2015-01-01"));// 第二个阶段GroupOperation groupOperation = Aggregation.group("date").sum(ArithmeticOperators.Multiply.valueOf("price").multiplyBy("quantity")).as("totalSaleAmount").avg("quantity").as("averageQuantity").count().as("count");// 第三个阶段SortOperation sortOperation = Aggregation.sort(Sort.by(Sort.Direction.DESC, "totalSaleAmount"));// 组合上面的3个阶段Aggregation aggregation = Aggregation.newAggregation(matchOperation,groupOperation,sortOperation);AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Sales.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=2014-04-04, totalSaleAmount=200, averageQuantity=15.0, count=2)//AggregationResult(id=2014-03-15, totalSaleAmount=50, averageQuantity=10.0, count=1)//AggregationResult(id=2014-03-01, totalSaleAmount=40, averageQuantity=1.5, count=2)
}
5. 示例5
聚合操作指定了 null 的 _id 组,计算集合中所有文档的总销售额、平均数量和计数。
db.sales.aggregate([{$group : {_id : null,totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },averageQuantity: { $avg: "$quantity" },count: { $sum: 1 }}}])
{"_id" : null,"totalSaleAmount" : Decimal128("452.5"),"averageQuantity" : 7.875,"count" : 8
}
这个聚合操作相当于以下 SQL 语句:
SELECT Sum(price * quantity) AS totalSaleAmount,Avg(quantity) AS averageQuantity,Count(*) AS Count
FROM sales
SpringBoot 整合 MongoDB实现上述操作:
@Data
public class AggregationResult {private String id;private Decimal128 totalSaleAmount;private Double averageQuantity;private Integer count;
}
@Test
public void aggregateTest() {GroupOperation groupOperation = Aggregation.group().sum(ArithmeticOperators.Multiply.valueOf("price").multiplyBy("quantity")).as("totalSaleAmount").avg("quantity").as("averageQuantity").count().as("count");// 组合上面的3个阶段Aggregation aggregation = Aggregation.newAggregation(groupOperation);AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Sales.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=null, totalSaleAmount=452.5, averageQuantity=7.875, count=8)
}
2. 构造测试数据
db.oredrs.insertMany([{ orderId: 1, customerId: 1, amount: 100 },{ orderId: 2, customerId: 2, amount: 200 },{ orderId: 3, customerId: 1, amount: 150 },{ orderId: 4, customerId: 3, amount: 300 },{ orderId: 5, customerId: 2, amount: 250 }
])
@Data
@Document(collection = "orders")
public class Order {private int orderId;private int customerId;private double amount;
}
1. 示例1
计算每个客户的订单总额:group阶段根据 customerId 字段对订单文档进行分组,然后使用 sum 操作符计算每个客户的订单总额。
db.orders.aggregate([{$group: {_id: "$customerId",totalAmount: { $sum: "$amount" }}}
])
// 1
{"_id": 3,"totalAmount": 600
}// 2
{"_id": 2,"totalAmount": 900
}// 3
{"_id": 1,"totalAmount": 500
}
SpringBoot 整合 MongoDB实现上述操作:
@Data
public class AggregationResult {private String id;private Integer totalAmount;
}
@Test
public void aggregateTest() {GroupOperation groupOperation = Aggregation.group("customerId").sum("amount").as("totalAmount");// 组合上面的3个阶段Aggregation aggregation = Aggregation.newAggregation(groupOperation);AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Order.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=3.0, totalAmount=300)//AggregationResult(id=2.0, totalAmount=450)//AggregationResult(id=1.0, totalAmount=250)
}
2. 示例2
计算每个客户的订单数量和平均订单金额:group阶段根据 customerId 字段对订单文档进行分组,然后使用 $sum 操作符计算每个客户的订单数量,并使用 $avg 操作符计算每个客户的平均订单金额。
db.orders.aggregate([{$group: {_id: "$customerId",count: { $sum: 1 },averageAmount: { $avg: "$amount" }}}
])
// 1
{"_id": 3,"count": 1,"averageAmount": 300
}// 2
{"_id": 2,"count": 2,"averageAmount": 225
}// 3
{"_id": 1,"count": 2,"averageAmount": 125
}
SpringBoot 整合 MongoDB实现上述操作:
@Data
public class AggregationResult {private String id;private Integer count;private Integer averageAmount;
}
@Test
public void aggregateTest() {GroupOperation groupOperation = Aggregation.group("customerId").count().as("count").avg("amount").as("averageAmount");// 组合上面的3个阶段Aggregation aggregation = Aggregation.newAggregation(groupOperation);AggregationResults<AggregationResult> results= mongoTemplate.aggregate(aggregation, Order.class, AggregationResult.class);List<AggregationResult> mappedResults = results.getMappedResults();mappedResults.forEach(System.out::println);//AggregationResult(id=3.0, count=1, averageAmount=300)//AggregationResult(id=2.0, count=2, averageAmount=225)//AggregationResult(id=1.0, count=2, averageAmount=125)
}
3. 示例3
按照订单金额范围统计订单数量:group阶段使用 $switch 操作符根据订单金额对订单文档进行分组。根据订单金额是否小于200,将订单分为"小额订单"和"大额订单"两个组。然后使用$sum操作符计算每个组的订单数量。
db.orders.aggregate([{$group: {_id: {$switch: {branches: [{ case: { $lt: ["$amount", 200] }, then: "小额订单" },{ case: { $gte: ["$amount", 200] }, then: "大额订单" }],default: "其他"}},count: { $sum: 1 }}}
])
// 1
{"_id": "大额订单","count": 3
}// 2
{"_id": "小额订单","count": 2
}
相关文章:
MongoDB - 聚合阶段 $group 的使用
文章目录 1. 构造测试数据1. 示例 12. 示例23. 示例34. 示例45. 示例5 2. 构造测试数据1. 示例12. 示例23. 示例3 在 MongoDB 中,$group 是聚合管道中的一个阶段,用于根据指定的条件对文档进行分组。 {$group: {_id: <expression>, // 分组的依据…...
Flutter 插件之 easy_refresh(下拉刷新、上拉加载)
今天给大家较少一下日常开发中最常见的一个功能,就是 下拉刷新、上拉加载,这个在我们使用分页功能是最常见的。 此前我我也写了一篇关于 下拉刷新、上拉加载。 Flutter 下拉刷新、上拉加载flutter_easyrefresh的使用https://blog.csdn.net/WangQingLei0307/article/details/…...
DVWA的安装和使用
背景介绍 DVWA是Damn Vulnerable Web Application的缩写,是一个用于安全脆弱性检测的开源Web应用。它旨在为安全专业人员提供一个合法的测试环境,帮助他们测试自己的专业技能和工具,同时也帮助web开发者更好地理解web应用安全防范的过程。DV…...
CSS相关记录
文章目录 backgroundposition文字displayflexjustify-contentalign-itemsflex-directionflex-wrap gridimportant transformtranslate(位移)scale(缩放)rotate(旋转)origin (旋转中心点)skew (倾斜 ) borde…...
Fedora40安装telnet-server启用telnet服务
Fedora40安装telnet-server启用telnet服务 安装 telnet-server sudo yum install telnet-server或 sudo dnf install telnet-server启用服务 fedora40 或 CentosStream9 不能用 yum或dnf安装xinetd, telnet-server 的服务名为: telnet.socket 启用 telnet.socket.service …...
Unity3D结合AI教育大模型 开发AI教师 AI外教 AI英语教师案例
自2022年底ChatGPT引爆全球之后,大模型技术便迎来了一段崭新的快速发展期,由其在GPT4.0发布后,AI与教育领域结合产品研发、已成为教育AI科技竞争的新高地、未来产业的新赛道、经济发展的新引擎和新产品的诞生地。 据不完全统计,目…...
lua 游戏架构 之 SceneLoad场景加载(一)
设计一个为BaseSceneLoad class,用于处理场景加载的相关操作 ,主要作用是提供了一个通用的场景加载框架,使得子类可以按照统一的接口进行场景加载操作。子类需要实现这些方法,以便在加载场景时能够正确地处理场景加载的各个阶段。…...
【linux深入剖析】命名管道 | 匿名管道与命名管道的区别 | system V共享内存
🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 1. 命名管道2. 创建命名管…...
Vite 常用插件配置:自动导入+自动注册组件+动态创建图标+设置组件名
创建 Vue3Vite 项目 创建 Vue3 项目 $ pnpm create vuelatest通过脚手架选择开启以下功能 ✔ Project name: … <your-project-name> ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application development?…...
(leetcode学习)236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖…...
Zabbix监控系统:zabbix服务部署+基于Proxy分布式部署+zabbix主动与被动监控模式
一、Zabbix概述 1.1 简介 zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 zabbix 能监视各种网络参数,保证服务器系统的安全运营,提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbix…...
【Vue实战教程】之 Vue Router 路由详解
Vue Router路由 1 路由基础 1.1 什么是路由 用Vue.js创建的项目是单页面应用,如果想要在项目中模拟出来类似于页面跳转的效果,就要使用路由。其实,我们不能只从字面的意思来理解路由,从字面上来看,很容易把路由联想…...
测试用例接口开发实战
测试用例接口开发实战 前言 在上一集,我们也大概完成了对Jmeter的二次开发的Demo版本的了解,我们接下来就要基于这个Demo来将Jmeter压测进行平台化。 那么这一集,我们讲一讲测试用例接口开发实战。 StressCaseController 我们的Controll…...
C#中压缩文件夹,及其内容
压缩包格式,本文主要用于说明如何使用代码 文件或文件夹压缩为 zip压缩包及其解压操作, 下面分两个版本进行实现 1.简单版本 bool DoCompressDirectoryInfo(string folderPath){try{var zipFilePath $"{folderPath}.zip";var directoryInfo …...
机器学习 | 回归算法原理——多项式回归
Hi,大家好,我是半亩花海。接着上次的最速下降法(梯度下降法)继续更新《白话机器学习的数学》这本书的学习笔记,在此分享多项式回归这一回归算法原理。本章的回归算法原理基于《基于广告费预测点击量》项目,…...
力扣224【基本计算器】
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。 1 < s.length < 3 * 105 s 由数字、‘’、‘-’、‘(’、‘)’、和 ’ ’ 组成 s 表示一个有效的…...
【Linux】HTTP 协议
目录 1. URL2. HTTP 协议2.1. HTTP 请求2.2. HTTP 响应 1. URL URL 表示着是统一资源定位符(Uniform Resource Locator), 就是 web 地址,俗称“网址”; 每个有效的 URL 可以通过互联网访问唯一的资源, 是互联网上标准资源的地址; URL 的主要由四个部分组成: sche…...
@Builder注释导致@RequestBody的前端json反序列化失败,HTTP400
项目里发生了一个bug,就是前端请求一个接口时候,报了HTTP 400 Bad Request 通常来说这个问题是前后端的参数没对齐,比如前端传了个String,但后端对应的是Integer。 所以我就排查了半天,结果没发现啥错误,…...
网络学习|如何理解服务的端口号
文章目录 1. 端口号的定义2. 端口号的分类3. 端口号的用途4. 注意事项5. 示例图解 后端面试中可能遇到的端口相关问题及答案1. 什么是端口号?为什么需要端口号?2. 知名端口(Well-Known Ports)有哪些,举例说明ÿ…...
《0基础》学习Python——第十八讲__爬虫/<1>
一、什么是爬虫 爬虫是一种网络数据抓取的技术。通过编写程序(通常使用Python),爬虫可以自动化地访问网页,解析网页内容并提取出所需的数据。爬虫可以用于各种用途,如搜索引擎的索引,数据分析和挖掘&#x…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
