node中的数据 持久化

ndoe中实现数据的持久化的多种方法

  • 文件系统 fs
  • 数据库
    1 关系型数据库 mysql
    2 文档型数据库 mongodb
    3 键值的对数据库 redis

文件系统数库

//fsdb.js
//实现一个文件系统读取数据库
const fs = require("fs")
function get(key){
	fs.readFile("./db.json", (err, data)=>{
		const json = JSON.parse(data)
		console.log(json[key])
	})
}

fonction set(key, value){
	//可能是空文件, 则设置为空对象
	const json = data ? JSOJN.parse(data):[]
	json[key] = value//设置值
	fs.writeFile('./db.json', JSON.stringify(json), err=>{
		if(err){console.log(err)}
		console.log('写入成功')
	})

}


//命令行接口部分
const readline = require('readline')
const rl = readline.createInterface({
	input: process.stdin,
	output: process.stdout
})

rl.on('line', function(input){
	const [op, key, value] = require.split(' ')
	if(op === 'get){
		get(key)
	}else if(op === 'set){
		set(key, value)
	}else if(op === 'quit'){
		rl.close()
	}else{
		console.log('没有该操作')
	}
})

rl.on('close', function(){

	console.log(''程序结束)
	process.exit(0)
})

node.js原生驱动

  • 安装mysql模块 npm i mysql --save
  • mysql模块的基本使用
//mysql.js
const mysql = require('mysql')
//链接配置
const cfg = {
	host: 'localhost',
	user: 'root',
	password: ' example',
	database: 'kkk',//确保数据库存在
}
//创建连接对象
const conn = mysql.createConnection(cfg)
//链接
conn.connect(err=>{
	if(err){
	throw err
	}else{
	console.log('connect success')
	}
})

//查询 conn.query()
//创建表
const CREATE_SQL = `
	CREATE TABLE IF NOT EXISTS TEST(
		id INT  NULL AUTO_INCREMENT,
		message VARCHAR(45) NULL,
		PRIMARY KEY (id)
	)`
const INSERT_SQL = `INSERT INTO test(message) VALUES(?)`
const SELECT_SQL = `SELECT * FROM test`
conn.query(CREATE_SQL, err=>{
	if(err){throw err}
	//
	conn.query(INSERT_SQL, 'hellow,world', (err, result)=>{
		if(err){throw err}
		console.log(result)
		conn.query(SELECT_SQL, (err, result)=>{
			console.log(result)
			conn.end()//若query语句有嵌套,则end需要在此执行
		})
	})
})
`

es2017 写法

// mysql2.js
(async () => {
// get the client
const mysql = require('mysql2/promise');
// 连接配置
const cfg = {
host: "localhost",
user: "root",
password: "example", // 修改为你的密码
database: "kaikeba" // 请确保数据库存在
 };
// create the connection
const connection = await mysql.createConnection(cfg);
// 查询 conn.query()
// 创建表
const CREATE_SQL = `CREATE TABLE IF NOT EXISTS test (
id INT NOT NULL AUTO_INCREMENT,
message VARCHAR(45) NULL,
PRIMARY KEY (id))`;
const INSERT_SQL = `INSERT INTO test(message) VALUES(?)`;
const SELECT_SQL = `SELECT * FROM test`;
// query database
let ret = await connection.execute(CREATE_SQL);
console.log('create:', ret)
ret = await connection.execute(INSERT_SQL, ['abc']);
console.log('insert:', ret)
const [rows, fields] = await connection.execute(SELECT_SQL);
console.log('select:', rows)
})()

node.js ORM – Sequelize

  • 概述 基于Promise的ORM,支持多种数据库,事物,关联等
  • 安装 npm i sequelize mysql2 -S
  • 基本使用
(async () => {
   const Sequelize = require("sequelize");
   // 建⽴连接
   const sequelize = new Sequelize("kaikeba", "root", "example", {
      host: "localhost",
      dialect: "mysql",
      operatorsAliases: false
   });
   // 定义模型
   const Fruit = sequelize.define("Fruit", {
      name: { type: Sequelize.STRING(20), allowNull: false },
      price: { type: Sequelize.FLOAT, allowNull: false },
      stock: { type: Sequelize.INTEGER, defaultValue: 0 }
   });
  let ret = await Fruit.sync()
  console.log('sync',ret)
  ret = await Fruit.create({
     name: "⾹蕉",
     price: 3.5
  })
  console.log('create',ret)
  ret = await Fruit.findAll()
  await Fruit.update(
   { price: 4 },
   { where: { name:'⾹蕉'} }
  )
  console.log('findAll',JSON.stringify(ret))
  const Op = Sequelize.Op;
  ret = await Fruit.findAll({
   // where: { price: { [Op.lt]:4 }, stock: { [Op.gte]: 100 } }
   where: { price: { [Op.lt]: 4, [Op.gt]: 2 } }
  })
  console.log('findAll', JSON.stringify(ret, '', '\t'))
})()
  • 强制同步:创建表之前先删除已存在的表
    Fruit.sync({ force: true })
  • 避免自动生成时间戳字段
const Fruit = sequelize.define("Fruit", {}, {
  timestamps: false
});
  • 指定表名freezeTableName: true 或 tableName:'xxx'
    设置前者则以modelName作为表名;设置后者则按其值作为表名。
    蛇形命名 underscored: true,
    默认驼峰命名

  • UUID 主键

id: {
 type: Sequelize.DataTypes.UUID,
 defaultValue: Sequelize.DataTypes.UUIDV1,
 primaryKey: true
 },
  • Getters & Setters:可⽤于定义伪属性或映射到数据库字段的保护属性
// 定义为属性的⼀部分
name: {
type: Sequelize.STRING,
allowNull: false,
get() {
const fname = this.getDataValue("name");
const price = this.getDataValue("price");
const stock = this.getDataValue("stock"); 
return `${fname}(价格:¥${price} 库存:${stock}kg)`;
 }
}
// 定义为模型选项
// options中 {
getterMethods:{
amount(){
return this.getDataValue("stock") + "kg";
 }
 },
setterMethods:{
amount(val){
const idx = val.indexOf('kg');
const v = val.slice(0, idx);
this.setDataValue('stock', v);
 }
 }
}
// 通过模型实例触发setterMethods
Fruit.findAll().then(fruits => {
console.log(JSON.stringify(fruits));
// 修改amount,触发setterMethods
fruits[0].amount = '150kg';
fruits[0].save();
});
  • 校验:可以通过校验功能验证模型字段格式、内容,校验会在 create 、 update 和 save 时⾃动运行
price: {
validate: {
isFloat: { msg: "价格字段请输⼊数字" },
min: { args: [0], msg: "价格字段必须⼤于0" }
 }
},
stock: {
validate: {
isNumeric: { msg: "库存字段请输⼊数字" }
 }
}
  • 模型扩展:可添加模型实例⽅法或类⽅法扩展模型
// 添加类级别⽅法
Fruit.classify = function(name) {
const tropicFruits = ['⾹蕉', '芒果', '椰⼦']; // 热带⽔果
return tropicFruits.includes(name) ? '热带⽔果':'其他⽔果';
};
// 添加实例级别⽅法
Fruit.prototype.totalPrice = function(count) {
return (this.price * count).toFixed(2);
};
// 使⽤类⽅法
['⾹蕉','草莓'].forEach(f => console.log(f+'是'+Fruit.classify(f)));
// 使⽤实例⽅法
Fruit.findAll().then(fruits => {
const [f1] = fruits;
console.log(`买5kg${f1.name}需要¥${f1.totalPrice(5)}`); 
});
  • 数据查询
// 通过id查询(不⽀持了)
Fruit.findById(1).then(fruit => {
// fruit是⼀个Fruit实例,若没有则为null
console.log(fruit.get());
});
// 通过属性查询
Fruit.findOne({ where: { name: "⾹蕉" } }).then(fruit => {
// fruit是⾸个匹配项,若没有则为null
console.log(fruit.get());
});
// 指定查询字段
Fruit.findOne({ attributes: ['name'] }).then(fruit => {
// fruit是⾸个匹配项,若没有则为null
console.log(fruit.get());
});
// 获取数据和总条数
Fruit.findAndCountAll().then(result => {
console.log(result.count);
console.log(result.rows.length);
});
// 查询操作符
const Op = Sequelize.Op;
Fruit.findAll({
// where: { price: { [Op.lt]:4 }, stock: { [Op.gte]: 100 } }
where: { price: { [Op.lt]:4,[Op.gt]:2 }}
}).then(fruits => {
console.log(fruits.length);
});
// 或语句
Fruit.findAll({
// where: { [Op.or]:[{price: { [Op.lt]:4 }}, {stock: { [Op.gte]: 100
}}] }
where: { price: { [Op.or]:[{[Op.gt]:3 }, {[Op.lt]:2 }]}}
}).then(fruits => {
console.log(fruits[0].get());
});
// 分⻚
Fruit.findAll({
offset: 0,
limit: 2,
})
// 排序
Fruit.findAll({
order: [['price', 'DESC']],
})
// 聚合
Fruit.max("price").then(max => {
console.log("max", max);
 });
Fruit.sum("price").then(sum => {
console.log("sum", sum);
 });
  • 更新
Fruit.findById(1).then(fruit => {
// ⽅式1
fruit.price = 4;
fruit.save().then(()=>console.log('update!!!!'));
});
// ⽅式2
Fruit.update({price:4}, {where:{id:1}}).then(r => {
console.log(r);
console.log('update!!!!')
})

删除

// ⽅式1
Fruit.findOne({ where: { id: 1 } }).then(r => r.destroy());
// ⽅式2
Fruit.destroy({ where: { id: 1 } }).then(r => console.log(r));

在这里插入图片描述

const log = (text, data) => {
console.log(`===========${text}========`)
console.log(JSON.stringify(data,null,"\t"))
console.log(`==========================`)
 }
const sequelize = require('./util/database')
// 定义模型 1:N 关系
const Product = require('./models/product');
const User = require('./models/user');
const Cart = require('./models/cart');
const CartItem = require('./models/cart-item');
Product.belongsTo(User, {
constraints: true,
onDelete: 'CASCADE'
 });
User.hasMany(Product)
await sequelize.sync({ force: true })
// 创建⽤户
let user = await User.fin
if (!user) {
user = await User.create({
name: 'kaikeba',
email: 'mail@kaikeba.com'
 })
 }
// 添加商品
let product = await user.createProduct({
title: '商品⼀',
price: 123,
imageUrl: 'abc.png',
description: '商品描述'
 })
log('product', product)
// N : N关系
User.hasOne(Cart)
Cart.belongsTo(User)
Cart.belongsToMany(Product, {
through: CartItem
});
Product.belongsToMany(Cart, {
through: CartItem
});
await sequelize.sync({ force: true })
// 创建⽤户
let user = await User.findByPk(1)
if (!user) {
user = await User.create({
name: 'kaikeba',
email: 'mail@kaikeba.com'
})
}
// 添加商品
let product = await user.createProduct({
title: '商品⼀',
price: 123,
imageUrl: 'abc.png',
description: '商品描述'
})
log('product', product)
// 添加购物⻋
await user.createCart()
ret = await User.findAll({ include: [Cart] })
log('getCart:', ret)
// 添加购物⻋商品
let cart = await user.getCart()
await cart.addProduct(product, {
through: {
quantity: 1 }
})
// 获取购物⻋商品数量
const productId = 1
const item = await cart.getProducts({
where: {
id: productId
}
})
log('item', item)
// 商品是否存在
if(item.length > 0){
console.log('商品存在....................')
await cart.addProduct(product, {
through: {
quantity: item[0].cartItem.quantity + 1 }
})
}else{
await cart.addProduct(product, {
through: {
quantity: 1 }
})
}
log('cart', cart)

Restful服务
实践指南 http://www.ruanyifeng.com/blog/2014/05/restful_api.html
原理 http://www.ruanyifeng.com/blog/2011/09/restful.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node-RED是一个开源的可视化编程工具,用于构建物联网应用和流程。它提供了丰富的节点来处理、转换和可视化数据。 在Node-RED,可以使用“uitable”节点来创建和管理一个持久化数据表格。uitable节点基于本地文件系统,将数据保存在磁盘上,以便在以后的运行可以重用。 要使用uitable节点进行持久化,需要先安装uitable依赖。可以通过Node-RED的命令行界面(CLI)或通过编辑settings.js文件来安装依赖。安装完成后,可以在Flows的节点面板找到uitable节点。 将uitable节点拖放到工作区,并与其他节点连接。然后,可以配置uitable节点的属性,包括数据存储位置、表格名称和列名。可以将输入的数据连接到uitable节点,以将数据存储到表格。 当启动或重新加载Flow时,uitable节点会自动加载之前保存的数据,并将其添加到表格。这样,即使重新启动Node-RED,也能够保留之前保存的数据。 在Flow可以使用uitable节点的输出来读取和处理已保存的数据。可以使用其他节点,如ui_table、debug等节点来实时显示和分析表格数据。 需要注意的是,uitable节点会将数据以JSON格式进行存储,因此可以灵活地对表格进行处理和修改。 总结起来,Node-RED的uitable节点提供了一种简单可视化的方式来持久化数据表格。通过配置uitable节点的属性和连接输入输出节点,可以方便地存储和读取数据,并在应用程序进行处理和可视化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值