【nodejs】让nodejs像后端mvc框架(asp.net mvc)一orm篇【如EF般丝滑】typeorm介绍(8/8)
文章目录
前情概要
在使用nodejs开发过程中,刚好碰到需要做一个小工具,需要用到数据库存储功能。而我又比较懒,一个小功能不想搞一个nodejs项目,又搞一个后端项目。不如直接在nodejs里面把对数据库的操作也做掉。
结果百度一圈下来发现nodejs这边还都是比较原始的、类似后端的通过coneection连数据库,接着open,在写sql语句干嘛干嘛的。经过后端这么多年的脚手架工具熏陶,实在懒得写这些没营养的简单增删改查sql语句了。
typeorm github地址
typeorm github地址
遂通过baidu、google找到了typeorm这个orm框架。果然不错,作者自己也说大量参考了如entityframework、hibernate、dapper等等众多orm框架。吸收了各家之所长。
更多介绍和各种示例可以参考它的demo项目,基本每个数据库都有一个demo,然后对特性也基本都介绍到的。
比如mongodb如何映射复杂对象,关系型数据怎么弄级联删除之类的功能
使用总结
mysql、sqlite、mongodb3个数据库下都使用过,使用感觉虽然没有后端的orm那么强大,但是在nodejs领域内,orm我觉得它已经可以说是no.1啦。当然不排除我孤陋寡闻漏了更NB的其他框架。
绝大多数的后端orm该有的功能它都有,没有可能是没找到正确的使用方式。为此我还发过几条issue给开发者。基本上自己最后google找到解决方或者组件作者给与了回复。
基本功能介绍可以直接去GitHub看,基本上orm应该要有的功能它都有了。
typeorm 项目介绍
此项目github上的第一句介绍:
ORM for TypeScript and JavaScript (ES7, ES6, ES5). Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms.
remark:
TypeORM is highly influenced by other ORMs, such as Hibernate, Doctrine and Entity Framework.
Some TypeORM features:
- supports both DataMapper and ActiveRecord (your choice)
- entities and columns
- database-specific column types
- entity manager
- repositories and custom repositories
- clean object relational model
- associations (relations)
- eager and lazy relations
- uni-directional, bi-directional and self-referenced relations
- supports multiple inheritance patterns
- cascades
- indices
- transactions
- migrations and automatic migrations generation
- connection pooling
- replication
- using multiple database connections
- working with multiple databases types
- cross-database and cross-schema queries
- elegant-syntax, flexible and powerful QueryBuilder
- left and inner joins
- proper pagination for queries using joins
- query caching
- streaming raw results
- logging
- listeners and subscribers (hooks)
- supports closure table pattern
- schema declaration in models or separate configuration files
- connection configuration in json / xml / yml / env formats
- supports MySQL / MariaDB / Postgres / SQLite / Microsoft SQL Server / Oracle / sql.js
- supports MongoDB NoSQL database
- works in NodeJS / Browser / Ionic / Cordova / React Native / NativeScript / Expo / Electron platforms
- TypeScript and JavaScript support
- produced code is performant, flexible, clean and maintainable
- follows all possible best practices
- CLI
And more...
个人的一些用法-mongodb
都是一些非常简单的封装,直接贴代码啦。
typeorm mongodb 初始化配置
比如数据库链接字符串,实体类,还有一些其他配置等等
InitMongoDb({ url: _appConfig.mongodb.url, entities: ['bin/Entity/*.js'], synchronize: true, logging: false }); export function InitMongoDb(dbName: string, mongoOptions: MongoConnectionOptions): void; export function InitMongoDb(mongoOptions: MongoConnectionOptions): void; export function InitMongoDb(): void { var options: MongoConnectionOptions = arguments[0]; var dbName: any; if (typeof arguments[0] === 'string') { dbName = arguments[0]; options = arguments[1]; } var dbName = dbName || 'default'; ManangerMongoConnection.ConnectOptions[dbName] = { hasGetConnection: false, options: options }; }
typeorm mongodb repository管理器
export async function getMongoRepositoryAsync<Entity>(entityClass: ObjectType<Entity>): Promise<GDMongoRepository<Entity>>; export async function getMongoRepositoryAsync<Entity>(entityClass: ObjectType<Entity>, dbName: string): Promise<GDMongoRepository<Entity>> export async function getMongoRepositoryAsync<Entity>(): Promise<GDMongoRepository<Entity>> { var entityClass = arguments[0] as ObjectType<Entity>; var dbName = (arguments.length > 1 ? arguments[1] : undefined) || 'default'; var conn = await new ManangerMongoConnection().getConnection(dbName); var repo = conn.getMongoRepository(entityClass); var gdRepo = new GDMongoRepository(repo) return gdRepo; } class ManangerMongoConnection { static ConnectOptions: any = {}; async getConnection(dbName: string): Promise<Connection> { var conf = ManangerMongoConnection.ConnectOptions[dbName]; if (!conf) throw Error(`找不到(${dbName})的数据库配置`); if (conf.hasCreated) return conf.connection; var options = conf.options as MongoConnectionOptions; var conn = await createConnection({ type: 'mongodb', url: options.url, synchronize: options.synchronize, logging: options.logging, entities: options.entities }); conf.connection = conn; conf.hasCreated = true; return conn; } }
typeorm mongodb repository 简单封装
import { ObjectType, FindManyOptions, MongoRepository, ObjectLiteral, Connection, createConnection, Entity, ObjectIdColumn, Column, ObjectID, getManager } from "typeorm"; import { ObjectId } from 'mongodb' export class GDMongoRepository<TEntity extends ObjectLiteral> { private _repo: MongoRepository<TEntity>; constructor(repo: MongoRepository<TEntity>) { this._repo = repo; } SaveAsync(docment: TEntity): Promise<TEntity> { if (!docment.createdTime) docment.createdTime = new Date(); return this._repo.save(docment); } FindByIdAsync(id: number | string) { return this._repo.findOneById(new ObjectId(id)); } FindByIdsAsync(ids: number[] | string[]) { var _id: ObjectId[] = []; for (let index = 0; index < ids.length; index++) { const element = ids[index]; _id.push(new ObjectId(element)); } return this._repo.findByIds(_id); } FindAsync(optionsOrConditions?: FindManyOptions<TEntity> | Partial<TEntity> | ObjectLiteral): Promise<TEntity[]> { return this._repo.find(optionsOrConditions) } CountAsync(optionsOrConditions?: FindManyOptions<TEntity> | Partial<TEntity> | ObjectLiteral): Promise<number> { var query: any = Object.assign({}, optionsOrConditions); if (query.take) delete query.take; if (query.skip) delete query.skip; if (query.order) delete query.order; query = query.where || query; return this._repo.count(query) } FindAndCount(optionsOrConditions?: FindManyOptions<TEntity> | Partial<TEntity>): Promise<[TEntity[], number]> { return this._repo.findAndCount(optionsOrConditions) } AggregateAsync(pipeline: ObjectLiteral[]): Promise<TEntity[]> { return this._repo.aggregate(pipeline).toArray() } async RemoveByIdAsync(id: number | string): Promise<number> { var r = await this._repo.deleteOne({ _id: new ObjectId(id) }); if (r.deletedCount) return r.deletedCount return 0; } async RemoveAsync(conditions: ObjectLiteral): Promise<number> { var r = await this._repo.deleteMany(conditions); if (r.deletedCount) return r.deletedCount return 0; } async UpdateByIdAsync(id: number | string, update: ObjectLiteral | Partial<TEntity>): Promise<number> { if (update.$set || update.$unset || update.$rename) { } else { update = { $set: update } } update.$set.lastModifyTime = new Date(); var r = await this._repo.updateOne({ _id: new ObjectId(id) }, update); return r.modifiedCount; } async UpdateAsync(query: FindManyOptions<TEntity> | Partial<TEntity> | ObjectLiteral, update: ObjectLiteral | Partial<TEntity>): Promise<number> { if (update.$set || update.$unset || update.$rename) { } else { update = { $set: update } } update.$set.lastModifyTime = new Date(); var r = await this._repo.updateMany(query, update); return r.modifiedCount; } }
一些简单的使用例子
public async list() { var repo = await getMongoRepositoryAsync(Host); var b = await repo.FindAsync(); return b } public async info() { var repo = await getMongoRepositoryAsync(Host); var b = await repo.FindAsync({ Ip: this.request.query.ip, HostEnv: this.request.query.env }); return b }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2017-07-25 扩展entity framework core 实现默认字符串长度,decimal精度,entity自动注册和配置