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
};
posted @ 2020-03-22 17:02  qiqf  阅读(385)  评论(0编辑  收藏  举报