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
    };
    
  • 相关阅读:
    linux-Windows文件上传Linux
    linux-ifconfig 查看没有IP
    springBoot 发布war/jar包到tomcat(idea)
    linux-常用命令
    (转)JVM各种内存溢出是否产生dump
    数据库缓存的几种方式
    使用jprofiler分析dump文件一个实例
    Hibernate之一级缓存和二级缓存
    最佳实践 缓存穿透,瞬间并发,缓存雪崩的解决方法
    缓存与数据库一致性之三:缓存穿透、缓存雪崩、key重建方案
  • 原文地址:https://www.cnblogs.com/qiqingfu/p/12546969.html
Copyright © 2011-2022 走看看