【后端开发实习】用MongoDB实现仓库管理的出库入库实战
用MongoDB实现仓库管理的出库入库
- MongoDB
- 什么是MongoDB
- MongoDB安装以及开始运行
- 配置启动以及mongosh
- mongodb的基础使用命令
- 启动和使用MongoDB服务
- 数据库操作
- 集合操作
- 文档操作
- 项目部署
- 在数据库中创建一张商品信息表
- 提供信息表的增删改查操作接口
MongoDB
什么是MongoDB
Mongodb是一种比较常见的NoSQL类型数据库,所谓NoSQL就是Not only SQL,非关系型数据库,数据在MongoDB中的存储相比MySQL而言比较松散,并没有特定的数据结构,存储方式类似JSON,采用了一种二进制的BSON来进行数据存储。但是MongoDB由于以下的几个优势在互联网需要处理海量数据场景下有独特的优势,比较经典的应用场景有微信和Twitter每天数以TB甚至PB级别的数据量。
- 高性能
- 高可用
- 高扩展
- 丰富的查询支持
MongoDB安装以及开始运行
安装成功运行会看到上面这张结果图。
配置启动以及mongosh
在命令行中输入如下命令:
sudo vim /etc/systemd/system/mongodb.service
在打开的mongodb.service文件中填入以下内容:
[Unit]
Description=High-performance, schema-free document-oriented database
After=network.target[Service]
User=mongodb
ExecStart=/usr/bin/mongod --quiet --config /etc/mongod.conf[Install]
WantedBy=multi-user.target
配置成功以后输入mongo就可以与数据库连接上并进行相关操作。
mongodb的基础使用命令
启动和使用MongoDB服务
# 重新加载配置,并启动mongodb
sudo systemctl daemon-reload
sudo systemctl start mongod# 查看运行状态
sudo systemctl status mongod
# 如果mongodb状态为stop,则运行 sudo systemctl enable mongod# 停止mongodb
sudo systemctl stop mongod# 重启mongodb
sudo systemctl restart mongod
数据库操作
# 创建和切换数据库,命名规范:全部小写
use dbname
# 删除数据库,主要是用来删除已经从内存持久化到磁盘中的数据库
db.dropDatabse()
# 显示已经创建的数据库
show dbs
集合操作
# 创建集合
db.createCollection("collectionname")
# 删除集合
db.collectionname.drop()
# 显示已经创建的数据库
show dbs
!注:这里还有一个是集合的隐式创建,通过在文档操作的时候insert操作如果没有匹配到现有数据库,就创建一个。
文档操作
# 创建文档
db.collectionname.insert({BSON格式数据})
# 文档数据查询
db.collectionname.find()
# 文档数据更新,直接使用是覆盖更新
db.collectionname.update(query, update, options)
# 局部更新,使用$set修改器
db.collectionname.update({userId:"1001"},{$set:{username="张三"}})
# 批量更新,在option选项中增加multi:true
db.collectionname.update({userId:"1001"},{$set:{username="张三"}})
# 文档删除,如果没有带条件就是“删库跑路”
db.collectionname.remove(query)
! 注:mongodb中默认的是浮点类型的数据,因此想使用整型变量的时候需要用NumberInt函数进行转换。
项目部署
在数据库中创建一张商品信息表
由于已经有MongoCampass这个图形化的工具,在创建的时候可以使用这个提高效率而不用一行一行输入数据。
创建好集合以后就可以向集合中插入文档数据,编辑好一行以后按加号继续编辑下一行。
提供信息表的增删改查操作接口
这个部分的内容有一位大佬总结的很好了,这里贴出他的博客,非常建议学习,他总结的关于Schema和Collection还有Document之间的关系使我茅塞顿开。
//引入mongodb数据库 => MongoClient mongo =>客户端
const {MongoClient} = require("mongodb");// mongo连接网址
const url = 'mongodb://127.0.0.1:27017';//mongo连接 数据库名称
const dbName = 'Shop';async function connect() {
// 注意点:由于 MongoClient.connect() 返回的是一个promise对象 因此可以使用async 和 await
// console.log(MongoClient.connect(url)); //(MongoClient.connect(url) 返回一个Promise对象)const client = await MongoClient.connect(url); //链接数据库const db = client.db(dbName); //匹配数据库return {client,db}
}//数据库操作之 增函数 参数1:集合 参数2:data数据(增的数据)
async function insert(colName, data) {
//1:链接数据库 并且把db 和 client在链接数据库中导出 let {db,client} = await connect()//2:匹配数据库集合const collection = db.collection(colName);
//3:需要判断传入的数据 是一条还是多条 一条就是insertOne 多条就是insertMany 在集合之中插入数据 const result = await collection[Array.isArray(data) ? "insertMany" : "insertOne"](data);
//3:关闭数据库连接client.close();return result;
}//数据库之 改
// `db.集合的名称.updateOne( {name:"ppp",age:10 } , { $set : { name:"嘿嘿",age:20} } );`
//根据id来修改 数据库中的data
async function update(colName, query, newData) { //newData{$set:{price:200,qty:2},$inc:{view:1}}let {db,client} = await connect();let collection = db.collection(colName);//根据id删除 数据if (query._id && typeof query._id === 'string') {query._id = ObjectId(query._id);}let result = await collection.updateOne(query, newData);console.log("result" + result);return result;}//数据库之 删
// `db.集合的名称.deleteMany({name:"ppp"})`
async function remove(colName, query) {//1:链接数据库let {db,client} = await connect()//根据id删除 数据if (query._id && typeof query._id === 'string') {query._id = ObjectId(query._id);}//2:匹配集合let collection = db.collection(colName);//判断是删除一条还是多条let result = await collection.deleteMany(query);client.close();return result;}
// //查 函数
// 操作数据库的前提是:引入数据库,还有连接网址,连接数据库名称,数据库的链接
// 方法里面:数据库的链接(里面有着:链接数据库 匹配数据库集合,最后根据所选的集合 操作数据库) 最后关闭数据库!
async function find(colName, query = {}, options = {}) { //参数1:数据库中的集合(表) 参数2:操作的数据库语句 参数3:配置参数 //1:链接数据库let {db,client} = await connect();//2:匹配数据库集合 let collection = db.collection(colName);//3:最后根据所选的集合 操作数据库 查询操作let result = collection.find(query);//分页功能 需要的参数:页数 限制显示的多少页 跳过的数据条数 eg: 1页-0~5-0条 2页-5~10条-5条 3页-10~15-10条//01:查询跳过的记录if (options.skip) {result = result.skip(options.skip) //result.skip()方法 设置跳过记录 }//02:设置显示的条数if (options.limit) {result = result.limit(options.limit)}//排序的功能if (options.sort) { //前端传来的之 ["price"] 或者["price","1"] 第一种为默认的降序 第二种为升序let key, val;key = options.sort[0]; //拿到key值 if (options.sort.length > 1) {val = options.sort[1] * 1;} else {val = -1;}result = result.sort({ //对象[字符串] [key]: val})}result = await result.toArray(); //返回的是一个数组的形式!给与前端!//最后 客户端关闭数据库 client.close();return result; //返回查询结果 一个promise对象}//把增删改查 到出 在引入这个工具函数时候 调用!module.exports = {insert,find,update,remove}
调用接口:
const express = require("express");
const router = express.Router();const mongo = require("./mongo");
const { ObjectId } = require("mongodb");const colc_name = "goods"
//post 方式 增加数据
router.post("/insert", async (req, res) => {// `db.集合的名称.insertMany([{name:"名称",age:11},{name:"www",age:20}])`// insert() 参数1:数据库集合 参数2:插入的数据 插入一条数据的话 直接一个对象 插入多条数据的话 [{},{}] 对象里面书写插入的参数!// let result = await mongo.insert("goods2", {// "name": "ppp",// "purchase": "1件起购",// "oldprice": 12345.00,// });let result = await mongo.insert(colc_name, [{"name": "ppp","purchase": "1件起购","oldprice": 222,}, {"name": "lll","purchase": "1件起购","oldprice": 111,}]);res.send("插入成功"+result);
})
//查询
router.get("/search", async (req, res) => {//分页效果!//设置默认显示的条数还有第几页 并且获取到前端发来的请求参数!let {//page 第一页 size为显示条数大小为10 sort默认的排序(降) 根据nowPrice排序 注意点:nowPrice一定是数值型! 不带""page = 1, size = 10, sort = "oldprice"} = req.query;//设置skip跳过的记录 还有限制显示的那些数据条数let skip = (page - 1) * size;let limit = size * 1;//排序的参数处理sort = sort.split(","); //参数传递:price,1等等! ['price'],['price','-1']//find()参数:参数1:数据库中的集合(表) 参数2:操作的数据库语句 参数3:配置参数 let result = await mongo.find(colc_name, {}, {skip,limit,sort});res.send(result);
})
//删除数据
router.delete('/:id', async (req, res) => {// router.delete('/:name', async (req, res) => {const {id// name} = req.params;// console.log("name" + name);var objectId = new ObjectId(id)try {const result = await mongo.remove(colc_name, {_id: id})// const result = await mongo.remove('goods2', {// name: name// })res.send('success')return result;} catch (err) {res.send(err);}})
//修改数据router.put("/:id", async (req, res) => {let {id} = req.params;console.log("id" + id);// let whereDate = {// name: "ooo"// }let whereDate = {_id: id}let updataDate = {$set: {name: "zzz",oldPrice: 200,},$inc: {view: 1}}console.log(whereDate, updataDate); //oktry {let result = await mongo.updata(colc_name, whereDate, updataDate);res.send("success");} catch (err) {res.send("fail")}})
module.exports = router;
在定义了所有的接口以后统一导出,然后就能通过router中的url来访问了。
相关文章:

【后端开发实习】用MongoDB实现仓库管理的出库入库实战
用MongoDB实现仓库管理的出库入库 MongoDB什么是MongoDBMongoDB安装以及开始运行配置启动以及mongoshmongodb的基础使用命令启动和使用MongoDB服务数据库操作集合操作文档操作 项目部署在数据库中创建一张商品信息表提供信息表的增删改查操作接口 MongoDB 什么是MongoDB Mong…...

内网信息收集——用户凭据窃取
文章目录 一、获取域内单机密码和hash1.1 在线读取lsass进程内存1.2 离线读取lsass.exe进程内存1.3 在线读取本地SAM文件1.4 离线读取本地SAM文件 二、域hash获取三、windows凭据导出 一、获取域内单机密码和hash 在windows中,SAM文件是windows用户的账户数据库&am…...

组串式逆变器散热分析
1 引言 组串式逆变器散热方式主要有强制风冷和自然冷却两种,针对两种散热方式的实际效果,笔者抽取了不同厂家不同散热方式的两款组串式逆变器进行实验对比,发现在同样的环境温度下,强制风冷的逆变器内部环境温度及核心器件温升比…...

WEB07Vue+Ajax
1. Vue概述 Vue(读音 /vjuː/, 类似于 view),是一款用于构建用户界面的渐进式的JavaScript框架(官方网站:https://cn.vuejs.org)。 在上面的这句话中呢,出现了三个词,分别是&#x…...

uniapp打包成Android时,使用uni.chooseLocation在App端显示的地址列表是空白?一直转圈的解决办法
问题描述: uniapp打包后的测试版app在ios里可以显示高德地图的定位列表,但是安卓手机却不显示定位列表,一直在转圈圈,怎么回事?之前的功能在正式版都能用,真机运行也能用,为什么测试版的安卓手…...

删除矩阵中0所在行 matlab
%for验证 new[]; for i1:size(old,1)if old(i,4)~0 %assume 0所在列在第4列new(end1,:)old(i,:);end enda(a(:,2)0,:)[]参考: 两种方式...

JavaWeb---HTML
一 HTML入门 1.1 HTML&CSS&JavaScript的作用 HTML 主要用于网页主体结构的搭建 CSS 主要用于页面元素美化 JavaScript 主要用于页面元素的动态处理 1.2 什么是HTML HTML是Hyper Text Markup Language的缩写。意思是超文本标记语言。它的作用是搭建网页结构,…...

Apache Doris:下一代实时数据仓库
Apache Doris:下一代实时数据仓库 概念架构设计快速的原因——其性能的架构设计、特性和机制基于成本的优化器面向列的数据库的快速点查询数据摄取数据更新服务可用性和数据可靠性跨集群复制多租户管理便于使用半结构化数据分析据仓一体分层存储 词条诞生技术概述适…...

t-SNE降维可视化并生成excel文件使用其他画图软件美化
t-sne t-SNE(t-分布随机邻域嵌入,t-distributed Stochastic Neighbor Embedding)是由 Laurens van der Maaten 和 Geoffrey Hinton 于 2008 年提出的一种非线性降维技术。它特别适合用于高维数据的可视化。t-SNE 的主要目标是将高维数据映射…...

End-to-End Object Detection with Transformers【方法详细解读】
摘要 我们提出了一种新的方法,将目标检测视为一个直接的集合预测问题。我们的方法简化了检测流程,有效地消除了许多手工设计的组件,如非极大值抑制程序或锚生成,这些组件显式编码了我们关于任务的先验知识。新框架的主要成分,称为DEtection TRansformer或DETR,是一个基于…...

SQLite数据库与ROOM数据库
目录 1、SQLite数据库 目的: 基本操作: 缺点: 解决: 2、ROOM持久性库 目的: 优点: 导入依赖: 主要组件: 编辑 使用步骤: a.定义数据实体 b.定义数据访问对象(接…...

vue实现动态图片(gif)
目录 1. 背景 2. 分析 3. 代码实现 1. 背景 最近在项目中发现一个有意思的小需求,鼠标移入一个盒子里,然后盒子里的图就开始动起来,就像一个gif一样,然后鼠标移出,再按照原来的变化变回去,就像变形金刚…...

win11系统设置允许无密码远程桌面连接
在windows11系统中设置允许无密码远程桌面连接,可以通过以下步骤进行操作: 1、启用远程桌面功能:首先,确保您的Windows 11是专业版,因为家庭版默认不支持远程桌面功能。您可以通过“设置” -> “系统” -&…...

使用 PyAMF / Django 实现 Flex 类映射
1、问题背景 PyAMF 是一个用于在 Flex 和 Python 之间进行通信的库,在使用 PyAMF 与 Flex 应用进行通信时,经常会遇到错误。例如,在发送一个 Flex Investor 对象到 Python 时,会得到一个 ‘KeyError: first_name’ 的错误。这是因…...

算法思想总结:字符串
一、最长公共前缀 . - 力扣(LeetCode) 思路1:两两比较 时间复杂度mn 实现findcomon返回两两比较后的公共前缀 class Solution { public:string longestCommonPrefix(vector<string>& strs) {//两两比较 string retstrs[0];size…...

滑块拼图验证码识别
通常滑块验证码都是横向滑动,今天看到一个比较特别的滑块拼图验证码,他不仅能在横向上滑动,还需要进行纵向滑动。如下图所示: 他的滑块在背景图片的左上角,需要鼠标拖动左上角的滑块,移动到背景图的缺口位置…...

Activity启动流程
1 冷启动与热启动 应用启动分为冷启动和热启动。 冷启动:点击桌面图标,手机系统不存在该应用进程,这时系统会重新fork一个子进程来加载Application并启动Activity,这个启动方式就是冷启动。 热启动:应用的热启动比冷…...

PHP转Go系列 | ThinkPHP与Gin框架之OpenApi授权设计实践
大家好,我是码农先森。 我之前待过一个做 ToB 业务的公司,主要是研发以会员为中心的 SaaS 平台,其中涉及的子系统有会员系统、积分系统、营销系统等。在这个 SaaS 平台中有一个重要的角色「租户」,这个租户可以拥有一个或多个子系…...

使用SOAP与TrinityCore交互(待定)
原文:SOAP with TrinityCore | TrinityCore MMo Project Wiki 如何使用SOAP与TC交互 SOAP代表简单对象访问协议,是一种类似于REST的基于标准的web服务访问协议的旧形式。只要必要的配置到位,您就可以利用SOAP向TrinityCore服务器发送命令。 …...

QQ频道导航退出
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140413538 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...

MySQL里的累计求和
在MySQL中,你可以使用SUM()函数来进行累计求和。如果你想要对一个列进行累计求和,可以使用OVER()子句与ORDER BY子句结合,进行窗口函数的操作。 以下是一个简单的例子,假设我们有一个名为sales的表,它有两个列&#x…...

Python爬虫速成之路(3):下载图片
hello hello~ ,这里是绝命Coding——老白~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页:绝命Coding-CSDN博客 &a…...

同三维T80004EA编解码器视频使用操作说明书:高清HDMI编解码器,高清SDI编解码器,4K超清HDMI编解码器,双路4K超高清编解码器
同三维T80004EA编解码器视频使用操作说明书:高清HDMI编解码器,高清SDI编解码器,4K超清HDMI编解码器,双路4K超高清编解码器 同三维T80004EA编解码器视频使用操作说明书:高清HDMI编解码器,高清SDI编解码器&am…...

ChatGPT提问获取高质量答案的艺术PDF下载书籍推荐分享
ChatGPT高质量prompt技巧分享pdf, ChatGPT提问获取高质量答案的艺术pdf。本书是一本全面的指南,介绍了各种 Prompt 技术的理解和利用,用于从 ChatGPTmiki sharing中生成高质量的答案。我们将探讨如何使用不同的 Prompt 工程技术来实现不同的目…...

微信小程序中的数据通信
方法1: 使用回调函数 在app.js中:可以在修改globalData后执行一个回调函数,这个回调函数可以是页面传递给app的一个更新函数。// app.js App({globalData: {someData: ,},setSomeData(newData, callback) {this.globalData.someData = newData;if (typeof callback === funct…...

everything搜索不到任何文件-设置
版本: V1.4.1.1024 (x64) 问题:搜索不到任何文件 click:[工具]->[选项]->下图所示 将本地磁盘都选中包含...

python如何结束程序运行
方法1:采用sys.exit(0),正常终止程序,从图中可以看到,程序终止后shell运行不受影响。 方法2:采用os._exit(0)关闭整个shell,从图中看到,调用sys._exit(0)后整个shell都重启了(RESTAR…...

InnoDB
InnoDB 是 MySQL 默认的存储引擎,它提供了事务支持、行级锁定和外键约束等高级功能。下面详细解析 InnoDB 的一些底层原理和关键特性。 1. 数据存储结构 表空间(Tablespace) InnoDB 使用表空间来管理数据存储,表空间可以是共享…...

spark运行报错:Container killed by YARN for exceeding memory limits
用spark跑数据量大的离线调度任务报错:Reason: Container killed by YARN for exceeding memory limits. 19.0 GB of 19 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead or disabling yarn.nodemanager.vmem-check-enabled becaus…...

(三)大模型/人工智能/机器学习/深度学习/NLP
一.模型 模型,简单来说,就是用来表示或解释某个事物、现象或系统的一种工具或框架。它可以是实体的,也可以是虚拟的,目的是为了帮助我们更好地理解和预测所描述的对象。在生活中,模型无处不在,它们以各种形…...