Koa框架数据存储

mysql

  • 下载mysqlnpm i mysql --save

  • 修改config/config.js文件

const DB = { host: '127.0.0.1', user: 'root', password: 'root', database: 'blog', port: 3306 } module.exports = { DB }

直连

  • 修改utils/mysql.js文件
const mysql = require('mysql') const { DB } = require('../config/config') function query(sql) { return new Promise((resolve, reject) => { const connection = mysql.createConnection(DB) connection.connect() // 执行sql脚本对数据库进行读写 connection.query(sql, (error, results, fields) => { if (error) reject(error) // 结束会话 connection.end() resolve(results) }) }) } module.exports = { query }
  • 在代码中使用
const mysql = require('../utils/mysql') async function test(ctx) { const res = await mysql.query('select * from wmm_article') return res }

使用连接池

  • 修改utils/mysql.js文件
const mysql = require('mysql') const { DB } = require('../config/config') const pool = mysql.createPool(DB) const query = function(sql, values){ return new Promise((resolve, reject) => { pool.getConnection(function(err, connection){ if(err) { reject(err) } else { connection.query(sql, values, (err, rows) => { if(err){ reject(err) }else{ resolve(rows) } connection.release() }) } }) }) } module.exports = { query }
  • 在代码中使用
const { query } = require('../utils/mysql') async function selectAllData() { const sql = 'select * from user' const dataList = await query(sql) return dataList } async function getData() { const dataList = await selectAllData() console.log(dataList) }

escape

上面的两种方式都会输出一个escape,它是用来防止SQL注入的。

最常见的例子是在登录页面

使用代码如下

const { query } = require('../utils/mysql') const login = async (username, password) => { // 格式化 预防sql注入 username = escape(username) // 生成加密密码 password = genPassword(password) // 格式化 预防sql注入 password = escape(password) const sql = `select id, username, realname from users where username=${username} and password=${password}` const rows = await query(sql) return rows[0] || '' }

sequelize

  • 下载mysql2 sequelizenpm i mysql2 sequelize --save

  • 在根目录下新建schema/目录。这个目录存放数据库各个表的配置

  • 在根目录下执行命令sequelize-auto -o "./schema" -d blog -h localhost -u root -p 3306 -x root -t user -e mysql直接导入数据表配置

备注

  • -o:目标地址,导出到哪个目录下

  • -d:数据库名称

  • -h:数据库地址

  • -u:数据库账号

  • -p:数据库端口

  • -x:数据库密码

  • -t:导出的表,若全部导出,可以忽略此项

  • -e:类型 MySQL

  • 如果提示没有命令sequelize-auto,执行以下命令全局安装

  • npm i mysql sequelize-auto -g

  • 命令执行完后,在schema/目录下会出现各数据表的配置文件

  • utils/目录下新建文件sequelize.js

const { Sequelize, DataTypes } = require('sequelize') const db = require('../config/config').DB const sequelize = new Sequelize(db.database, db.user, db.password, { host: db.host, port: db.port, dialect : 'mysql', // replication: { // read: [ // { host: '8.8.8.8', username: 'anotherusernamethanroot', password: 'lolcats!' }, // { host: 'localhost', username: 'root', password: null } // ], // write: { host: 'localhost', username: 'root', password: null } // }, // pool: { // 如果要覆盖用于读取池的选项,可以在此处进行 // max: 20, // idle: 30000 // }, define: { // 取消Sequelzie自动给数据表添加的 createdAt 和 updatedAt 两个时间戳字段 timestamps: false } }) const schema = str => { const table = `../schema/${db.prefix}${str}` // 这是v4的用法 // return sequelize.import(table) const tableSchema = require(table) return tableSchema(sequelize, DataTypes) } module.exports = { schema }
  • 在代码中使用
const articleSchema = require('../utils/sequelize').schema('article') async function test(ctx) { const list = await articleSchema.findAndCountAll({ limit: 10, // 每页多少条 offset: 0, // 跳过多少条 attributes : ['id', 'user_id', 'title', 'content'], where: { status : 1 } }) return list }

Redis

redis是一个key-value存储系统,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash

性能方面,redis是一个高性能的key-value数据库。

  • 下载redisnpm i redis --save

  • 简单使用

const redis = require('redis') const client = redis.createClient(6379, '127.0.0.1') client.on('error', err => { console.log(err) }) client.set('name', 'asen', redis.print) client.get('name', (err, value) => { if (err) throw err console.log(value) })

session + redis

Session 中的数据一般都是短时间内高频访问的,需要保证性能,所以比 较好的方式是内存配合 Redis 做一个持久化。
这是因为内存访问的性能虽然是最好的,但是容易丢失数据,如遇到重启服务器等情况。 因此,可以在 Redis 中做一个备份,当内存中的 数据丢失时,就可以从 Redis 中恢复数据

  • 未使用redis的代码
const session = require('koa-session') app.keys = ['xxxxxxxxxx'] const CONFIG = { key: 'myAppSessKey', maxAge: 1000*60*60*24, overwrite: true, httpOnly: true, signed: true } app.use(session(CONFIG, app)) app.use(async ctx => { if (ctx.path === '/favicon.icon') return; let n = ctx.session.views || 0 ctx.session.views = ++n ctx.body = `${n} views` })
  • 使用redis做了优化之后的代码
const session = require('koa-session') const redis = require('redis') const client = redis.createClient(6379, '127.0.0.1') const { promisify } = require('util') const hgetAllAsync = promisify(client.hgetAll).bind(client) app.keys = ['xxxxxxxxxx'] const store = { get: async (key, maxAge) => { return await hgetAllAsync(key) }, set: (key, sess, maxAge) => { client.hmset(key, sess) }, destroy: (key) => { client.hdel(key) } } const CONFIG = { key: 'myAppSessKey', maxAge: 1000*60*60*24, overwrite: true, httpOnly: true, signed: true, store } app.use(session(CONFIG, app)) app.use(async ctx => { if (ctx.path === '/favicon.icon') return; let n = ctx.session.views || 0 ctx.session.views = ++n ctx.body = `${n} views` })

MongoDb

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

他支持的数据结构非常松散,是类似jsonbson格式,因此可以存储比较复杂的数据类型。

Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
它的特点是高性能、易部署、易使用,存储数据非常方便。

非结构型数据库。没有行、列的概念。用JSON来存储数据。
集合就相当于“表”,文档就相当于“行”。

  • 下载mongodbnpm i mongodb --save

  • 修改config/db.js文件,添加mongodb配置

const mongodb = { dbUrl: 'mongodb://localhost:27017/', dbName: 'koa' } module.exports = { mongodb }
  • utils/目录下新建mongodb.js文件
const MongoDB = require('mongodb') const { MongoClient, ObjectID } = MongoDB const mongodbConfig = require('../config/db').mongodb class Mongo { // 单例 多次实例化实例不共享的问题 static getInstance() { if (!Mongo.instance) { Mongo.instance = new Mongo() } return Mongo.instance } constructor(){ // 属性 放db对象 this.dbClient = '' // 实例化的时候就连接数据库 this.connect() } // 连接数据库 connect(){ return new Promise((resolve, reject) => { // 实例化的时候就连接数据库 if (!this.dbClient) { MongoClient.connect(mongodbConfig.dbUrl, { useNewUrlParser: true }, (err, client) => { if (err) { reject(err) } else { this.dbClient = client.db(mongodbConfig.dbName) resolve(this.dbClient) } }) } else { resolve(this.dbClient) } }) } find(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then(db => { const result = db.collection(collectionName).find(json) result.toArray((err, docs) => { err ? reject(err) : resolve(docs) db.close() }) }) }) } findOne(collectionName, json) { return new Promise((resolve,reject) => { this.connect().then(db => { const result = db.collection(collectionName).find(json).limit(1) result.toArray((err, docs) => { err ? reject(err) : resolve(docs) db.close() }) }) }) } update(collectionName, jsonOld, jsonNew) { return new Promise((resolve, reject)=>{ this.connect().then(db => { // db.user.update({}, { $set:{} }) db.collection(collectionName).updateOne(jsonOld, { $set: jsonNew }, (err, result) => { err ? reject(err) : resolve(result) db.close() }) }) }) } insert(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then(db => { db.collection(collectionName).insertOne(json, (err, result) => { err ? reject(err) : resolve(result) db.close() }) }) }) } remove(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then(db => { db.collection(collectionName).remove(json, (err, result) => { err ? reject(err) : resolve(result) db.close() }) }) }) } removeOne(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then(db => { db.collection(collectionName).removeOne(json, (err, result) => { err ? reject(err) : resolve(result) db.close() }) }) }) } // mongodb里面查询 _id 把字符串转换成对象 getObjectId(id) { return new ObjectID(id) } } module.exports = Mongo.getInstance()
  • 在文件中使用
const mongo = require('../utils/mongodb') async function test(ctx) { const res = await mongo.find('documents', { 'a': 3 }) return res }

创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: