Egg 中的 model
- app/model/** 用于放置领域模型,可选,由领域类相关插件约定。
- Loader : Egg 在 Koa 的基础上进行增强最重要的就是基于一定的约定
- 根据功能差异将代码放到不同的目录下管理,对整体团队的开发成本提升有着明显的效果,Loader 实现了这套约定,并抽象了很多底层API可以进一步扩展
- Loader还提供了caseStyle强制指定首字母大小写,比如加载 model时API首字母大写,app/model/user.js => app.model.User
- 文档:https://eggjs.org/zh-cn/advanced/loader.html
Egg 中使用 Mongoose
-
安装:$
npm i egg-mongoose --save
-
在 {app_root}/config/plugin.js 中启用 egg-mongoose 插件
exports.mongoose = { enable: true, package: 'egg-mongoose' };
-
在配置文件中配置 mongoose 数据库连接地址 {app_root}/config/config.default.js
//第一种配置方式 exports.mongoose = { url: 'mongodb://127.0.0.1/example', options: {} }; //第二种推荐配置方式 exports.mongoose = { client: { url: 'mongodb://127.0.0.1/example', options: {}, }, };
-
实际的配置举例
config.mongoose = { // url 示例:mongodb://账号:密码@服务器:端口/库名 client: { url: 'mongodb://eggadmin:123456@127.0.0.1:27017/eggcms', options: {}, }, };
-
在egg项目的app目录里面新建model文件夹,在model文件夹中定义mongoose的schema和model。如:{app_root}/app/model/user.js
module.exports = app => { // 引入建立连接的mongoose const mongoose = app.mongoose; const Schema = mongoose.Schema; // 数据库表的映射 const UserSchema = new Schema({ username: { type: String, unique: true, }, password: String, age: Number, sex: String, tel: Number, status: { type: Number, default: 1, }, }); return mongoose.model('User', UserSchema, 'user'); };
-
在egg项目控制器或者服务里面使用 mongoose
// {app_root}/app/controller/user.js exports.index = function* (ctx) { ctx.body = await ctx.model.User.find({}); }
-
注意:上面和之前的写法都只是举例,我们在项目中不会在控制器中进行数据的查询,我们会把数据处理工作,放入service中
-
我们会专门新建一个app/service目录,用于存放提供数据的服务,如app/service/user.js
'use strict'; const Service = require('egg').Service; class UserService extends Service { async getUserList() { return this.ctx.model.User.find({}); } } module.exports = UserService;
-
之后在controller中调用即可
'use strict'; const Controller = require('egg').Controller; class UserController extends Controller { async index() { const { ctx } = this; ctx.body = await this.service.user.getUserList(); } } module.exports = UserController;
-
继续编写,我们把UserService中的CRUD补全
// 增加用户 async addUser(userObj) { const user = new this.ctx.model.User(userObj); return await user.save(); } // 编辑用户 async editUserById(uid, userObj) { return await this.ctx.model.User.updateOne({ _id: uid, }, userObj); } // 删除用户 async removeUserById(uid) { return await this.ctx.model.User.deleteOne({ _id: uid }); }
关联查询
基于之前的举例,订单和订单详情进行多表查询
-
配置app/model/order.js
'use strict'; module.exports = app => { // 引入建立连接的mongoose const mongoose = app.mongoose; const Schema = mongoose.Schema; // 数据库表的映射 const OrderSchema = new Schema({ order_id: String, uid: Number, trade_no: String, all_price: Number, all_num: Number, }); return mongoose.model('Order', OrderSchema, 'order'); };
-
在controller中进行调用测试(应该封装在service中,此处仅作演示)
'use strict'; const Controller = require('egg').Controller; class OrderController extends Controller { async index() { const { ctx } = this; /* 最简单的方式,只查询订单 const orderResult = await ctx.model.Order.find({}); ctx.body = orderResult; */ // 关联查询订单详情表 ctx.body = await ctx.model.Order.aggregate([ { $lookup: { from: 'order_item', localField: 'order_id', foreignField: 'order_id', as: 'items', }, }, { $match: { all_price: { $gte: 90 } }, }, ]); } } module.exports = OrderController;