繁体   English   中英

ZCCADDEDB567ABAE643E15DCF0974E503Z 与 MongoDB 连接

[英]Mongoose Connection with MongoDB

我一直在使用 Mongoose/MongoDB,但我意识到我不太明白 mongoose 和我的 MongoDB 数据库之间的连接是如何持续存在的。 假设我有一个带有 server.js 文件的 Node 应用程序。

const express = require('express')
const dotenv = require('dotenv')
dotenv.config()

const connectDB = require('./config/db')

connectDB()

const app = express()

app.get('/', (req, res) => {
  res.send('API is running...')
})

const PORT = process.env.PORT || 5000

app.listen(
  PORT,
  console.log(`Server running in ${process.env.NODE_ENV} port ${PORT}`)
)

然后我有我的数据库配置文件,连接开始的地方。

const mongoose = require('mongoose')

const connectDB = async () => {
  try {
    const conn = await mongoose.connect(process.env.MONGO_URI, {
      useUnifiedTopology: true,
      useNewUrlParser: true,
      useCreateIndex: true,
    })

    console.log(`MongoDB Connected: ${conn.connection.host}`)
  } catch (error) {
    console.error(`Error: ${error.message}`)
    process.exit(1)
  }
}

module.exports = connectDB

我的问题是,数据库与mongoose.connect()连接后,它如何在整个应用程序的rest中持续存在? 显然,这允许我与其他文件中的数据库进行交互,但我不太清楚“幕后”发生了什么。 假设我有一个产品 model

const mongoose = require('mongoose')

const reviewSchema = mongoose.Schema(
  {
    name: { type: String, required: true },
    rating: { type: Number, required: true },
    comment: { type: String, required: true },
  },
  {
    timestamps: true,
  }
)

const productSchema = mongoose.Schema(
  {
    user: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User' },
    name: { type: String, required: true },
    image: { type: String, required: true },
    brand: { type: String, required: true },
    category: { type: String, required: true },
    description: { type: String, required: true },
    reviews: [reviewSchema],
    rating: { type: Number, required: true, default: 0 },
    numReviews: { type: Number, required: true, default: 0 },
    price: { type: Number, required: true, default: 0 },
    countInStock: { type: Number, required: true, default: 0 },
  },
  {
    timestamps: true,
  }
)

const Product = mongoose.model('Product', productSchema)

module.exports = Product

然后我可以有一条路线

router.get(
  '/',
  asyncHandler(async (req, res) => {
    const products = await Product.find({})
    res.json(products)
  })
)

它将在此产品 model 上运行。 我的问题是,mongoose 如何仍然知道数据库(在初始连接之后),它允许它调用这个 Model 上的方法,允许它与数据库交互。

我不是 MongoDB 和 JavaScript 方面的专家,但我认为您可能误解了一些概念。

ZCCADCDEDB567ABAE643E15DCF0974E503Z 正如它在其网站上所说的那样,为您的应用程序数据提供了一个基于模式的解决方案模块。

你用mongoose通过它的方法连接数据库,数据库没有用mongoose连接。

Dotenv 文件基本上将您的服务器配置数据存储在您的项目中,将其与允许您以清晰的方式显示端口信息、进程等的代码分开。

让我们开始回顾第一个文件

在这里,您创建了一些 express 和dotenv的 const

const express = require('express')
const dotenv = require('dotenv')

之后,将 config 方法应用于 dotenv const(您也可以在第一行添加该方法)

dotenv.config()

现在您创建 connectDB const,从 DB 文件加载内容(我想它是下一个)

const connectDB = require('./config/db')

调用 class 的方法启动与数据库的连接:

connectDB()

现在您使用 express 发出一个 get 请求,该请求将显示在您的根文件夹中,并且基本上将显示来自端口和进程的一些基本数据(从 ENV 文件加载)

const app = express()

app.get('/', (req, res) => {
  res.send('API is running...')
})

const PORT = process.env.PORT || 5000

app.listen(
  PORT,
  console.log(`Server running in ${process.env.NODE_ENV} port ${PORT}`)
)

现在让我们回顾一下另一个文件。

您从 mongoose 创建一个 const

const mongoose = require('mongoose')

并建立与您的数据库的连接

const connectDB = async () => {
  try {
    const conn = await mongoose.connect(process.env.MONGO_URI, {
      useUnifiedTopology: true,
      useNewUrlParser: true,
      useCreateIndex: true,
    })

    console.log(`MongoDB Connected: ${conn.connection.host}`)
  } catch (error) {
    console.error(`Error: ${error.message}`)
    process.exit(1)
  }
}

这是重要的部分,您将该 const 导出到整个项目,以便可以从项目的不同部分访问它,这就是允许您连接数据库而无需每次都提供相同凭据的原因,并且适用相同的逻辑到 dotenv 文件

module.exports = connectDB 

(((如果你不熟悉 Java 就忽略这个:))

I was working today with MySQL and Java JDBC API and I created some files that allow me to interact with the DB like you're doing with Mongoose, see:

//variables to get DB info and connection
private Connection connection;
    private PreparedStatement stmt = null;
    private ResultSet rs = null;
    private Statement statement = null;
//Constructor, when you create an object of this class will establish a connection 
with the dbCredentials variables (like dotenv)
  public DevOps() throws SQLException {

        this.connection = DriverManager.getConnection(dbCredentials.getDbname(), dbCredentials.getUsername(), dbCredentials.getPass());

    } 

这就像您的 dotenv 文件,您只需在此处更改数据,而不是在迁移数据库或更新凭据时更改大量代码行

public class dbCredentials {

    public final static String username = "user";
    public final static String pass = "password";
    public static String dbname = "jdbc:mysql://192.168.56.1/school";

    public static String allowMultiQueries() {
        return dbname+"?allowMultiQueries=true";
    }

    public static String getUsername() {
        return username;
    }

    public static String getPass() {
        return pass;
    }

    public static String getDbname() {
        return dbname;
    }
}

你基本上只需要这样做:

DevOps devops = new DevOps();

这将类似于:

const connectDB = require('./config/db')

所以基本上所有这一切的概念是保持你的代码有条理,你可以将所有这些放在一个文件中,但就可伸缩性而言,维护起来会很痛苦,尤其是当你必须对数据库应用任何更改时。

希望这对您有用,如果您有任何疑问,请询问我!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM