egg项目创建之连接配置(三)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 默认情况下,egg-sequelize 将使用 sequelize@5,您可以自定义 sequelize 版本使用 config.sequelize.Sequelize 绕过

egg的连接配置


  • 安装


$ npm i --save egg-sequelize
$ npm install --save mysql2 # For both mysql and mariadb dialects
或者使用其他方式连接
$ npm install --save pg pg-hstore
$ npm install --save tedious 


  • config/plugin.js里配置插件


exports.sequelize = {
    enable: true,
    package: 'egg-sequelize'
}


  • conif/config.{env}.js里进行连接配置


exports.sequelize = {
  delegate: 'model', // 加载所有的模型到 app.model and ctx.model
  baseDir: 'model', // 要加载的模型目录`app/model/*.js`
  dialect: 'mysql', // 支持的数据连接类型: mysql, mariadb, postgres, mssql
  database: 'test',
  host: 'localhost',
  port: 3306,
  username: 'root',
  password: '',
  // delegate: 'myModel', // load all models to `app[delegate]` and `ctx[delegate]`, default to `model`
  // baseDir: 'my_model', // load all files in `app/${baseDir}` as models, default to `model`
  // exclude: 'index.js', // ignore `app/${baseDir}/index.js` when load models, support glob and array
  // more sequelize options
  timezone: 'Asia/Shanghai', // 时间差
  benchmark: true,
  modelName: 'bar', // 这将控制自动生成的foreignKey和关联命名的名称
  timestamps: false, // 不添加时间戳属性 (updatedAt, createdAt)
  // 我不想要 createdAt
  createdAt: false,
  // 我想 updateAt 实际上被称为 updateTimestamp
  updatedAt: 'updateTimestamp',
  // 并且希望 deletedA t被称为 destroyTime(请记住启用paranoid以使其工作)
  deletedAt: 'destroyTime',
  // paranoid 只有在启用时间戳时才能工作
  paranoid: true,// 不删除数据库条目,但将新添加的属性deletedAt设置为当前日期(删除完成时). 
  underscored: true, // 将自动设置所有属性的字段参数为下划线命名方式.不会覆盖已经定义的字段选项
  freezeTableName: true,// 禁用修改表名; 默认情况下,sequelize将自动将所有传递的模型名称(define的第一个参数)转换为复数. 如果你不想这样,请设置以下内容
  tableName: 'my_very_custom_table_name',// 定义表的名称
  // 启用乐观锁定. 启用时,sequelize将向模型添加版本计数属性,
  // 并在保存过时的实例时引发OptimisticLockingError错误.
  // 设置为true或具有要用于启用的属性名称的字符串.
  version: true,
  define: {
      reezeTableName: true, // 禁止数据读写时给表赋别名(as)
      underscored: true,
      timestamps: false, // 为模型添加createdAt和updatedAt字段
  },
};


  • 也可以进行以下这样连接


exports.sequelize = {
      dialect: 'mysql', // support: mysql, mariadb, postgres, mssql
      connectionUri: 'mysql://root:@127.0.0.1:3306/test',
      // delegate: 'myModel', // load all models to `app[delegate]` and `ctx[delegate]`, default to `model`
      // baseDir: 'my_model', // load all files in `app/${baseDir}` as models, default to `model`
      // exclude: 'index.js', // ignore `app/${baseDir}/index.js` when load models, support glob and array
      // more sequelize options
};


  • egg-sequelize 有一个默认的 sequelize 选项如下


{
        delegate: 'model',
        baseDir: 'model',
        logging(...args) {
          // if benchmark enabled, log used
          const used = typeof args[1] === 'number' ? `[${args[1]}ms]` : '';
          app.logger.info('[egg-sequelize]%s %s', used, args[0]);
        },
        host: 'localhost',
        port: 3306,
        username: 'root',
        benchmark: true,
        define: {
          freezeTableName: false,
          underscored: true,
        },
};


模型文件


默认情况下,请将模型置于 app/model 目录下。


约定


model file class name
user.js app.model.User
person.js app.model.Person
user_group.js app.model.UserGroup
user/profile.js app.model.User.Profile


  • 表格始终具有时间戳字段:created_at datetimeupdated_at datetime


  • 使用下划线样式列名,如: user_idcomments_count


实例


标准


首先定义模型


注意:options.delegate 默认为 model,所以 app.modelSequelize实例, 可以使用如下方法:


app.model.sync, app.model.query ...


// app/model/user.js
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const User = app.model.define('user', {
    login: STRING,
    name: STRING(30),
    password: STRING(32),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE,
  });
  User.findByLogin = async function(login) {
    return await this.findOne({
      where: {
        login: login
      }
    });
  }
  // don't use arraw function
  User.prototype.logSignin = async function() {
    return await this.update({ last_sign_in_at: new Date() });
  }
  return User;
};


现在您可以在控制器中使用它:


// app/controller/user.js
class UserController extends Controller {
  async index() {
    const users = await this.ctx.model.User.findAll();
    this.ctx.body = users;
  }
  async show() {
    const user = await this.ctx.model.User.findByLogin(this.ctx.params.login);
    await user.logSignin();
    this.ctx.body = user;
  }
}


关联


Model.associate() 中定义所有关联,egg-sequelize 将在加载所有模型后执行它。请参见下面的示例:


多数据源


egg-sequelize 支持独立加载多个数据源,您可以使用 config.sequelize.datasources 配置和加载多个数据源。


// config/config.default.js
exports.sequelize = {
  datasources: [
    {
      delegate: 'model', // load all models to app.model and ctx.model
      baseDir: 'model', // load models from `app/model/*.js`
      database: 'biz',
      // other sequelize configurations
    },
    {
      delegate: 'admninModel', // load all models to app.adminModel and ctx.adminModel
      baseDir: 'admin_model', // load models from `app/admin_model/*.js`
      database: 'admin',
      // other sequelize configurations
    },
  ],
};


我们可以这样定义模型:


// app/model/user.js
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const User = app.model.define('user', {
    login: STRING,
    name: STRING(30),
    password: STRING(32),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE,
  });
  return User;
};


// app/admin_model/user.js
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const User = app.adminModel.define('user', {
    login: STRING,
    name: STRING(30),
    password: STRING(32),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE,
  });
  return User;
};


如果为不同的数据源定义同一个模型,那么对于不同的数据库,同一个模型文件将执行两次,因此我们可以使用两个参数获取 sequelize 实例:


// app/model/user.js
// if this file will load multiple times for different datasource
// we can use the secound argument to get the sequelize instance
module.exports = (app, model) => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const User = model.define('user', {
    login: STRING,
    name: STRING(30),
    password: STRING(32),
    age: INTEGER,
    last_sign_in_at: DATE,
    created_at: DATE,
    updated_at: DATE,
  });
  return User;
};


自定义 Sequelize


默认情况下,egg-sequelize 将使用 sequelize@5,您可以自定义 sequelize 版本使用 config.sequelize.Sequelize 绕过,例如:


// config/config.default.js
exports.sequelize = {
  Sequelize: require('sequelize'),
};


完整示例


// app/model/post.js
module.exports = app => {
  const { STRING, INTEGER, DATE } = app.Sequelize;
  const Post = app.model.define('Post', {
    name: STRING(30),
    user_id: INTEGER,
    created_at: DATE,
    updated_at: DATE,
  });
  Post.associate = function() {
    app.model.Post.belongsTo(app.model.User, { as: 'user' });
  }
  return Post;
};


// app/controller/post.js
class PostController extends Controller {
  async index() {
    const posts = await this.ctx.model.Post.findAll({
      attributes: [ 'id', 'user_id' ],
      include: { model: this.ctx.model.User, as: 'user' },
      where: { status: 'publish' },
      order: 'id desc',
    });
    this.ctx.body = posts;
  }
  async show() {
    const post = await this.ctx.model.Post.findByPk(this.params.id);
    const user = await post.getUser();
    post.setDataValue('user', user);
    this.ctx.body = post;
  }
  async destroy() {
    const post = await this.ctx.model.Post.findByPk(this.params.id);
    await post.destroy();
    this.ctx.body = { success: true };
  }
}


同步模型到数据库


我们强烈建议您使用 Sequelize - Migrations 创建或迁移数据库。


此代码只应在开发中使用。


// {app_root}/app.js
module.exports = app => {
  if (app.config.env === 'local' || app.config.env === 'unittest') {
    app.beforeStart(async () => {
      await app.model.sync({force: true});
    });
  }
};


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
Go
GoLand创建项目过程
GoLand创建项目过程
77 0
|
2月前
|
JavaScript
vue3 创建项目、安装依赖、启动项目
vue3 创建项目、安装依赖、启动项目
41 0
|
4月前
|
Java Maven
Idea下运行Maven项目时provide包没有依赖导致类找不到
Idea下运行Maven项目时provide包没有依赖导致类找不到
119 0
|
4月前
|
JavaScript
Mac 使用CLI脚手架创建 Vue项目、不同版本创建项目的项目结构差异
Mac 使用CLI脚手架创建 Vue项目、不同版本创建项目的项目结构差异
|
4月前
vite创建新项目-常见配置信息
vite创建新项目-常见配置信息
41 0
|
11月前
|
XML Java 应用服务中间件
安装使用IDEA,修改样式,配置服务,构建Maven项目(超级详细版)
安装使用IDEA,修改样式,配置服务,构建Maven项目(超级详细版)
66 0
|
JSON JavaScript 前端开发
npm包管理工具基本使用步骤相当于前端的Maven
npm包管理工具基本使用步骤相当于前端的Maven
|
SpringCloudAlibaba Java Nacos
IDEA 最便捷创建 SpringBoot 父子 Module 项目
IDEA 最便捷创建 SpringBoot 父子 Module 项目
2516 0
IDEA 最便捷创建 SpringBoot 父子 Module 项目
|
JSON 安全 测试技术
egg创建后端项目(二)
简单来说,就是把业务逻辑代码进一步细化和分类,所以和数据库交互的代码都放到Service中。这样作有三个明显的好处。
|
JavaScript 前端开发
egg创建后台项目
只要在 package.json 中添加下面的声明之后,会在项目根目录下动态生成 typings 目录,里面包含各种模型的类型声明