使用 node-json-db 为node项目添加一个简易的本地数据库

8 篇文章 0 订阅

使用 node-json-db 为 node 项目添加一个简易的本地数据库

数据库大家都不陌生,对于前端来说也不算太熟悉。 很多时候可能会和我一样为了信息抓取会用 node 做一些小爬虫(当然别乱用:爬虫写得好,牢饭吃到饱)

可是 node 的容错性属实有点低,比如

  • 一共抓取 20 页的数据,抓到第 5 页,发现 dom 结构不同了,JS 报错了,进程结束
  • 抓取第六页的时候,被发现了,爬虫返回了 500, ajax 报错 进程又结束了
  • 抓取 20 页数据,抓到一半断网了。这时候数据没保存,又得从头抓起

针对以上的问题,其实无非就是因为我们抓取的每一页数据并没有实时的存储下来,导致遇到错误都得从头开始。那么 node-json-db 就极大方便了我们对数据的操作

搭建 node-json-db 的测试环境

终端执行

npm init -y
npm i koa koa-router nodemon node-json-db

新建几个目录:/src/index,/db

添加一个启动命令 package.json

"dev": "nodemon src/index.js",
  • /src/index.js
const { JsonDB } = require('node-json-db')
const { Config } = require('node-json-db/dist/lib/JsonDBConfig')

const Koa = require('Koa')
const Router = require('koa-router')

const path = require('path')
const fs = require('fs')

const app = new Koa()
var db = new JsonDB(new Config(path.join(__dirname, '../db/myDataBase.json'), true, true, '/'))
const router = new Router()

router.get('/add', function(ctx) {
  // ... 预留位置写db操作语句

  ctx.body = {
    code: 0,
    data: db.getData('/'), // 每次访问接口直接打印db所有的数据
    msg: ''
  }
})

app.use(router.routes())

app.listen(8000, function() {
  console.log('app run at http://localhost:8000/')
})

运行后,访问 localhost:8000/ 看到如下

qbupg1.png

基础 API

看文档也有具体的说明,我只是把几个常用的 API 列举一下

引入 node-json-db

const { JsonDB } = require('node-json-db')
const { Config } = require('node-json-db/dist/lib/JsonDBConfig')

初始化

const db = new JsonDB(new Config(path.join(__dirname, '../db/myDataBase.json'), true, false, '/'))

几个参数的含义:

export declare class Config implements JsonDBConfig {
    filename: string;
    humanReadable: boolean;
    saveOnPush: boolean;
    separator: string;
    syncOnSave: boolean;
    constructor(filename: string, saveOnPush?: boolean, humanReadable?: boolean, separator?: string, syncOnSave?: boolean);
}
  1. filename: 就是数据库保存的位置和名称
  2. saveOnPush: 是否每当调用 push 方法的时候都存到本地 json 中,如果使用 false 则需要自己调用 save 方法进行保存
  3. humanReadable: 可读性。存入本地 JSON 的时候,默认会进行数据压缩,如果该配置为 true ,则会相当于编辑器格式化 JSON 一样有缩进有换行
  4. separator: 分隔符 默认是 /
  5. syncOnSave: 使用同步写入(毕竟 nodejs 写入文件是支持异步写入的)

上面说到的 separator 分隔符,可以这么理解

const user = { name: 'Jioho', age: 18 }

// 正常我们获取 user 下的 name 属性写法如下
console.log(user.name)
// 修改:
user.name = 'jio'

分隔符就好像上面代码中的 . ,所以在 node-json-db 中,假如你想修改 user.name ,那么就调用相应的 api,其中键值为 user/name

展示不能理解后面有完整的示例

增删改查

增 db.push()

调用 db.push 方法进行 操作(如果saveOnPush 为 false,则还需要调用 db.save() 才能保存数据到本地)

但是和我们认识的增有一定的区别

举个例子:

// ... 省略引入和初始化db步骤

// 该部分代码写入刚才预留db操作的位置
// 连续调用 3 次 push
db.push('/user', { name: 'Jioho', age: 18 })
db.push('/user', { name: 'Jioho2', age: 19 })
db.push('/user', { name: 'Jioho3', age: 20 })

调用 /add 接口,最后的返回值只有一条数据:

{
  "code": 0,
  "data": {
    "user": {
      "name": "Jioho3",
      "age": 20
    }
  },
  "msg": ""
}

因为 /user 是一个对象,并不是一个数组,如果想要递增的效果,改为如下代码,明确 user 对象是一个数组类型

PS: 直接修改代码后运行会报错,因为在本地的数据中 user 已经存储了一个对象类型,所以需要手动把本地的 JSON 文件清空掉在运行代码

所以定义数据结构必须一开始想好,否则后面想改就比较麻烦了

db.push('/user[]', { name: 'Jioho', age: 18 })
db.push('/user[]', { name: 'Jioho2', age: 19 })
db.push('/user[]', { name: 'Jioho3', age: 20 })

查询的 API 目前有如下几个方法:

db.getData(dataPath)
传入需要查询的数据路径,返回值为 any
毕竟这只是 JSON 操作,所以并不能像 SQL 一样比如指定查询出 user 数组下的所有 name,需要自行写逻辑(查询出所有的 user 数据,然后筛选 name 属性出来)

// 当前JSON 中所有的数据
db.getData('/')
// 查询所有的 user 数据
db.getData('/user')

// 查询第一条
db.getData('/user[0]')

db.getObject(dataPath)
该方法和 db.getData() 一样,只是可以指定返回值类型,如果是在 TS 环境中

interface User {
  name: String
  age: Number
}

const userList: User[] = db.getObject<User[]>('/user[0]')
const user: User = db.getObject<User>('/user[0]')

db.exists
判断路径下的数据是否存在,这个还是比较实用的,防止数据未定义情况下就去调用

if (db.exists('/user')) {
  return db.getData('/user')
} else {
  return []
}

db.count
返回当前数据类型的条数

db.count('/user')

db.getIndex(dataPath: string, searchValue: (string | number), propertyName?: string): number
找到所匹配的的一条查询的值需要是字符串或者数字类型,不能为数组类型


返回值为查询到的第一个索引,即便有多条匹配的数据,返回值也是第一个匹配的索引,如果没找到则返回 1

// 查询所有等于19岁的用户
db.getIndex('/user', 19, 'age')

db.getIndexValue

同 getIndex 一样,getIndex 返回的是索引,getValue 返回的则是对应的数据


db.filter(rootPath: string, callback: FindCallback): T[] | undefined;
和 JS 的 filter 一样,传入需要查询的对象的路径,然后传入筛选的方法,返回值为一个数组(支持泛型操作)

// 查询所有等于19岁的用户
db.filter('/user', function(value, index) {
  if (value.age >= 19) {
    return true
  }
  return false
})

db.find

用法和 filter 一样,返回值为第一条匹配的数据(也是支持泛型)

修改数据其实还是用到 db.push 方法

还记得一开始说的 方法中如果 push 的对象不是数组则是替换原理吗?所以改也是用到 push,其实 push 还有第三个参数就是 是否覆盖源对象 默认是 true

db.push('/vipuser', { name: 'Jio', age: 18 })

// 这时候的对象是 user: { name: 'Jio', age: 18 }

// 修改年龄为19
db.push('/vipuser', { name: 'Jio', age: 19 })
// user: { name: 'Jio', age: 20 }

// 修改年龄为20
db.push('/vipuser', { age: 20 })
// ! 注意这里的 name 属性被覆盖了
// user: { age: 20 }

// 这里用上了第三个参数,标记为false,而且没有写入 age 属性
db.push('/vipuser', { name: 'Jioho', job: '前端' }, false)
// user: { name:'Jioho' age: 20, job: '前端' }

以上就是覆盖和不覆盖的区别

假设需要修改数组中指定某一项的值,只需要指定好路径,进行修改即可

db.push('/user[0]', { age: 20 }, false)

// 等价于
db.push('/user[0]/age', 20)

// 如果不指定索引,这时候修改的的则是 user 数组中的最后一项的 age 属性
db.push('/user[]/age', 22)

db.delete(path),传入要删除的路径即可

更新

db.reload()
因为还有 db.save 方法的存在,个人猜测所有的的数据在初始化后都读到了内存中,这样可以减少每次查数据的时候还要读一次文件的操作。

然而既然是文件,可能不止 node-json-db 可以操作这份 JSON 文件,node 自身也可以写入文件,所以当自己操作 node api 写入文件后,可以通过 db.reload() 进行把最新的数据重新读到内存中


db.resetData(data)
重置当前的数据为data,这将会重置所有的数据

最后

node-json-db 的出现让一些 node 小工具有更好的拓展性,称之为“数据库”可能会有点夸张,毕竟数据库最基础的 where 方法之类的并没有实现,只有简单的 JS 的 filter,find 作为支撑

不过对于一些小应用,用这套 JSON 操作的方法来存储一些配置(比如很多脚手架新建项目后都会询问是否保存配置下次使用)。这个库就能很好的胜任了,包括各种查询的方便的操作

最后有一个小提示,就是指定索引 push 或者删除等操作之前,记得先判断 exists~

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jsonDBjsonDB一个基于JSON格式的内存数据库.它具有以下特点:轻量级. 无守护进程,无需任何额外的安装和配置,你只需要import jsonDb即可使用,非常方便.NOSQL. 类似于mongoDb的非关系型数据库.内存数据库. 所有数据基于内存进行操作和访问,性能相对较高.目前版本的性能测试数据请 参考reference文档.任意迁移. 数据库可以完整导出为外部文件,并且可以从外部文件导入.基于此,数据库可以 进行任意的迁移,而无需做任何修改.灵活的数据类型. 一个数据集合(collection)中的数据,并不需要相同的格式.比如以下几种数据 可以同时存在于一个collection中: {'key1':1},{'key2':'value','pic':'value'},{'key3':'value'}JsonDB使用Python语言实现,是一个github开源项目,遵循MIT的LICENCE,基本上可以不受限制用于任何用途。该DB的接口大体模仿了mongoDB的风格,使用起来非常简单和顺手。概念说明:db: 即数据库. 创建一个jsonDb类的实例,即是创建了一个数据库.可以指定dbname和hash的长度.collection: 数据集合(表). 一个collection可以理解为数据库中的一个表. collection不需要 单独创建,当insert第一条数据,或者ensureKey时,系统会自动创建.data: 数据. collection中的一条数据,或者是一个数据的list. data必须是dict字典类型,是一个 key-value键值对.安装从源码安装,首先从github下载源码,jsonDb源码下载地址python setup.py install功能说明:创建数据库实例化一个JSONDB类实例,即创建一个数据库.我们重载了__str__方法,所以可以通过print直接查看数据库的统计信息.>>> from jsonDb.database import JSONDB >>> myDb = JSONDB('USER_DB') >>> print myDb ------ jdb statics ------ db_name: USER_DB mem_collection: 0 bytes mem_hash: 0 bytes collection_num: 0 **** collection statics ****更多详细使用说明请参考中文说明文档。 标签:jsonDB
### 回答1: 好的,我可以为你提供一个使用Node.js连接数据库并编写登录接口的示例。在这个示例中,我将使用MySQL作为数据库,并使用Express作为Node.js的Web框架。 首先,我们需要安装必要的依赖。在终端中运行以下命令: ``` npm install express mysql body-parser ``` 接下来,我们将创建一个名为`app.js`的文件,并将以下代码添加到文件中: ```javascript const express = require('express'); const mysql = require('mysql'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); const connection = mysql.createConnection({ host: 'localhost', user: 'your_mysql_username', password: 'your_mysql_password', database: 'your_database_name' }); connection.connect((err) => { if (err) throw err; console.log('Connected to database!'); }); app.post('/login', (req, res) => { const { username, password } = req.body; const sql = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; connection.query(sql, (err, result) => { if (err) throw err; if (result.length > 0) { res.send('Login success!'); } else { res.send('Invalid username or password'); } }); }); const port = 3000; app.listen(port, () => console.log(`Server running on port ${port}`)); ``` 在上面的代码中,我们首先引入了Express、MySQL和Body-parser模块。然后,我们创建一个名为`app`的Express实例,并配置Body-parser中间件,以便我们能够解析请求正文中的数据。 接下来,我们使用MySQL模块创建了一个名为`connection`的数据库连接。请确保将`your_mysql_username`、`your_mysql_password`和`your_database_name`替换为实际的值。 在登录接口的路由处理程序中,我们从请求正文中获取用户名和密码,并使用MySQL模块执行SQL查询。如果查询返回结果,则表示用户名和密码是有效的,否则表示它们是无效的。 最后,我们将服务器监听在端口3000上,并在控制台输出一条消息,以指示服务器已启动。 请注意,上面的代码仅用于示例目的,并不考虑安全性和其他最佳实践。在实际应用程序中,您应该实施更严格的安全性措施,例如对密码进行哈希处理,使用预备语句而不是直接将参数插入SQL查询中等。 ### 回答2: 使用Node.js连接数据库并编写一个登录接口,可以按照以下步骤进行操作: 1. 首先,确保已经安装了Node.js和适用于所选数据库的相关驱动程序。常见的数据库驱动程序有mysql、mongodb等。可以通过npm命令行安装这些驱动程序。 2. 在Node.js应用程序的文件中,引入所需的Node模块和数据库驱动程序。 3. 创建一个服务器以监听请求,并创建一个路由来处理登录功能的请求。例如,可以使用Express模块创建服务器和路由。 4. 在处理登录请求的路由函数中,获取来自请求的用户名和密码。 5. 连接到数据库使用数据库驱动程序的函数或方法来验证用户提供的用户名和密码是否与数据库中存储的一致。如果一致,返回登录成功的响应,否则返回登录失败的响应。 6. 关闭数据库连接。 下面是一个例子,假设使用MySQL作为数据库驱动程序,使用Express创建服务器和路由。 ```javascript const express = require('express'); const mysql = require('mysql'); const app = express(); const port = 3000; const db = mysql.createConnection({ host: 'localhost', user: 'your_username', password: 'your_password', database: 'your_database' }); app.get('/login', (req, res) => { const username = req.query.username; const password = req.query.password; db.query( 'SELECT * FROM users WHERE username = ? AND password = ?', [username, password], (error, results) => { if (error) throw error; if (results.length > 0) { res.send('Login successful'); } else { res.send('Login failed'); } } ); }); db.connect((error) => { if (error) throw error; console.log('Connected to the database'); app.listen(port, () => { console.log(`Server is running on port ${port}`); }); }); ``` 请注意,上述代码仅供参考,实际应用中需要根据具体情况进行修改和完善,例如增加错误处理和安全性措施。 ### 回答3: 使用Node.js连接数据库并编写一个登录接口的步骤如下: 首先,需要确定要连接的数据库类型,例如MySQL、MongoDB等,并安装相应的数据库驱动程序。 接下来,在Node.js项目的入口文件中引入所需的模块和库,例如`express`用于创建服务器,`mysql`或`mongoose`用于连接和操作数据库。 在代码中创建一个名为`login`的路由,监听前端发送的登录请求。可以使用`POST`方法获取请求中的用户名和密码。 通过数据库驱动程序提供的连接方法,连接到数据库。例如,使用MySQL时,可以使用`mysql.createConnection`方法来创建连接。 在接收到登录请求后,构建相应的SQL查询语句,查询数据库中是否存在该用户并验证其密码是否匹配。 如果查询结果中存在该用户且密码正确,返回登录成功的信息给前端;否则,返回登录失败的信息。 最后,在登录接口中导出路由,并在服务器配置中添加该路由,启动服务器。 整个过程类似如下所示(以使用MySQL为例): ```javascript const express = require('express'); const mysql = require('mysql'); const app = express(); const port = 3000; app.use(express.json()); app.use(express.urlencoded({ extended: false })); const db = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydb' }); db.connect((err) => { if (err) throw err; console.log('Connected to database'); }); app.post('/login', (req, res) => { const { username, password } = req.body; const sql = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; db.query(sql, (err, result) => { if (err) throw err; if (result.length > 0) { res.status(200).send('Login successful'); } else { res.status(401).send('Invalid username or password'); } }); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); }); ``` 以上是一个简单的基于Node.js的登录接口,可以连接到MySQL数据库,并根据请求中的用户名和密码验证登录。具体逻辑和细节可以根据需求进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值