北京那个医院治疗白癜风较好 https://wapjbk.39.net/yiyuanzaixian/bjzkbdfyy/bdf/如果是经常使用Node来做服务端开发的童鞋,肯定不可避免的会操作数据库,做一些增删改查(CRUD,CateReadUpdateDelete)的操作,如果是一些简单的操作,类似定时脚本什么的,可能就直接生写SQL语句来实现功能了,而如果是在一些大型项目中,数十张、上百张的表,之间还会有一些(一对多,多对多)的映射关系,那么引入一个ORM(ObjectRelationalMapping)工具来帮助我们与数据库打交道就可以减轻一部分不必要的工作量,Sequelize就是其中比较受欢迎的一个。
CRUD原始版手动拼接SQL
先来举例说明一下直接拼接SQL语句这样比较“底层”的操作方式:
CREATETABLEanimal(idINTAUTO_INCREMENT,nameVARCHAR(14)NOTNULL,weightINTNOTNULL,PRIMARYKEY(`id`));
创建这样的一张表,三个字段,自增ID、name以及weight。如果使用mysql这个包来直接操作数据库大概是这样的:
constconnection=mysql.cateConnection({})consttableName=animalconnection.connect()//我们假设已经支持了Promise//查询const[sults]=awaitconnection.query(`SELECTid,name,weightFROM${tableName}`)//新增constname=Nikoconstweight=70awaitconnection.query(`INSERTINTO${tableName}(name,weight)VALUES(${name},${weight})`)//或者通过传入一个Object的方式也可以做到awaitconnection.query(`INSERTINTO${tableName}SET?`,{name,weight})connection.end()
看起来也还算是比较清晰,但是这样带来的问题就是,开发人员需要对表结构足够的了解。
如果表中有十几个字段,对于开发人员来说这会是很大的记忆成本,你需要知道某个字段是什么类型,拼接SQL时还要注意插入时的顺序及类型,WHERE条件对应的查询参数类型,如果修改某个字段的类型,还要去处理对应的传参。
这样的项目尤其是在进行交接的时候更是一件恐怖的事情,新人又需要从头学习这些表结构。
以及还有一个问题,如果有哪天需要更换数据库了,放弃了MySQL,那么所有的SQL语句都要进行修改(因为各个数据库的方言可能有区别)
CRUD进阶版Sequelize的使用
关于记忆这件事情,机器肯定会比人脑更靠谱儿,所以就有了ORM,这里就用到了在Node中比较流行的Sequelize。
ORM是干嘛的
首先可能需要解释下ORM是做什么使的,可以简单地理解为,使用面向对象的方式,通过操作对象来实现与数据库之前的交流,完成CRUD的动作。开发者并不需要关心数据库的类型,也不需要关心实际的表结构,而是根据当前编程语言中对象的结构与数据库中表、字段进行映射。
就好比针对上边的animal表进行操作,不再需要在代码中去拼接SQL语句,而是直接调用类似Animal.cate,Animal.find就可以完成对应的动作。
Sequelize的使用方式
首先我们要先下载Sequelize的依赖:
npmisequelizenpmimysql#以及对应的我们需要的数据库驱动
然后在程序中创建一个Sequelize的实例:
constSequelize=qui(Sequelize)constsequelize=newSequelize(mysql://root:jarvis17.0.0.1:06/ts_test)//dialect://username:passwordhost:port/db_name//针对上述的表,我们需要先建立对应的模型:constAnimal=sequelize.define(animal,{id:{type:Sequelize.INTEGER,autoIncment:true},name:{type:Sequelize.STRING,allowNull

alse},weight:{type:Sequelize.INTEGER,allowNull

alse},},{//禁止sequelize修改表名,默认会在animal后边添加一个字母`s`表示负数fezeTableName:true,//禁止自动添加时间戳相关属性timestamps

alse,})//然后就可以开始使用咯//还是假设方法都已经支持了Promise//查询constsults=awaitAnimal.findAll({raw:true,})//新增constname=Nikoconstweight=70awaitAnimal.cate({name,weight,})sequelize定义模型相关的各种配置:docs
抛开模型定义的部分,使用Sequelize无疑减轻了很多使用上的成本,因为模型的定义一般不太会去改变,一次定义多次使用,而使用手动拼接SQL的方式可能就需要将一段SQL改来改去的。
而且可以帮助进行字段类型的转换,避免出现类型强制转换出错NaN或者数字被截断等一些粗心导致的错误。
通过定义模型的方式来告诉程序,有哪些模型,模型的字段都是什么,让程序来帮助我们记忆,而非让我们自己去记忆。我们只需要拿到对应的模型进行操作就好了。
这还不够But,虽说切换为ORM工具已经帮助我们减少了很大一部分的记忆成本,但是依然还不够,我们仍然需要知道模型中都有哪些字段,才能在业务逻辑中进行使用,如果新人接手项目,仍然需要去翻看模型的定义才能知道有什么字段,所以就有了今天要说的真正的主角儿:sequelize-typescriptCRUD终极版装饰器实现模型定义
Sequelize-typescript是基于Sequelize针对TypeScript所实现的一个增强版本,抛弃了之前繁琐的模型定义,使用装饰器直接达到我们想到的目的。
Sequelize-typescript的使用方式
首先因为是用到了TS,所以环境依赖上要安装的东西会多一些:
#这里采用ts-node来完成举例npmits-nodetypescriptnpmisequelizeflect-metadatasequelize-typescript
其次,还需要修改TS项目对应的tsconfig.json文件,用来让TS支持装饰器的使用:
{"