在Midway中使用sequelize- typescript

895 阅读3分钟

midway的官方文档有提到如何使用sequelize如何使用,但是提供的例子也过于简单,涉及到许多复杂的数据库操作的时候这些就都是坑了,作为一个把这些坑都踩过一遍的大冤种,我觉得很有必要把自己的经验分享出来,好了废话不多说直接开始

配置依赖

首先安装好sequelize模块依赖 npm i @midwayjs/sequelize@3 sequelize sequelize-typescript --save,这里跟官方文档比起来多装了一个sequelize-typescript,然后安装数据库driver,这是一些常用的数据库驱动,

# for MySQL or MariaDB,也可以使用 mysql2 替代
npm install mysql --save
npm install mysql2 --save

# for PostgreSQL or CockroachDB
npm install pg --save

# for SQLite
npm install sqlite3 --save

# for Microsoft SQL Server
npm install mssql --save

# for sql.js
npm install sql.js --save

# for Oracle\
npm install oracledb --save

# for MongoDB(experimental)
npm install mongodb --save

这里我用的是postgres,所以就直接npm install pg --save,之后在configuration.ts里面引入sequelize模块

import { App, Configuration } from '@midwayjs/decorator';
import { ILifeCycle } from '@midwayjs/core';
import { Application } from 'egg';
import { join } from 'path';
import * as sequlize from '@midwayjs/sequelize';

@Configuration({
imports: [sequlize],
importConfigs: [join(__dirname, './config')],
})
export class ContainerLifeCycle implements ILifeCycle {
@App()
app: Application;
async onReady() {
}
}

最后再配置一下config,默认在config.default.ts,

// src/config/config.default.ts
export default {
// ...
sequelize: {
options: {
database: '你的数据库名称',
username: '用户名',
password: '密码',
host: '你的数据库ip地址',
port: 端口号,一般是3306,
encrypt: false, //是否加密
dialect: 'postgres',//这里我的数据库是postgres,如果是mysql就换成mysql,其他的数据库也一样
define: { charset: 'utf8' },
timezone: '+08:00',//时区
logging: console.log //是否打印数据库查询日志
},
sync: false // 本地的时候,可以通过sync: true直接createTable,
},
}

如果需要区分生产环境和开发环境,那就在对应的config里面添加上就好了,这里强烈建议生产环境下不要设置为true,因为seqeulize的sync同步是破坏性的,在生产环境下建议使用在 Sequelize CLI 的帮助下使用高级概念 Migrations(迁移) 进行同步。

数据库操作

基础的配置做好了,接下来我们开定义模型(model)

import { Column, Model,Table } from "sequelize-typescript";
import { BaseTable } from "@midwayjs/sequelize";

@BaseTable
@Table({
    timestamps: true, // 自动维护时间
    tableName: 'user', // 数据库表名称
    freezeTableName: true, // 禁止修改表名,如果不写会把表名自动复数化,users
})
export class User extends Model<User>{
@Column({
comment: '名字'
})
name: string;
}

定义好模型之后就可以进行增删改查了,我们直接在业务层引入刚刚创建好的模型

import { Provide } from "@midwayjs/decorator";
import { User } from '../model/User'

@Provide()
export class SequelizeService {
    async editSQL(){
        //增
        await User.create({
            name:'张三'
        })
        //删
        await User.destory({
            where:{
                name:'张三'
            }
        })
        //改
        await User.update({
            name:'李四'
        },{
            where:{
                name:'张三'
            }
        })
        //查
       const user = await User.findOne({
            where:{
                name:'张三'
            }
        })
    }
}

更多的查询方式可以参考sequelize官方文档,这里我就不再细述了,链接放这儿 好了,到这里,midway的官方文档就停了,涉及到一些更复杂的操作时,就需要我们自己摸索了

事务(transaction)

咱们在使用sequelize时时常需要使用到transaction,但是midway官方文档没有提供这些操作的实例这里贴一下github的issue,原谅我技术太菜,我是真没看懂该怎么操作( ;´Д`)

image.png 这里我说一下我的几种解决思路 第一种,自己new一个sequelize,这种方法确实可行,但是代码属实丑陋,就不贴了 第二种,使用定义好的model,我们可以直接通过定义好的model获取到sequelize实例

import { Provide } from "@midwayjs/decorator";
import { User } from '../model/User'

@Provide()
export class transactionService {
    const t = await User.sequelize.transaction() 
    //这里声明了transaction之后一定要把该事务及时处理掉,不然会造成数据库暂时性死区
    //这里我们涉及到两次数据库的操作,所以要用到事务,当错误的数据库操作后进行数据库回滚
    try{
        await User.create({
            name:'admin'
        },{
            transaction:t
        })
        await User.update({
            name:'test'
        },{
            where:{
                name:'张三'
            },
            transaction:t
        })
        await t.commit() //提交数据更新
    }catch{
        await t.rollback() //数据回滚
        throw error
    }
}

好了涉及到数据库的事务操作就暂时介绍到这里了,后面如果有空到话我会分享下sequlize-typescript的多表关联增删改查的一些经验