当前位置: 首页 > 后端技术 > Node.js

Nodejs相关的ORM框架分析_1

时间:2023-04-03 20:29:45 Node.js

总结了写这篇博客的缘由。想找一个nodeORM框架来用。真的很难找到一篇对这些ORM框架进行比较分析的文章。唯一找到的居然是通过明星用数字来谈论英雄,觉得很难服众,所以找了几个来看看。后来就不想分析了,因为发现node的野蛮生长和这些ORM轮子的滋生比比皆是,远超我的想象;后来觉得可以写了,作为一个学node的java出身的业余爱好者,想借助java的ORMFramework,深入了解一下node的ORM框架群的是非,于是挑了几个框架来闲聊。ORM框架ORM框架:ObjectRelationalMapping,object-relationship-mapping,所以ORM框架是以面向对象的方式来匹配现在的关系数据库。Java开发者熟悉的是目前主流的hibernate和mybatis,原来的JDBCdriver方法肯定不会成为主流了。下面介绍node.js的几种ORM框架。在介绍ORM的两种模式之前:ActiveRecord模式:活动记录模式、领域模型模式。一个模型类对应关系数据库中的一张表,模型类的一个实例对应一张表。一行记录。这个不难理解,比较简单,但是不够灵活。再看另一种模式,对比一下DataMapper模式:数据映射模式,领域模型对象和数据表松耦合,只做业务逻辑处理,与数据层解耦。需要实体管理器将模型映射到持久层,这样灵活性高,当然也增加了复杂度。因此DataMapper模式对业务代码的干预更少,ActiveRecord模式直接对对象进行增删改查,代码编写更方便。这就好比hibernate和mybatis这两个框架。如果想深入研究一下,可以理解有这么一句话是非常认同的,ActiveRecord更适合短期快速开发的简单项目,而DataMapper更适合长期开发复杂的项目保持业务逻辑和数据存储独立的项目。此外,在技术选择上还应考虑其他因素,如项目的历史背景等。TypeORMTypeORM是一个ORM框架。详细介绍见TypeORM官方介绍。TypeORM也借鉴了hibernate,所以你会觉得很熟悉,尤其是装饰类的方式。闲话少说,直接使用CLI命令快速搭建项目npminstalltypeorm-g创建项目typeorminit--nameMyProject--databasemysqlname为项目名称,database为要使用的数据库,TypeORM支持多个数据库。生成文档结构MyProject├──src//TypeScript代码│├──entity//存储实体的位置(数据库模型)││└──User.ts//示例实体│├──migration//存储迁移的目录│└──index.ts//程序执行主文件├──.gitignore//gitignore文件├──ormconfig.json//ORM和数据库连接配置├──package.json//node模块依赖├──README.md//简单readme文件└──tsconfig.json//TypeScript编译选项修改ormconfig.json数据库配置文件,直接运行npmstart即可看到实体模型,用户类import{Entity,PrimaryGeneratedColumn,Column}from"typeorm";@Entity()exportclassUser{@PrimaryGeneratedColumn()id:number;@Column()firstName:string;@Column()lastName:string;@Column()age:number;}CRUD操作:逻辑层导入“reflect-metadata”;从“typeorm”导入{createConnection};从“./entity/User”导入{User};createConnection().then(asyncconnection=>{console.log("Insertinganewuserintothedatabase...");constuser=newUser();user.firstName="Timber";user.lastName="Saw";user.age=25;awaitconnection.manager.save(user);console.log("保存了一个新的userwithid:"+user.id);console.log("正在从数据库中加载用户...");constusers=awaitconnection.manager.find(User);console.log("Loadedusers:",users);console.log("在这里你可以设置和运行express/koa/任何其他框架。");}).catch(error=>console.log(error));所以,TypeORM的方式很像hibernate的方式,虽然es6已经有了装饰器,具有类似Java注解的功能,但它还是和装饰器不同,因为TypeORM使用的是TypeScript方法,它是JavaScript的超集。TypeScript使用的类型注解方式虽然支持es6标准,但还是需要了解一些语法,或多或少增加了选择的难度。Sequelize是star最多的ORM框架。官方不提供中文文件。找个CLI命令没有快速搭建,也找不到合适的轮子,只能自己搭建,并不代表离不开轮子。不过Sequelize的官网文档还是很赏心悦目的,不得不表扬一下。需要注意的一点是Sequelizev5版本发生了比较大的变化。在这里我将重点介绍最新版本的v5。老版本的可以看官方文档。Sequelizev5installnpmpackage$npminstall--savesequelize$npminstall--savemysql2数据库配置文件config.jsmodule.exports={database:{dbName:'TEST',host:'localhost',port:3306,user:'root',password:'123456'}}参考nodejs进阶视频讲解:进入学习建库访问公共文件db.jsconstSequelize=require('sequelize')const{dbName,host,port,user,password}=require('../config').databaseconstsequelize=newSequelize(dbName,user,password,{dialect:'mysql',host,port,logging:true,timezone:'+08:00',define:{//create_time&&update_timetimestamps:true,//delete_timeparanoid:true,createdAt:'created_at',updatedAt:'updated_at',deletedAt:'deleted_at',//将驼峰式大小写转换为下划线underscored:true,scopes:{bh:{attributes:{exclude:['password','updated_at','deleted_at','created_at']}},iv:{attributes:{exclude:['content','password','updated_at','deleted_at']}}}}})//创建模型sequelize.sync({force:false})module.exports={sequelize}modelconst{Sequelize,Model}=require('sequelize')const{db}=require('../../db')classUserextendsModel{}User.init({//属性firstName:{type:Sequelize.STRING,allowNull:false},lastName:{type:Sequelize.STRING//allowNull默认为true}},{db,modelName:'user'//选项});还有一种写法,兼容老版本,不推荐.STRING//allowNull默认为true}},{//options});这实际上是sequelize.define在内部调用model.init,但是老版本没有第一种写法。另外要知道,sequelize还默认为每个model定义了字段id(主键)、createdat和updatedat,也是可以设置的。在我们的db.js文件中配置了不自动创建模型,即自动创建数据表。关闭它是有原因的,因为如果表存在,它会先被删除,然后再创建。这个操作本身就很可怕//CreateModelsequelize.sync({force:false})单个模型也可以配置,记住这个操作是很危险的,尤其是在生产环境中//注意:使用`force:true`如果表已经存在,将删除表User.sync({force:true}).then(()=>{//现在数据库中的`users`表对应于模型定义returnUser.create({firstName:'约翰',lastName:'汉考克'});});CRUD操作:再看逻辑层,很简单,直接用ES7async/await就可以了//FindallusersUser.findAll().then(users=>{console.log("Allusers:",JSON.stringify(users,null,4));});//创建一个新的用户User.create({firstName:"Jane",lastName:"Doe"}).then(jane=>{console.log("Jane'sauto-generatedID:",jane.id);});//删除所有名为“Jane”的人User.destroy({where:{firstName:"Jane"}}).then(()=>{console.log("Done");});//改变所有人没有最后名称为“Doe”User.update({lastName:“Doe”},{where:{lastName:null}}).then(()=>{console.log("Done");});从这个看,没有什么typeorm装饰方法看起来顺眼,但是整体结构简单易用,操作简单,容易理解。看官网文档,功能覆盖很强大。Typeorm用户反馈的使用问题比Sequelize多,我们后面会用它来做对比ORM2ORM2好像没有官网改正,所以看起来特别麻烦,不过可以看看github介绍node-orm2,只支持MySQL、PostgreSQL、AmazonRedshift、SQLite四种数据库。这个我没写demo,直接分析一下安装npminstallorm数据库连接varorm=require("orm");orm.connect("mysql://username:password@host/database",function(err,db){//...里面有些参数没有写详细});modelvarPerson=db.define('person',{name:String,surname:String,age:String,male:boolean},{identityCache:true});CRUD操作Person.create([{name:"John",surname:"Doe",age:25,male:true},{name:"Liza",surname:"Kollan",age:19,male:false}],function(err,items){//err-错误的描述或null//items-插入项目的数组});Person.get(1,function(err,John){John.name="Joe";John.surname="Doe";John.save(function(err){console.log("saved!");});//保存Person.find({surname:"Doe"}).remove(function(err){//Doesgone..});//Remove});Person.find({name:"admin"}).limit(3).offset(2)//skip.only("name","age")//returnfield.run(function(err,data){});所以,应该就是node-orm2,写法跟sequelize差不多,但是文档确实不好,数据库支持也少。后续可维护性很难想象。其他书架(这个也用的比较多)persistencejswaterlinemongoosenode-mysqlknex