zoukankan      html  css  js  c++  java
  • Koa 数据库连接和查询分离, CommonJS 模块遇到的一个坑

    踩坑小结一下, 在使用 koa + mysql 进行数据库查询时。为了不让 连接数据库查询数据库 以及路由都在一个文件中(臃肿),特分离三个文件。分别处理 mysql连接mysql异步查询处理路由请求等。

    结构如下:

    - index.js 
    - mysql_config.js
    - async_db.js
    

    index.js 代码如下:

    const Koa = require("koa");
    const Router = require("@koa/router");
    const { connect_mysql } = require("./mysql_config");
    const { findSession } = require("./async_db");
    
    const app = new Koa();
    const router = new Router().prefix("/api");
    
    // 连接数据库
    connect_mysql();
    
    router.get("/session", async ctx => {
      try {
        const { results } = await findSession("SELECT * FROM _mysql_session_store");
    
        ctx.body = {
          errno: 0,
          data: results
        };
      } catch (e) {
        ctx.status = 500;
        ctx.body = e;
      }
    });
    
    app.use(router.routes(), router.allowedMethods());
    
    app.listen(3001);
    

    mysql_config.js 代码如下:

    const mysql = require("mysql");
    let connection;
    
    const connect_mysql = () => {
      connection = mysql.createConnection({
        host: "127.0.0.1",
        user: "root",
        password: "abc123",
        database: "base"
      });
    };
    
    module.exports = {
      connection,
      connect_mysql
    };
    

    async_db.js 代码如下

    const { connection } = require("./mysql_config");
    
    const findSession = sql => {
      return new Promise((resolve, reject) => {
        connection.query(sql, (err, results, fileds) => {
          if (err) return reject(err);
    
          resolve({
            results,
            fileds
          });
        });
      });
    };
    
    module.exports = {
      findSession
    };
    

    结果在浏览器访问 http://localhost:3001/api/session 时, 查询的结果是 {}。

    一番排查后, 发现在 async_db.js 引入的 connection 对象为 undefined。但是在 index.js 文件, 开启服务器的时候已经和服务器建立连接, 并且将结果赋值给 connection 变量了, 在别的文件取不到值呢?

    原来在 async_db.js 文件中访问的 connection 是最开始值的拷贝,在mysql_config.js导出的时候并没有对 connection初始化, 就算后面完成了赋值, 但是在别的模块中也任然只能访问最开始的一份拷贝值 undefined

    解决

    修改 mysql_config.js 文件, 创建一个闭包环境, 将 connection 保存在闭包中, 并对外提供一个可以随时访问闭包环境中的 connection 值。

    const mysql = require("mysql");
    
    (function() {
      // 创建数据库会话
      let connection;
    
      const connect_mysql = () => {
        connection = mysql.createConnection({
          host: "127.0.0.1",
          user: "root",
          password: "abc123",
          database: "base"
        });
      };
    
      const getConnection = () => connection;
    
      module.exports = { getConnection, connect_mysql };
    })();
    

    async_db.js 中引入 getConnection 函数来获取已初始化好的 connection值。

    const { getConnection } = require("./mysql_config");
    
    const findSession = sql => {
      return new Promise((resolve, reject) => {
        getConnection().query(sql, (err, results, fileds) => {
          if (err) return reject(err);
    
          resolve({
            results,
            fileds
          });
        });
      });
    };
    
    module.exports = {
      findSession
    };
    
  • 相关阅读:
    cloudstack secondary vm starting
    什么东西有机会
    ansible 远程以普通用户执行命令
    python 爬虫--同花顺-使用代理
    python3 Beautifulsoup <class 'bs4.element.ResultSet'> <class 'bs4.element.Tag'> 取值
    python3 raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 403: Forbid
    kubernetes 生命周期问题分析
    'utf-8' codec can't decode byte 0xbc in position 1182: invalid start byte
    找回Firefox4的状态栏!Status-4-Evar扩展
    生命周期和Zend引擎
  • 原文地址:https://www.cnblogs.com/qiqingfu/p/12546969.html
Copyright © 2011-2022 走看看