开发者社区> calvink> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

【nodejs】让nodejs像后端mvc框架(asp.net mvc)一orm篇【如EF般丝滑】typeorm介绍(8/8)

简介: 文章目录 前情概要 在使用nodejs开发过程中,刚好碰到需要做一个小工具,需要用到数据库存储功能。而我又比较懒,一个小功能不想搞一个nodejs项目,又搞一个后端项目。不如直接在nodejs里面把对数据库的操作也做掉。
+关注继续查看

文章目录

前情概要

在使用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
    }

给开源项目点赞!给国际友人点赞!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
asp.net core mvc 中间件之WebpackDevMiddleware
asp.net core mvc 中间件之WebpackDevMiddleware WebpackDevMiddleware中间件主要用于开发SPA应用,启用Webpack,增强网页开发体验。好吧,你想用来干嘛就干嘛,这次主要是通过学习该中间件,学习如何在core中启用Webpack支持 通过上上篇asp.
827 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--目录(8/8 完结)
为什么要做这个 在使用nodejs开发过程中,总是发现需要做很多重复性的体力劳动,且因为自身是服务端程序员出身,感觉有一些服务端好的东西其实可以在nodejs上得到应用并能提高一些开发工作效率。 本系列文章将介绍对express框架的一些扩展,来达到部分后台框架一样的特性功能。
621 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)
文章目录 前情概要 前面一大坨一大坨的代码把route、controller、action、attribute都搞完事儿了,最后剩下一部分功能就是串起来的调用。 那接下就说个说第二个中间件,也是最后一个中间件RequestHandler RequestHandler 中间件的注册 app.use一下就完事啦。
643 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)
文章目录 前情概要 路由、action的扫描、发现、注册搞定之后,后来我发现在我们的action里面获取参数往往都是通过request对象来一个一个获取。同样的一行代码我们不厌其烦的重复写了无数次。遂想着那我们能不能像后端程序一样做得更自动化一些呢? 所以,接下来我们再来完成一个比较重要的功能,那就是参数的自动绑定。
793 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--路由限制及选择篇(2/8)【route】
文章目录 前情概要 上文中的RouteHandler中有一个重要方法GetActionDescriptor没有贴代码和说,接下来我们就说一说这个方法。 使用controllerName、actionName、httpmethod获得唯一匹配的处理函数描述对象 直接上代码,看代码注释即可 //acti...
586 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--控制器的声明定义和发现篇(3/8)
文章目录 前情概要 前面文章把路由已经介绍的差不多了,包括url映射,路由选择等。接下来讲一讲controller的一些基本规则 BaseController的所有代码都在这里拉。相当简单。 主要逻辑:我们的组件接到请求后,根据url规则找到对应的controller和要处理的请求的action后,直接new一个controller出来,把req,res等对象传递给controller对象。
667 0
【nodejs】让nodejs像后端mvc框架(asp.net mvc )一样处理请求--自动路由篇(1/8)【route】
文章目录 前情概要 在使用express框架开发的时候,每加一个请求,都在增加一条route请求规则,类似于下面的代码,很烦有木有! app.use('/myroute path', (req, res, next) => { //dosomething }) 我们难道不能再智能一点点么,学习后端mvc框架一样,比如加个标记,或者默认规则直接自动映射嘛。
697 0
基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-5
来个目录吧:第一章-入门第二章- Entity Framework Core Nuget包管理第三章-创建、修改、删除、查询第四章-排序、过滤、分页、分组第五章-迁移,EF Core 的codefirst使用 暂时就这么多。
1009 0
基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-3
来个目录吧:第一章-入门第二章- Entity Framework Core Nuget包管理第三章-创建、修改、删除、查询第四章-排序、过滤、分页、分组第五章-迁移,EF Core 的codefirst使用 暂时就这么多。
670 0
基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-1
来个目录吧:第一章-入门第二章- Entity Framework Core Nuget包管理第三章-创建、修改、删除、查询第四章-排序、过滤、分页、分组第五章-迁移,EF Core 的codefirst使用 暂时就这么多。
1426 0
+关注
calvink
软件开发从业8年,从一台服务器打天下到几千台服务器共同服务,一路采坑,一路成长
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Java Spring Boot开发实战系列课程【第7讲】:Spring Boot 2.0安全机制与MVC身份验证实战(Java面试题)
立即下载
阿里分布式文件系统PolarFS VLDB2018 论文下载
立即下载
蚂蚁金服大数据开放式创新实践
立即下载