天天看点

使用JavaScript访问mysql数据库的单实例封装

作者:程序老胡的日常
  • JavaScript的灵魂是灵活,骨子里面就是简单,优雅,灵活。访问数据库也是如此。
  • 尝试做了一个简单的mysql访问封装工具类,封装需求如下:1, 这个工具类需要是单实例,避免数据库链接浪费。2,提供连接池功能。3,启动后检测链接是否有效。4,提供简单查询和执行的方法,支持异步和同步(返回对象是Promise)。
使用JavaScript访问mysql数据库的单实例封装

想的越少,做的越快

  • JavaScript方法封装应该都使用Promise返回,首先是封装了catch异常,更重要的是这样可以任由使用者来决定是同步调用还是异步调用,等于一份代码支持两种场景。
  • 如果有更好的建议,请及时提出指正一起进步哈
// 使用mysql2的  promise包,能更好的适应 同步和异步处理
const mysql = require('mysql2/promise');
// 读取mysql配置,可以先忽略,自行定义即可
var dbbooks = require('../config').db.books

class Db{
    static getInstance(){ //1、单例 多次实例化实例不共享的问题
        if(!Db.instance){
            Db.instance = new Db()
            Db.instance.connect()     /*实例化的时候就连接数据库*/
        }
        return Db.instance;
    }
    constructor(){
        //创建pool, 这个时候不会链接数据库,有需要的时候才链接
        this.pool = mysql.createPool({
            host: dbbooks.host,
            user: dbbooks.username,
            port: dbbooks.port,
            password: dbbooks.password,
            database: dbbooks.database,
            waitForConnections: true,
            connectionLimit: 10,
            queueLimit: 0
          })
    }
    /**
     * 链接数据库
     */
    connect(){
        //测试是否通畅
        this.query('select 1').then(()=>{
            console.log('mysql connected', dbbooks)
        }).catch(()=>{
            console.log('mysql connect fail', dbbooks)
        })
    }

    //  每一个对外公开的方法,都应该尽可能写成Promise,
    //   这样由使用者来决定是同步调用还是异步调用,
    //   而且promise自带对异常的处理,代码更安全。
    
    /**
     * 查询
     * @param {string} sql 
     * @param {Array} param 
     * @returns 
     */
    async query(sql, param){
        return new Promise((resolve, reject) => {
            this.pool.query(sql, param).then((results)=>{
                resolve(results[0])
            }).catch((err)=>{
                reject(err);
            })
        });
    }

    /**
     * 查询只返回一个对象,如果查询不到,返回 {}
     * @param {string} sql 
     * @param {Array} param 
     * @returns 
     */
    async queryOne(sql, param){
        return new Promise((resolve, reject) => {
            this.pool.query(sql, param).then((results)=>{
                // console.log('resutls', results)
                if(results[0].length>=1){
                    resolve(results[0][0])
                }else{
                    resolve({})
                }
            }).catch((err)=>{
                reject(err);
            })
        });
    }
  
    /**
     * 执行新增,修改,删除的sql。也可以执行查询sql
     * @param {string} sql 
     * @param {array} param 
     * @returns 
     */
    async execute(sql, param){
        return new Promise((resolve, reject) => {
            this.pool.execute(sql, param).then((results)=>{
                // console.log(results, '---', fields)
                resolve(results[0]) 
            }).catch((err)=>{
                reject(err);
            })
        });
    }

}
// 这里, Db.getInstance() 每次返回的是同一个对象,以此实现单例调用
module.exports = Db.getInstance()           
  • 测试代码
var db = require('../db/mysql')
// 同步调用
const testbook = async ()=>{
  return await db.query('select * from books  where status=0  order by views desc');
}

//或者是 异步调用
db.query('select * from books  where status=0  order by views desc').then((data)=>{
    console.log(data)
}).catch((err)=>{
	 console.log(err)
})           
  • 同步和异步调用的区别在于,你是否决定马上处理异常(then,catch),还是以后再说(同步await执行)。
  • 关注老胡,带来更多简单优雅的代码。

继续阅读