掌握数据持久化存储,构建完整的数据驱动应用🗄️

学习目标

  • ✅ 理解关系型数据库和非关系型数据库的区别
  • ✅ 掌握MySQL的基本操作和SQL语法
  • ✅ 学会MongoDB的文档模型和CRUD操作
  • ✅ 能够使用Node.js连接和操作数据库

📖📖 教程概览

数据库是后端开发的核心,负责数据的存储、查询和管理。本教程将带你学习两种主流数据库:MySQL(关系型)和MongoDB(非关系型),并掌握在Node.js中操作数据库的技能。

💻💻 第一步:数据库基础概念

1.1 关系型数据库(MySQL)

  • 结构化数据:预定义的表结构
  • SQL语言:标准化的查询语言
  • ACID事务:保证数据一致性
  • 适用场景:复杂查询、事务处理

1.2 非关系型数据库(MongoDB)

  • 文档模型:灵活的JSON-like格式
  • 无模式:不需要预定义结构
  • 高扩展性:适合大数据和分布式系统
  • 适用场景:快速迭代、非结构化数据

🛠🛠 第二步:MySQL数据库实战

2.1 安装和配置MySQL

# 使用Docker快速启动MySQL
docker run --name mysql-server -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:8.0

# 连接MySQL
mysql -h localhost -P 3306 -u root -p

2.2 基本SQL操作

-- 创建数据库
CREATE DATABASE myapp;
USE myapp;

-- 创建用户表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入数据
INSERT INTO users (username, email, password) 
VALUES ('zhangsan', 'zhangsan@example.com', 'hashed_password');

-- 查询数据
SELECT * FROM users WHERE username = 'zhangsan';

-- 更新数据
UPDATE users SET email = 'new_email@example.com' WHERE id = 1;

-- 删除数据
DELETE FROM users WHERE id = 1;

2.3 Node.js连接MySQL

// 安装mysql2包
npm install mysql2

// db.js - 数据库连接配置
const mysql = require('mysql2/promise');

const dbConfig = {
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '123456',
    database: 'myapp'
};

async function query(sql, params) {
    const connection = await mysql.createConnection(dbConfig);
    const [results] = await connection.execute(sql, params);
    await connection.end();
    return results;
}

module.exports = { query };

🌟🌟 第三步:MongoDB数据库实战

3.1 安装和启动MongoDB

# 使用Docker启动MongoDB
docker run --name mongodb -p 27017:27017 -d mongo:latest

# 连接MongoDB
mongosh

3.2 MongoDB基本操作

// 使用数据库
use myapp

// 插入文档
db.users.insertOne({
    username: "lisi",
    email: "lisi@example.com",
    profile: {
        age: 25,
        city: "北京"
    },
    created_at: new Date()
})

// 查询文档
db.users.find({ "profile.age": { $gt: 20 } })

// 更新文档
db.users.updateOne(
    { username: "lisi" },
    { $set: { "profile.city": "上海" } }
)

// 删除文档
db.users.deleteOne({ username: "lisi" })

3.3 Node.js连接MongoDB

// 安装mongodb包
npm install mongodb

// mongodb.js - MongoDB连接
const { MongoClient } = require('mongodb');

const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);

async function connect() {
    try {
        await client.connect();
        console.log("成功连接到MongoDB");
        return client.db("myapp");
    } catch (error) {
        console.error("连接失败:", error);
    }
}

module.exports = { connect };

🎮🎮 第四步:用户管理系统实战

4.1 项目结构

user-management/
├── package.json
├── server.js
├── config/
│   └── database.js
├── models/
│   ├── userModel.js
│   └── mongoUserModel.js
├── routes/
│   └── userRoutes.js
└── controllers/
    └── userController.js

4.2 MySQL用户模型

// models/userModel.js
const { query } = require('../config/database');

class UserModel {
    // 创建用户
    async createUser(userData) {
        const sql = `INSERT INTO users (username, email, password) VALUES (?, ?, ?)`;
        const result = await query(sql, [userData.username, userData.email, userData.password]);
        return result.insertId;
    }
    
    // 根据ID查询用户
    async getUserById(id) {
        const sql = `SELECT id, username, email, created_at FROM users WHERE id = ?`;
        const [user] = await query(sql, [id]);
        return user;
    }
    
    // 查询所有用户
    async getAllUsers() {
        const sql = `SELECT id, username, email, created_at FROM users`;
        return await query(sql);
    }
    
    // 更新用户信息
    async updateUser(id, userData) {
        const sql = `UPDATE users SET email = ? WHERE id = ?`;
        await query(sql, [userData.email, id]);
    }
    
    // 删除用户
    async deleteUser(id) {
        const sql = `DELETE FROM users WHERE id = ?`;
        await query(sql, [id]);
    }
}

module.exports = new UserModel();

4.3 MongoDB用户模型

// models/mongoUserModel.js
const { connect } = require('../config/database');

class MongoUserModel {
    async getCollection() {
        const db = await connect();
        return db.collection('users');
    }
    
    // 创建用户
    async createUser(userData) {
        const collection = await this.getCollection();
        const result = await collection.insertOne({
            ...userData,
            created_at: new Date()
        });
        return result.insertedId;
    }
    
    // 根据ID查询用户
    async getUserById(id) {
        const collection = await this.getCollection();
        return await collection.findOne({ _id: id });
    }
    
    // 查询所有用户
    async getAllUsers() {
        const collection = await this.getCollection();
        return await collection.find({}).toArray();
    }
    
    // 更新用户信息
    async updateUser(id, userData) {
        const collection = await this.getCollection();
        await collection.updateOne(
            { _id: id },
            { $set: userData }
        );
    }
    
    // 删除用户
    async deleteUser(id) {
        const collection = await this.getCollection();
        await collection.deleteOne({ _id: id });
    }
}

module.exports = new MongoUserModel();

4.4 用户控制器

// controllers/userController.js
const userModel = require('../models/userModel');
const mongoUserModel = require('../models/mongoUserModel');

class UserController {
    // 使用MySQL创建用户
    async createUserMySQL(req, res) {
        try {
            const userId = await userModel.createUser(req.body);
            res.status(201).json({
                success: true,
                message: '用户创建成功',
                data: { id: userId }
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: '创建用户失败',
                error: error.message
            });
        }
    }
    
    // 使用MongoDB创建用户
    async createUserMongoDB(req, res) {
        try {
            const userId = await mongoUserModel.createUser(req.body);
            res.status(201).json({
                success: true,
                message: '用户创建成功',
                data: { id: userId }
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: '创建用户失败',
                error: error.message
            });
        }
    }
    
    // 获取所有用户(MySQL)
    async getUsersMySQL(req, res) {
        try {
            const users = await userModel.getAllUsers();
            res.json({
                success: true,
                data: users
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: '获取用户列表失败',
                error: error.message
            });
        }
    }
    
    // 获取用户详情
    async getUserDetail(req, res) {
        try {
            const user = await userModel.getUserById(req.params.id);
            if (!user) {
                return res.status(404).json({
                    success: false,
                    message: '用户不存在'
                });
            }
            res.json({
                success: true,
                data: user
            });
        } catch (error) {
            res.status(500).json({
                success: false,
                message: '获取用户详情失败',
                error: error.message
            });
        }
    }
}

module.exports = new UserController();

4.5 路由配置

// routes/userRoutes.js
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');

// MySQL路由
router.post('/mysql/users', userController.createUserMySQL);
router.get('/mysql/users', userController.getUsersMySQL);
router.get('/mysql/users/:id', userController.getUserDetail);

// MongoDB路由
router.post('/mongodb/users', userController.createUserMongoDB);

module.exports = router;

4.6 主服务器文件

// server.js
const express = require('express');
const userRoutes = require('./routes/userRoutes');

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 路由
app.use('/api', userRoutes);

// 健康检查
app.get('/health', (req, res) => {
    res.json({ status: 'OK', timestamp: new Date().toISOString() });
});

// 启动服务器
app.listen(PORT, () => {
    console.log(`用户管理服务运行在 http://localhost:${PORT}`);
});

📚📚 小结与练习

本章重点回顾:

  • MySQL适合结构化数据,MongoDB适合灵活的数据模型
  • SQL提供强大的查询能力,MongoDB查询语法更接近JavaScript
  • Node.js通过相应的驱动包可以轻松连接两种数据库
  • 实际项目中根据业务需求选择合适的数据库类型

练习任务:

  1. 在本地安装并配置MySQL和MongoDB
  2. 实现完整的用户管理系统API
  3. 为系统添加数据验证和错误处理
  4. 尝试使用数据库事务(MySQL)和聚合管道(MongoDB)

💡💡 常见问题

Q:如何选择MySQL还是MongoDB?
A:需要复杂事务和关联查询选MySQL,需要灵活模式和快速开发选MongoDB

Q:数据库连接池有什么作用?
A:连接池可以复用数据库连接,提高性能,避免频繁创建和关闭连接

Q:如何保证数据库安全?
A:使用参数化查询防止SQL注入,设置合适的数据库权限,定期备份数据

👉👉 下一篇预告

在下一篇中,我们将学习RESTful API设计,掌握如何设计规范、易用的API接口,为前后端分离开发打下基础!

分类: 「从零到上线」Web开发新手村 🔧后端修炼 标签: Node.js后端开发MySQLMongoDB数据库操作

评论

暂无评论数据

暂无评论数据

目录