• 【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
        }
    

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

  • 相关阅读:
    数据库操作
    jquery 第一章
    算法很美 第一章
    python 学习第四天
    python学习第三天
    python学习第二天
    学习python的第一天
    C#-线程
    C#-流、存储
    C#-集合
  • 原文地址:https://www.cnblogs.com/calvinK/p/nodejs-mvc-typeorm-desc.html
Copyright © 2020-2023  润新知