使用MySQL求助!Nodejs环境下如何操作

使用MySQL求助!Nodejs环境下如何操作

app.js中代码如下

app.locals({
categorys: dao_base.queryAllcategory(function(err, categorys) {})
});

dao_base代码如下

exports.queryAllcategory = function(callback){
mysql.query('select * from cb_category order by seq',function(err, categorys){
    callback(err, categorys);
});
};

jade页面代码如下

#{categorys.length}

然后运行 提示错误

  > 1|   #{categorys.length}
Cannot read property 'length' of undefined

这是为什么啊?


6 回复

根据你提供的信息,问题出在app.locals的设置时机和方式上。app.locals是在应用启动时初始化的,而你希望的是每次请求时都能够获取到最新的数据。因此,你需要将数据获取逻辑放在路由处理函数中,而不是在应用启动时。

示例代码

app.js

const express = require('express');
const app = express();
const dao_base = require('./dao_base'); // 假设dao_base模块已经正确导入

// 设置路由
app.get('/', (req, res) => {
    dao_base.queryAllcategory((err, categorys) => {
        if (err) {
            return res.status(500).send('Database error');
        }
        res.render('index', { categorys }); // 渲染jade模板,并传递数据
    });
});

app.listen(3000, () => {
    console.log('App is listening on port 3000');
});

dao_base.js

const mysql = require('mysql');

// 创建数据库连接
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'yourusername',
    password: 'yourpassword',
    database: 'yourdatabase'
});

connection.connect();

exports.queryAllcategory = function(callback) {
    connection.query('SELECT * FROM cb_category ORDER BY seq', function(err, results, fields) {
        if (err) throw err;
        callback(null, results);
    });
};

index.jade

doctype html
html
  head
    title= 'Category List'
  body
    h1 Category List
    ul
      each category in categorys
        li= category.name
    p Total categories: #{categorys.length}

解释

  1. 路由处理

    • app.js中,我们将数据获取逻辑移到了路由处理函数中。这样每次请求都会重新执行queryAllcategory函数来获取最新的数据。
  2. 数据传递

    • 使用res.render('index', { categorys })将查询结果传递给Jade模板进行渲染。
  3. 错误处理

    • 如果在数据库查询过程中发生错误,我们返回一个500状态码并显示错误信息。
  4. 模板渲染

    • 在Jade模板中,我们使用each循环遍历categorys数组,并显示每个分类的名称。同时,我们也展示了分类的总数。

通过这种方式,你可以确保每次请求都能获取到最新的数据,避免了因为数据未加载完成而导致的undefined错误。


mysql没有连接上,看下配置端口用户名密码之类的 https://github.com/ChunMengLu/node_mysql_test 这是我之前的一个mysql的demo

应该是已经连上了的,调试control输出有信息。

你这写法有很大的问题啊,用你这么写的回调是无法给属性赋值的。你调用dao_base.queryAllcategory这个函数,但是你期待的结果是在异步过程中,所以这个函数的返回值肯定是undefined。你只能在异步的回调中去给app.locals赋值。

有时间你先搞明白JS的函数回调和node的异步吧。

嗯,谢谢。我后来已经想明白了,在函数中是可以得到数据的,不过因为异步的原因 app.locals中得不到数据。现在已经换了一个思路来实现了。

你遇到的问题是因为 app.locals 中的 categorys 是一个异步调用的结果,而 app.locals 在应用启动时是同步执行的。因此,在 dao_base.queryAllcategory 执行完成之前,app.locals 已经返回了结果,导致 categorysundefined

你可以通过以下几种方法来解决这个问题:

方法一:在路由中处理

你可以在路由处理程序中获取数据,并将数据传递给视图。

app.js

const express = require('express');
const app = express();
const dao_base = require('./dao_base');

app.set('views', './views'); // 设置视图目录
app.set('view engine', 'jade'); // 设置模板引擎

app.get('/', (req, res) => {
    dao_base.queryAllcategory((err, categorys) => {
        if (err) return res.status(500).send('Database error');
        res.render('index', { categorys }); // 渲染Jade模板并传递数据
    });
});

app.listen(3000, () => console.log('Server running on port 3000'));

Jade 模板

html
  body
    h1 Category List
    ul
      each cat in categorys
        li= cat.name

方法二:使用中间件

你可以创建一个中间件来处理数据库查询,并将结果保存到 res.locals 中。

middleware.js

const dao_base = require('./dao_base');

module.exports = function(req, res, next) {
    dao_base.queryAllcategory((err, categorys) => {
        if (err) return res.status(500).send('Database error');
        res.locals.categorys = categorys;
        next(); // 继续处理下一个中间件或路由
    });
};

app.js

const express = require('express');
const app = express();
const middleware = require('./middleware');

app.use(middleware);

app.set('views', './views'); // 设置视图目录
app.set('view engine', 'jade'); // 设置模板引擎

app.get('/', (req, res) => {
    res.render('index', { categorys: res.locals.categorys }); // 渲染Jade模板并传递数据
});

app.listen(3000, () => console.log('Server running on port 3000'));

通过上述方法之一,你可以在请求处理期间正确地获取数据库查询结果,并将其传递给视图进行渲染。

回到顶部