集成 MongoDB
安装mongoDB
首先确保电脑中已安装并启动 MongoDB 数据库,如果是 Mac 电脑,可以用下面的命令快速安装和启动:
$ brew install mongodb-community
$ brew services start mongodb/brew/mongodb-community # 后台启动
# 或者使用
$ mongod --config /usr/local/etc/mongod.conf 前台启动
定义连接参数
config = {
client: {
url: 'mongodb://127.0.0.1/example',
options: {}
}
}
然后在 model/user.js 中定义模型:
module.exports = app => {
const mongoose = app.mongoose
//定义表结构
const UserSchema = new mongoose.Schema(
{
username: {type: String, required: true, unique: true}, // 用户名
password: {type: String, required: true}, // 密码
},
{ timestamps: true } // 自动生成 createdAt 和 updatedAt 时间戳
)
// 生成名为User的mongoDB Model
// 后续操作都是基于该 Model
return mongoose.model('user', UserSchema)
}
在Controller或Service中调用 mongoose 的方法:
const {Controller} = require('egg')
class UserController extends Controller {
// 用户列表 GET /users
async index() {
const {ctx} = this
ctx.body = await ctx.model.User.find({})
}
// 用户详情 GET /users/:id
async show() {
const {ctx} = this
ctx.body = await ctx.model.User.findById(ctx.params.id)
}
// 创建用户 POST /users
async create() {
const {ctx} = this
ctx.body = await ctx.model.User.create(ctx.request.body)
}
// 更新用户 PUT /users/:id
async update() {
const {ctx} = this
ctx.body = await ctx.model.User.findByIdAndUpdate(ctx.params.id, ctx.request.body)
}
// 删除用户 DELETE /users/:id
async destroy() {
const {ctx} = this
ctx.body = await ctx.model.User.findByIdAndRemove(ctx.params.id)
}
}
module.exports = UserController
集成 MySQL
安装 MySQL
首先确保电脑中已安装 MySQL 数据库,如果是 Mac 电脑,可通过下面的命令快速安装和启动:
$ brew install mysql
$ brew services start mysql # 后台启动
# 或者 mysql.server start 前台启动
$ mysql_secure_installation # 设置密码
定义连接参数
config = {
client: {
host: 'localhost',
port: '3306',
user: 'root',
password: 'root',
database: 'cms',
}
}
在 Controller 或 Service 中获取到 mysql 对象
class UserService extends Service {
async find(uid) {
const user = await this.app.mysql.get('users', { id: 11 });
return { user }
}
}
如果启动的时候报错:
ERROR 5954 nodejs.ER_NOT_SUPPORTED_AUTH_MODEError: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
是因为你使用了 MySQL 8.x 版本,而 egg-mysql 依赖了 ali-rds 这个包,这是阿里自己封装的包,里面又依赖了 mysql 这个包,而这个包已经废弃,不支持 caching_sha2_password 加密方式导致的。可以在 MySQL workbench 中运行下面的命令来解决:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
flush privileges
sequelize
但是更好的集成 MySQL 的方式是借助 ORM 框架来帮助我们管理数据层的代码,sequelize 是当前最流行的 ORM 框架,它支持 MySQL、PostgreSQL、SQLite 和 MSSQL 等多个数据源,接下来我们使用 sequelize 来连接 MySQL 数据库,首先安装依赖:
npm install egg-sequelize mysql2 --save
yarn add egg-sequelize mysql2
然后在 config/plugin.js 中开启 egg-sequelize 插件:
exports.sequelize = {
enable: true,
package: 'egg-sequelize',
}
复制代码
同样要在 config/config.default.js 中编写 sequelize 配置
config.sequelize = {
dialect: 'mysql',
host: '127.0.0.1',
port: 3306,
database: 'example',
}
然后在 egg_example 库中创建 books 表:
CREATE TABLE `books` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`name` varchar(30) DEFAULT NULL COMMENT 'book name',
`created_at` datetime DEFAULT NULL COMMENT 'created time',
`updated_at` datetime DEFAULT NULL COMMENT 'updated time',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='book';
创建 model/book.js 文件,代码是:
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize
const Book = app.model.define('book', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
})
return Book
}
添加 controller/book.js 控制器:
const Controller = require('egg').Controller
class BookController extends Controller {
async index() {
const ctx = this.ctx
ctx.body = await ctx.model.Book.findAll({})
}
async show() {
const ctx = this.ctx
ctx.body = await ctx.model.Book.findByPk(+ctx.params.id)
}
async create() {
const ctx = this.ctx
ctx.body = await ctx.model.Book.create(ctx.request.body)
}
async update() {
const ctx = this.ctx
const book = await ctx.model.Book.findByPk(+ctx.params.id)
if (!book) return (ctx.status = 404)
await book.update(ctx.request.body)
ctx.body = book
}
async destroy() {
const ctx = this.ctx
const book = await ctx.model.Book.findByPk(+ctx.params.id)
if (!book) return (ctx.status = 404)
await book.destroy()
ctx.body = book
}
}
module.exports = BookController
最后配置 RESTful 路由映射:
module.exports = app => {
const {router, controller} = app
router.resources('books', '/books', controller.book)
}