Nodejs相关ORM框架分析

news/2024/4/24 17:28:28/文章来源:https://blog.csdn.net/m0_67614517/article/details/129241241

概述

写这篇blog的原因,想找个node的ORM框架用用,确很难找到一篇对比分析这些ORM框架的文章,唯一找到了一篇,居然是通过star数来论英雄,我觉着很难服众,于是就找几个看看。后来又不想分析,因为我发现node这种野蛮生长,滋生这些ORM轮子比比皆是,远比我想象的多;后来又觉着可以写,作为一个java出身业余研究node的就想通过java的ORM框架来洞悉node这群ORM框架的是非曲直,于是挑了几个框架小扯一篇。

ORM框架

ORM框架:Object Relational Mapping,对象-关系-映射,所以说ORM框架就是用面向对象的方式和目前的关系型数据库做匹配,java开发者目前主流的hibernate、mybatis很熟悉了,JDBC原始驱动的方式想必也不在成为主流了。下面介绍几款node的ORM框架,介绍之前先介绍ORM的两种模式:

Active Record 模式:活动记录模式,领域模型模式一个模型类对应关系型数据库中的一个表,模型类的一个实例对应表中的一行记录。这个不难理解,比较简单,但是不够灵活,再看另一种模式,比较一下

Data Mapper 模式:数据映射模式,领域模型对象和数据表是松耦合关系,只进行业务逻辑的处理,和数据层解耦。需要一个实体管理器来将模型和持久化层做对应,这样一来,灵活性就高,当然复杂性也增加了。

所以说,Data Mapper模式对业务代码干预少,Active Record模式直接在对象上CRUD,代码编写也更方便,这就像hibernate和mybatis两种框架,如果想深入研究,可以了解一下

有这么一句话很认同,ActiveRecord更加适合快速开发成型的短期简单项目,而DataMapper更加适合长线开发,保持业务逻辑与数据存储独立的复杂项目。除此之外,技术选型还要考虑其他因素,比如项目历史背景等等。

TypeORM

TypeORM 是一个 ORM 框架,详细介绍见 TypeORM 官方介绍,TypeORM 也借鉴了hibernate,所以你会发现它特别熟悉,尤其是装饰类的方式。

闲话少说,直接用CLI 命令快速构建项目

npm install typeorm -g

创建项目

typeorm init --name MyProject --database mysql

name 是项目的名称,database 是将使用的数据库,TypeORM 支持多种数据库。

生成文档结构

MyProject
├── src              // TypeScript 代码
│   ├── entity       // 存储实体(数据库模型)的位置
│   │   └── User.ts  // 示例 entity
│   ├── migration    // 存储迁移的目录
│   └── index.ts     // 程序执行主文件
├── .gitignore       // gitignore文件
├── ormconfig.json   // ORM和数据库连接配置
├── package.json     // node module 依赖
├── README.md        // 简单的 readme 文件
└── tsconfig.json    // TypeScript 编译选项

修改 ormconfig.json 数据库配置文件,直接运行就可以了

npm start

看一下实体model,user类

import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class User {
​    @PrimaryGeneratedColumn()
​    id: number;​    @Column()
​    firstName: string;​    @Column()
​    lastName: string;​    @Column()
​    age: number;
}

CRUD操作:逻辑层

import "reflect-metadata";
import {createConnection} from "typeorm";
import {User} from "./entity/User";createConnection().then(async connection => {
​    console.log("Inserting a new user into the database...");const user = new User();
​    user.firstName = "Timber";
​    user.lastName = "Saw";
​    user.age = 25;await connection.manager.save(user);
​    console.log("Saved a new user with id: " + user.id);
​    console.log("Loading users from the database...");const users = await connection.manager.find(User);
​    console.log("Loaded users: ", users);
​    console.log("Here you can setup and run express/koa/any other framework.");
}).catch(error => console.log(error));

所以,TypeORM的方式很像hibernate的方式,虽然es6中就已经有装饰器类似java的注解的功能了,但是还是和装饰器有所区别,因为TypeORM采用的是TypeScript 的方式,TypeScript 是 JavaScript 的一个超集,TypeScript 采用类型注解方式,虽然支持es6的标准,但是有些语法还是需要了解,这也或多或少增加了一些选择难度。

Sequelize

这个被star数最多了一个ORM框架,官方居然不给中文文档,找个CLI命令快速构建也没有,也没找到个合适轮子,只能自己搭了,也不是少了轮子就不能活了。不过Sequelize的官网文档看着很顺眼,不得不称赞一下,需要注意的一点Sequelize v5版本发生了比较大的变化,这里我以最新版本v5版本为主,老版本可以自己看看下官方文档。Sequelize v5

安装npm包

$ npm install --save sequelize
$ npm install --save mysql2

数据库的配置文件config.js

module.exports = {
​    database: {
​        dbName: 'TEST',
​        host: 'localhost',
​        port: 3306,
​        user: 'root',
​        password: '123456'}
}

构建数据库访问公共文件db.js

const Sequelize = require('sequelize')
const {
​    dbName,
​    host,
​    port,
​    user,
​    password
} = require('../config').databaseconst sequelize = new Sequelize(dbName, user, password, {
​    dialect: 'mysql',
​    host,
​    port,
​    logging: true,
​    timezone: '+08:00',
​    define: {// create_time && update_time
​        timestamps: true,// delete_time
​        paranoid: 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
}

参考 前端进阶面试题详细解答

model

const {Sequelize, Model} = require('sequelize')
const {db} = require('../../db')class User extends Model {}
User.init({// attributesfirstName: {type: Sequelize.STRING,allowNull: false},lastName: {type: Sequelize.STRING// allowNull defaults to true}
}, {db,modelName: 'user'// options
});

还有一种写法,兼容老版本,不推荐

const User = db.define('user', {// attributesfirstName: {type: Sequelize.STRING,allowNull: false},lastName: {type: Sequelize.STRING// allowNull defaults to true}
}, {// options
});

这种实际上是sequelize.define内部调用了model.init,但是老版本是没有第一种写法的。

此外需要知道的是,sequelize还默认为每个模型定义字段id(主键)、createdat和updatedat,也可以进行设置。

我们的db.js文件里面配置了,不自动创建模型,也就是自动创建数据表,关闭是有原因的,因为如果表存在会先drop然后再创建,这种操作本身就很可怕的

// 创建模型
sequelize.sync({force: false
})

单个模型也可以配置,切记这种操作很危险,尤其是生成环境

// Note: using `force: true` will drop the table if it already exists
User.sync({ force: true }).then(() => {// Now the `users` table in the database corresponds to the model definitionreturn User.create({firstName: 'John',lastName: 'Hancock'});
});

CRUD操作:然后看一下逻辑层,就非常简单了,直接使用ES7 async/await即可

// Find all users
User.findAll().then(users => {console.log("All users:", JSON.stringify(users, null, 4));
});
// Create a new user
User.create({ firstName: "Jane", lastName: "Doe" }).then(jane => {console.log("Jane's auto-generated ID:", jane.id);
});
// Delete everyone named "Jane"
User.destroy({where: {firstName: "Jane"}
}).then(() => {console.log("Done");
});
// Change everyone without a last name to "Doe"
User.update({ lastName: "Doe" }, {where: {lastName: null}
}).then(() => {console.log("Done");
});

由此来看,没有typeorm装饰类的方式看着顺眼,但是整体构造也容易上手,操作简单,容易理解,看官网文档,功能覆盖强大,typeorm用户反馈使用问题比Sequelize要多,后期用到再做比较。

ORM2

ORM2貌似没有正了八经的官网,所以看起来就特别麻烦,但是可以看一下github介绍node-orm2,只支持四种数据库MySQL、PostgreSQL、Amazon Redshift、SQLite,这个我没写demo,直接分析一下

安装

npm install orm

数据库连接

var orm = require("orm");
orm.connect("mysql://username:password@host/database", function (err, db) {// ...里面一些参数不详细写了
});

model

var Person = 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 - description of the error or null// items - array of inserted 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) {// Does gone..});//删除
});
Person.find({name: "admin"}).limit(3).offset(2)//跳过.only("name", "age")//返回字段.run(function(err, data) {});

所以,准确应该是node-orm2,写法和sequelize类似,但是文档确实不行,数据库支持也少,很难想象后续的可维护性。

其它

  • bookshelf(这个用的也挺多)

  • persistencejs

  • waterline

  • mongoose

  • node-mysql

  • knex

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75020.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用逻辑运算符

逻辑符号表格 逻辑符号含义描述&按位与将数字转成二进制计算&#xff0c;两个位都为1时&#xff0c;结果才为1|或两个位都为0时&#xff0c;结果才为0 &#xff0c;反知任何一个为1结果为1^异或两个位相同为0&#xff0c;不同为1<<左移整体二进位全部左移若干位&…

webrtc音视频通话(一)搭建turn服务器

全球定位&#xff1a;webrtc音视频通话&#xff08;一&#xff09;搭建turn服务器webrtc音视频通话&#xff08;二&#xff09;简单音视频通话webrtc音视频通话&#xff08;三&#xff09;整合websocket在学习webrtc之前呢&#xff0c;需要对websocket有一定基础&#xff0c;如…

腾讯云卖向“有币”区块链

曾经坚决“不涉币”的腾讯云将业务延伸向“有币区块链”。 在首届 Web3 全球峰会“腾讯云Web3构建日”上&#xff0c;腾讯云宣布进军Web3&#xff0c;并公开了与Ankr、Avalanche、Scroll和Sui 四个原生区块链项目的合作&#xff0c;其中前两个项目都发行了加密货币&#xff0c…

比特数据结构与算法(第四章_中_续②)堆解决Topk问题(最小的k个数)

TopK问题介绍&#xff1a;在N个数中找出最大/小的前K个 &#xff08;比如在1000个数中找出最大/小的前10个&#xff09;以前的方法&#xff1a;冒泡排序。时间复杂度&#xff1a; O(N^2)现在找最大的k个数的方法&#xff1a;方法1&#xff1a;堆排序降序&#xff0c;前N个就是最…

使用非对称加密(RSA) 实现前端加密后端解密

数据加密方式有&#xff1a; 单向加密、对称加密、非对称加密、加密盐、散列函数、数字签名。 1、单向加密 单向加密通过对数据进行摘要计算生成密文&#xff0c;密文不可逆推还原。只能加密&#xff0c;不能解密&#xff0c;常用于提取数据的指纹信息以此来验证数据的完整性…

JVM内存溢出与内存泄露

1. 什么是内存溢出? 当前创建的对象的大小大于可用的内存容量大小&#xff0c;发生内存溢出。2. 什么是内存泄露? 该回收的垃圾对象没有被回收&#xff0c;发生了内存泄露&#xff0c;垃圾对象越堆越多&#xff0c; 可用内存越来越少&#xff0c;若可用内存无法存放新的垃圾…

Tcpdump抓包验证zookeeper的心跳机制

一、背景 在分布式系统中&#xff0c;zookeeper可以作为服务注册中心&#xff0c;所有提供服务的节点都可以在zookeeper上面注册&#xff0c;并作为一个node被组织起来&#xff0c;如下图&#xff1a; 在RPC框架中&#xff0c;这些服务提供者就是RPC服务的提供者。zookeeper注…

185、【栈与队列】leetcode ——496. 下一个更大元素 I:单调栈-哈希表(C++版本)

题目描述 原题链接&#xff1a;496. 下一个更大元素 I 解题思路 本题与 739. 每日温度 的区别在于&#xff0c;需要先通过让nums1与nums2判定出为想等元素后&#xff0c;再去找nums2中更大的数。 因此&#xff0c;第一步需要找到想等数&#xff0c;第二步需要找到大于的数。…

c++之引用

目录 引用的概念 引用做函数参数 引用的本质 常引用 引用的概念 在c中新增加了引用的概念&#xff0c;引用可以看作一个已定义变量的别名。 引用的语法&#xff1a;Type &name var; int main() {int a 10;int &b a;printf("b%d\n", b);printf(&quo…

第四阶段02-酷鲨商城项目Mybatis相关的配置

14. 添加与Mybatis相关的配置 在每个项目中&#xff0c;当需要使用Mybatis实现数据库编程时&#xff0c;都需要添加2项一次性配置&#xff1a;配置Mapper接口所在的包&#xff08;package&#xff09;、配置XML文件在哪里。 关于配置Mapper接口所在的包&#xff0c;可以&…

【一】kubernetes集群部署

一、docker环境搭建 1、移除以前docker相关包 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine2、配置yam源 sudo yum install -y yum-utilssudo yum-config-manager --ad…

C++进阶--二叉树编程题

文章目录力扣606. 根据二叉树创建字符串力扣102. 二叉树的层序遍历力扣236. 二叉树的最近公共祖先JZ36 二叉搜索树与双向链表力扣105--通过前序和中序遍历构造二叉树力扣144--二叉树的前序遍历&#xff08;非递归&#xff09;力扣94--二叉树的中序遍历&#xff08;非递归&#…

虹科新闻|虹科与iX systems正式建立合作伙伴关系

近日&#xff0c;虹科与美国iXsystems公司达成战略合作&#xff0c;虹科正式成为iXsystems公司在中国区域的认证授权代理商。未来&#xff0c;虹科将携手iXsystems&#xff0c;共同致力于提供企业级存储解决方案。虹科及iXsystems双方的高层领导人员都对彼此的合作有很大的信心…

操作系统基础教程

目录 第二章&#xff1a;处理器管理 概览 进程调度的层次 进程的调度方式&#xff1a; 调度的评价标准&#xff1a; 典型的调度算法&#xff1a; 第三章&#xff1a;同步、通信和死锁 什么是进程同步&#xff1f; 什么是进程互斥&#xff1f; 进程同步的实现方式 进程…

JVM总结

1. 内存结构 线程私有区 程序计算器 作用&#xff1a;是一块较小的内存空间&#xff0c;存储的是当前线程所执行的字节码文件的序号特点&#xff1a;线程私有&#xff0c;不会出现内存空间溢出 虚拟机栈 虚拟机栈是管理JAVA方法执行的内存模型&#xff0c;每个方法执行时都…

贴吧顶贴软件《今日/更新》

贴吧顶贴软件《今日/更新》百收贴吧工具箱&#xff0c;贴吧顶帖软件&#xff0c;贴吧推广引流神器#贴吧顶帖#贴吧推广 hello&#xff0c;大家好&#xff0c;我是软件的作者百收编辑狂潮老师。本次的视频讲解是作为一个百度顶贴的自动化脚本的视频安装教程和使用教程。你作为新…

SpringCloud(五)MQ消息队列

MQ概念常见消息模型helloworld案例实现实现spring AMQP发送消息实现spring AMQP接收消息工作消息队列实现发布订阅模型Fanout Exchange实现DirectExchange实现TopicExchange实现DirectExchange 和FanoutExchange的差异DirectExchange 和TopicExchange的差异基于RabbitListener注…

钉钉产品体验报告

一、调研的目的了解企业社交软件&#xff0c;借写竞品分析来帮助自己整理思路&#xff0c;看清市场的发展趋势&#xff1b;体验这类企业设计软件&#xff0c;掌握产品核心业务流程和产品结构&#xff0c;把握需求对应的功能点和界面结构&#xff0c;并侧面了解用户习惯&#xf…

用Python做数据分析有哪些优势?

众所周知&#xff0c;可以用作数据分析的语言有很多&#xff0c;包含Python、R语言等&#xff0c;而且Python被誉为数据分析的一大利器&#xff0c;更是该领域的首选语言&#xff0c;那么用Python做数据分析有哪些优势呢?跟着蛋糕往下看。 第一、Python语言自身的优势 Pytho…

ShardingSphere水平、垂直分库、分表和公共表

目录一、ShardingSphere简介二、ShardingSphere-分库分表1、垂直拆分&#xff08;1&#xff09;垂直分库&#xff08;2&#xff09;垂直分表2、水平拆分&#xff08;1&#xff09;水平分库&#xff08;2&#xff09;水平分表三、水平分库操作1、创建数据库和表2、配置分片的规则…