前端实现数据持久化的几种方式

1,655 阅读3分钟

前端可以通过操作文件或者数据库实现数据持久化,下面简单介绍几种方式,抛砖引玉。如有错误和疑问,欢迎指正补充。

1. 数据持久化方式

数据持久化的几种方式:

  • 文件系统

  • 数据库

  1. 关系型数据库-mysql
  2. 键值对数据库-redis
  3. 文档型数据库-mongodb

2. 文件系统数据库

使用 fs 模块的 readFile() 和 writeFile() 方法实现文件异步的读和写,还有同步读写方法 readFileSync() 和 writeFileSync(),同步读写方法程序会等待IO操作,在等待时间内,无法响应其他任何事件,且无法定义回调函数。所以一般异步方法使用较多。

// test.js
const fs = require('fs');

function get(key){
    fs.readFile('./db.json', (err, data) => {
        const json = JSON.parse(data);
        console.log(json[key]);
    })
}

function set(key, value){
    fs.readFile('./db.json', (err, data = '{}') => {
        const json = JSON.parse(data);
        json[key] = value;
        // 写入文件
        fs.writeFile('./db.json', JSON.stringify(json), err => {
            if(err){
                console.log(err)
            }else{
                console.log('写入成功')
            }
        })
    })
}

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

rl.on('line', input => {
    const [op, key, value] = input.split(' ');
    if(op == 'get'){
        get(key);
    }else if(op == 'set'){
        set(key, value);
    }else if(op == 'quit'){
        rl.close();
    }
})

rl.on('close', () => {
    process.exit(0);
})

运行结果如下:

// 执行命令
node test.js
set test {name:11}
写入成功
get test
{name: 11}

3. 关系型数据库mysql

首先安装依赖包 mysql2:

yarn add mysql2

示例代码如下:

(async () => {
    const mysql = require('mysql2/promise');

    // 建立连接
    const connection = await mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: '123456',  //此处密码不能直接写成数字,需要写成字符串形式
        database: 'test'
    });

    // 执行sql语句-建表
    let result = await connection.execute('CREATE TABLE IF NOT EXISTS user (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(45) NULL,PRIMARY KEY (id))')
    console.log('建表成功', result);

    // 新增
    result = await connection.execute('INSERT INTO user(name) VALUES(?)', ['Lucy']);
    console.log('新增成功', result);

    // 删除
    result = await connection.execute('DELETE FROM user WHERE name=?', ['Lucy']);
    console.log('删除成功', result);
})()

SQL语句中需要使用查询参数占位符,这样可以有效防止sql注入,参考另一篇文档:juejin.cn/post/703192…

一般实际项目中会建立数据库连接池,通过复用之前的连接来减少连接数据库的次数,从而降低数据库的压力。

(async () => {
    const mysql = require('mysql2/promise');

    const pool  = mysql.createPool({
        host: 'localhost',
        user: 'root',
        password: '123456',
        database: 'test'
    });

    // 执行sql语句-建表
    let result = await pool.execute('CREATE TABLE IF NOT EXISTS user (id INT NOT NULL AUTO_INCREMENT,name VARCHAR(45) NULL,PRIMARY KEY (id))')
    console.log('建表成功', result);

    // 新增
    result = await pool.execute('INSERT INTO user(name) VALUES(?)', ['Lily']);
    console.log('新增成功', result);
})()

4. ORM-Sequelize

基于Promise的ORM(Object Relation Mapping),是一种数据库中间件,支持多种数据库,事务,关联等。无需写原生的SQL语句,用操作对象的方式即可操作数据库。但是对于复杂的数据联表查询,中间件的能力可能会有些限制。

首先安装依赖包Sequelize。

yarn add Sequelize

示例代码如下:

(async () => {
    const Sequelize = require('sequelize');

    // 参数分别为'database', 'username', 'password'
    const sequelize = new Sequelize('test', 'root', '123456', {   
        host: 'localhost',
        dialect: 'mysql' /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
    });
	
    // 定义模型
    const User = sequelize.define('User', {
        name: {
            type: Sequelize.STRING(20), 
            allowNull: false
        },
        role: {
            type: Sequelize.INTEGER,
            defaultValue: 0
        }
    })
	
    // 同步数据库
    let ret = await User.sync();
	
    // 数据增加
    ret = await User.create({
        name: '张三',
        role: 1
    })

    // 数据修改
    ret = await User.update({
        role: 2
    },{
        where: {
            name: '张三'
        }
    })
	
    // 数据查找
    const Op = Sequelize.Op;
    ret = await User.findAll({
        where: {
            role: { 
                [Op.eq]: 2
            }
        }
    })
    console.log(ret);

    //数据删除
    ret = await User.destroy({
        where: {
            role: { 
                [Op.eq]: 3
            }
        }
    })
})()

如果需要设置UUID-主键:

id: {
    type: Sequelize.DataTypes.UUID,
    defaultValue: Sequelize.DataTypes.UUIDV1,
    primaryKey: true
}

更多用法参考官网文档:

sequelize.org/master/inde…

www.npmjs.com/package/seq…

5. 总结

前端操作数据库时,可以通过编写sql语句,或是借助中间件的能力,用JS操作对象的方式来操作数据库。使用中间件时,需要熟悉其API调用。对于复杂的逻辑,建议还是直接编写SQL来完成。

以上来自网络课程学习资料总结。