SQLite快速上手

还记得之前我们学过的 NeDB 数据库吗?它是一款 Nodejs 编写的 NoSQL 嵌入式数据库。今天我们来认识另外一款嵌入式数据库,SQLite

NeDB 一样,SQLite 也具有零配置、无服务的特点,遵循 ACID 规则,是一款备受欢迎的轻量级数据库。

注解

ACID 规则即:A(原子性)、C(一致性)、I(独立性)、D(持久性)

安装sqlite3

使用 npm 安装 sqlite3,执行如下命令:

  1. $ npm i sqlite3 --save

连接数据库

引入依赖

  1. const sqlite3 = require('sqlite3').verbose()

引入 sqlite3 模块后,执行了 verbose 函数。verbose 函数用于将执行模式设置为输出调用堆栈,也就是说,如果代码出错,将会定位到具体的代码执行函数,而不仅仅只是提示错误信息,方便我们调试代码。

初始化数据库

  1. var db = new sqlite3.Database(
  2. './user.db',
  3. sqlite3.OPEN_READWRITE,
  4. function (err) {
  5. if (err) {
  6. return console.log(err.message)
  7. }
  8. console.log('connect database successfully')
  9. }
  10. )

1 行,使用 Database 函数,初始化数据库对象 db;第 2 行,配置数据存储的文件路径为 user.db ;第 3 行,指定数据库操作模式为读写模式。得到一个数据库对象 db 后,接下来我们进行建表操作。

run方法

sqlite3 模块提供了一个执行 sql 语句的方法 run。有了这个方法,我们可以很简单地执行对应的 sql 语句,实现除了查询操作之外的建表插入更新删除 操作。那 查询 用什么方法呢?别急,接下来会介绍到。

在操作数据库之前,有必要先介绍 run 方法如何使用。run 接收三个参数,分别是,sqlvaluecallback。语法糖如下:

  1. run(sql, value, callback)

其中,sql 表示需要执行的语句,value 表示 sql 语句中需要替换的值,callback 则是执行后的回调函数。具体的例子,可以接着看下面的介绍。

建表

我们建立一张表,命名为user:

  1. db.run('CREATE TABLE user(name text)', function (err) {
  2. if (err) {
  3. return console.log(err)
  4.  
  5. }
  6. console.log('create table user')
  7. })

建表没有存储数据的操作,因此不必传入 value

数据操作

插入

sqlite 表示插入的 sql 语句为: INSERT INTO table_name(column_name) VALUES(value) 。对应的,可以写出以下代码:

  1. db.run('INSERT INTO user(name) VALUES(?)', ['Alice'], function (err) {
  2. if (err) {
  3. return console.log('insert data error: ', err.message)
  4. }
  5. console.log('insert data: ', this)
  6. })

1 行,run 方法的第二参数 value,主要用于替换 sql 语句的 ? 符号;第 5 行,callback 中的 this 关键字,存储了插入数据的信息。结构为:Statement {sql: ‘sql语句’, lastID: id, changes: changesNum }

查询

查询数据,我们使用另一个方法:allall 方法表示查询所有数据,除此之外,sqlite3 还提供了其他查询方式

  1. db.all('SELECT name FROM user WHERE name = ?', ['Alice'], function (err, rows) {
  2. if (err) {
  3. return console.log('find Alice error: ', err.message)
  4. }
  5.  
  6. console.log('find Alice: ', rows)
  7. })

1 行,allrun 方法一样,接收三个参数:sqlvaluecallback,用法也同 run 方法一样,不再详述;第 6 行,callback 除了 err 参数,还有 rows 参数,表示插入后的数据。

更新

name 的值,由 Alice 改为 Alin

  1. db.run(
  2. 'UPDATE user SET name = ? WHERE name = ?',
  3. ['Alin', 'Alice'],
  4. function (err) {
  5. if (err) {
  6. return console.log('update data error: ', err.message)
  7. }
  8. console.log('update data: ', this)
  9. }
  10. )

2 行,更新的 sql 语句中,出现了两个 ? 符号,因此对应的,可以看到 value 数组也传入了两个数据。

验证下是否成功将 Alice 改为 Alin

  1. db.all('SELECT * FROM user', [], function (err, rows) {
  2. if (err) {
  3. return console.log('find error: ', err)
  4. }
  5. console.log('find updated data', rows)
  6. })

删除

name 值改为 Alin 后,删除 Alin 的数据:

  1. db.run('DELETE FROM user WHERE name = ?', ['Alin'], function (err) {
  2. if (err) {
  3. return console.log(err.message)
  4. }
  5. console.log('deleted Alin: ', this)
  6. })
  7. })

关闭数据库

在做完所有操作后,使用 close 方法关闭数据库:

  1. db.close(function (err) {
  2. if (err) {
  3. return console.log(err.message)
  4. }
  5. console.log('close database connection')
  6. })

运行demo

ok,至此我们知道了数据库从连接、建表、操作数据到关闭的过程,先来运行下 demo

  1. $ node demo.js

终端输出如下:

  1. connect database successfully
  2. find error: { [Error: SQLITE_ERROR: no such table: user] errno: 1, code: 'SQLITE_ERROR' }
  3. SQLITE_ERROR: no such table: user
  4. update data error: SQLITE_ERROR: no such table: user
  5. insert data error: SQLITE_ERROR: no such table: user
  6. create table user
  7. find Alice: undefined
  8. close database connection

咦?这结果不对,报错了。仔细看下结果,发现,插入、更新、建表等操作都乱了顺序执行。建表前进行查询、更新等操作,当然会报 no such table 错误。现在知道问题了,是因为操作没有顺序执行,怎么解决呢?sqlite3 提供了 serialize 方法,顾名思义,指定操作串行执行。使用如下:

  1. // 引入依赖
  2. const sqlite3 = require('sqlite3').verbose()
  3. // 初始化数据库
  4. var db = new sqlite.Database(...)
  5. db.serialize(function() {
  6. // 建表
  7. db.run('CREATE ...')
  8. // 插入数据
  9. db.run('INSERT ...')
  10. // 查询数据
  11. db.all('SELECT ...')
  12. // 更新数据
  13. db.run('UPDATE ...')
  14. // 删除数据
  15. db.run('DELETE ...')
  16. })
  17.  
  18. // 关闭数据库
  19. db.close(...)

以上有关数据库的操作均为伪代码,具体的可看上面几小节。

加上 serialize 方法后,我们再运行 demo,输出如下结果:

  1. connect database successfully
  2. create table user
  3. insert data: Statement {
  4. sql: 'INSERT INTO user(name) VALUES(?)',
  5. lastID: 1,
  6. changes: 1 }
  7. find Alice: [ { name: 'Alice' } ]
  8. update data: Statement {
  9. sql: 'UPDATE user SET name = ? WHERE name = ?',
  10. lastID: 1,
  11. changes: 1 }
  12. find updated data [ { name: 'Alin' } ]
  13. deleted Alin: Statement { sql: 'DELETE FROM user WHERE name = ?', lastID: 1, changes: 1 }
  14. close database connection

成功了!

下一步

订阅更新,获取更多学习资料,请关注我们的 微信公众号

../../_images/wechat-mp-qrcode.png 小菜学编程