简体   繁体   English

ZCCADDEDB567ABAE643E15DCF0974E503Z 与 MongoDB 连接

[英]Mongoose Connection with MongoDB

I've been working with Mongoose/MongoDB and I realized I don't quite understand how the connection between mongoose and my MongoDB database persists.我一直在使用 Mongoose/MongoDB,但我意识到我不太明白 mongoose 和我的 MongoDB 数据库之间的连接是如何持续存在的。 Let's say I have Node application with a server.js file.假设我有一个带有 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}`)
)

And then I have my database configuration file where the connection is initiated.然后我有我的数据库配置文件,连接开始的地方。

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

My question is, after the database is connected with mongoose.connect(), how does it persist throughout the rest of the application?我的问题是,数据库与mongoose.connect()连接后,它如何在整个应用程序的rest中持续存在? Obviously, this allows me to interact with the database in other files, but I'm not quite clear on what's going on "underneath the hood".显然,这允许我与其他文件中的数据库进行交互,但我不太清楚“幕后”发生了什么。 Let's say I have a Product model假设我有一个产品 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

I can then have a route然后我可以有一条路线

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

Which would operate on this Product model.它将在此产品 model 上运行。 My question is, how is mongoose aware of the database still (after the initial connection) that allows it to call methods on this Model that allow it to interact with the database.我的问题是,mongoose 如何仍然知道数据库(在初始连接之后),它允许它调用这个 Model 上的方法,允许它与数据库交互。

I'm not an expert in MongoDB nor JavaScript but I think that you might have misunderstood some concepts.我不是 MongoDB 和 JavaScript 方面的专家,但我认为您可能误解了一些概念。

Mongoose as it says on its website provides a schema-based solution module to your application data. ZCCADCDEDB567ABAE643E15DCF0974E503Z 正如它在其网站上所说的那样,为您的应用程序数据提供了一个基于模式的解决方案模块。

You use mongoose to connect with the database through its methods, the database is not connected with mongoose.你用mongoose通过它的方法连接数据库,数据库没有用mongoose连接。

Dotenv file basically stores your server configuration data within your project separating it from the code that allows you to display port info, processes etc in a clear way. Dotenv 文件基本上将您的服务器配置数据存储在您的项目中,将其与允许您以清晰的方式显示端口信息、进程等的代码分开。

Let's start reviewing the first file让我们开始回顾第一个文件

Here you create some const of express and dotenv在这里,您创建了一些 express 和dotenv的 const

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

After that, you apply the config method to the dotenv const (you can also add that method at the first line)之后,将 config 方法应用于 dotenv const(您也可以在第一行添加该方法)

dotenv.config()

Now you create the connectDB const loading the content from the DB file (which I suppose it's the next one)现在您创建 connectDB const,从 DB 文件加载内容(我想它是下一个)

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

Calling the method of the class starts the connection with the Database:调用 class 的方法启动与数据库的连接:

connectDB()

Now you use express to make a get request that will be displayed on your root folder and basically will display some basic data from the port and the process (loaded from ENV file)现在您使用 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}`)
)

Let's review now the other file.现在让我们回顾一下另一个文件。

You create a const from mongoose您从 mongoose 创建一个 const

const mongoose = require('mongoose')

And establish a connection to your DB并建立与您的数据库的连接

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)
  }
}

This is the important part, you export that const to the whole project so it can be accessed from different parts of the project that's the reason that allows you to connect with the DB without providing the same credentials every single time, and the same logic applies to dotenv file这是重要的部分,您将该 const 导出到整个项目,以便可以从项目的不同部分访问它,这就是允许您连接数据库而无需每次都提供相同凭据的原因,并且适用相同的逻辑到 dotenv 文件

module.exports = connectDB 

((If you're not familiar with Java just ignore this:)) (((如果你不熟悉 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: 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());

    } 

This would be like your dotenv file, you just have to change the data here instead of changing lots of lines of code when you migrate your DB or update credentials这就像您的 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;
    }
}

And you basically just have to do this:你基本上只需要这样做:

DevOps devops = new DevOps();

which would be similar to:这将类似于:

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

So basically the concept of all of this is to keep your code organized, ofc you can have all of that on a single file but in terms of scalability would be painful to maintain especially when you have to apply any change to your DB.所以基本上所有这一切的概念是保持你的代码有条理,你可以将所有这些放在一个文件中,但就可伸缩性而言,维护起来会很痛苦,尤其是当你必须对数据库应用任何更改时。

Hope this was useful for you, just ask me if you have any doubt!希望这对您有用,如果您有任何疑问,请询问我!

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

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