EFが重すぎて、MyBatisが軽すぎて、ORMフレームワークはいったいどうやって選びますか?

6654 ワード

EFに代表されるLinqベースのORMフレームワークは常に重い.
彼らの機能はすでに1つのORMの範疇を超えており、ORMはObject Relational Mappingであり、名前から見ると、データベースのフィールドをエンティティの属性に関連付けることを目的としていますが、重型ORMフレームワークは多くの追加のことをしています.
  • データベース接続
  • データベーストランザクションパッケージ
  • エンティティキャッシュ
  • エンティティ関連管理
  • データベーステーブル同期
  • これらの機能はとても良くて、
  • の強力な機能は往々にしてデッドボードであり、
  • いくつかの簡単な操作を実現するために、柔軟なSqlを作成することはできません.
    それでNET,Dapperに代表されるのは,開発者が自らSqlを作成したORMフレームワークに基づいているが,軽すぎる.
    自分でSqlを書いているので、とても柔軟ですが、使うのはつらいです.簡単なInsertでもUpdateはSqlと書かなければなりませんが、
    また、データベースの互換性の問題から抜け出すことはできません.あなたが書いたSqlはほとんどの場合、1つのデータベースにしか使用できません.
    今日は軽量級でSqlを書かずにマルチデータベースに対応できるORMフレームワークをご紹介します
    Reface.NPI
    NPIとは
    NPIフルネームNet Persistent Interface .
    インターフェースを利用した軽量級ORMフレームワークです
    市場のほとんどのORMフレームワークとは異なり、LinqベースではなくMethod Nameベースです.
    たとえば
    IList SelectById(int id);
    
    IList SelecyByNameLike(string name);
    
    void UpdatePasswordById(int id, string password);
    
    bool DeleteById(int id);
    

    NPIは、上述したMethodNameと実際の演算時のインバウンドをSql実行情報を生成する方法を提供する.
    このライブラリでは、次の機能は実装されていません.
  • AOPによりinterfaceを生成するProxy(この機能はReface.AppStarter.NPIでCastle.DynamicProxyに基づいて実現される)
  • Sql実行情報の実行
  • .
  • クエリー結果を対応するエンティティにマッピングします(この機能は、Repace.AppStarter.NPIでDapperベースで実装されます)
  • .
  • トランザクションの管理(この機能はReface.AppStarterによって構築されたビジネスフレームワークで実現される予定)
  • このライブラリを直接業務機能の開発に使用することは推奨されず、そのライブラリを一定の二次開発またはカプセル化してから使用することを提案し、開発者はシステムが現在依存しているライブラリに基づいてカプセル化することができる.
    将来的に計画を転換する.NetStandardバージョンは、同時に提供されます.NetCore使用.
    依存
  • Reface.StateMachine(このライブラリに依存するライブラリ内のメソッド名の解析プロセス)
  • Reface(いくつかの基礎的な機能と方法を提供し、.NetStandard 2.0を使用して作成された)
  • 使用したため.NetStrand2.0であるため、本ライブラリは必要である.Net framework 4.6.1以降は使用できません.
    使用方法
    4つのアナライザ
    システムでは、4つのデータベースの異なる操作(削除・変更)に対して、それぞれ4つの異なる意味アナライザが提供されています.
  • ISelectParser
  • IInsertParser
  • IUpdateParser
  • IDeleteParser

  • この4つの変換器は、1つの文字列を構造化されたデータベース処理構造に解析することができる.
    ISelectParser parser = new DefaultSelectParser();
    string command = "ByIdAndName";
    SelectInfo info = parser.Parse(command);
    // info.Fields = [];
    // info.Conditions[0].Field = "Id";
    // info.Conditions[1].Field = "Name";
    // info.Orders = [];
    

    4つのアナライザは、それぞれ4つの異なる文構造を生成できます.
    Parser
    結果のタイプ
    ISelectParser
    SelectInfo
    IInsertParser
    InsertInfo
    IUpdateParser
    UpdateInfo
    IDeleteParser
    DeleteInfo
    これらのxxxInfoの構造は複雑ではありませんが、ここではその展開について詳しく説明しません.
    4つのアナライザの統合
    ICommandParserは4つのアナライザを統合し,方法の区別に関心を持たずにICommandInfoを直接得るようにした.SelectInfo,InsertInfo,UpdateIfo,DeleteInfoともにICommandInfoインタフェースを実現した.
    ICommandParserは、メソッドの最初の単語によってメソッド名を分類し、クエリに属する接頭辞、更新に属する接頭辞は、その実装によって実現されます.
    ライブラリ内のDefaultCommandParserは、次の最初の単語に従って論理的に区別されます.
    クエリ文
  • Get
  • Select
  • Fetch
  • Find
  • PagingGet
  • PagingSelect
  • PagingFetch
  • PagingFind

  • 新規文
  • Insert
  • New
  • Create

  • 文の更新
  • Update
  • Modify

  • 文の削除
  • Delete
  • Remove

  • 次の例は、更新文を解析します.ICommandInfoのTypeフィールドは、ICommandInfoを特定のInfoに変換すべきだと判断するのに役立ちます.
    string command = "UpdateNameById";
    ICommandParser parser = new DefaultCommandParser();
    ICommandInfo info = parser.Parse(command);
    if (info.Type == CommandInfos.Update)
        UpdateInfo updateInfo = (UpdateInfo)info;
    // updateInfo.SetFields[0].Field = "Name";
    // updateInfo.Conditions[0].Field = "Id";
    

    方名とパラメータによる実行情報の生成
    実行情報には2つの情報が含まれています
  • Sql文
  • Sqlパラメータ
  • ライブラリでは、実行情報の生成はISqlCommandGeneratorによって行われます.
    // ISqlCommandGenerator.cs
    using System.Reflection;
    
    namespace Reface.NPI.Generators
    {
        public interface ISqlCommandGenerator
        {
            SqlCommandDescription Generate(MethodInfo methodInfo, object[] arguments);
        }
    }
    

    このインタフェースを設計する目的は,使用者がAOP方式であるメソッドの実行をブロックし,MethodInfoとブロックされたインパラメータをISqlCommandGeneratorに渡し,生成された実行情報に基づいて直接実行し,結果を得ることである.
    現在、ライブラリに実装タイプがあります.D e f a u ltSqlServerCommandGeneratorです.名前から、SqlServer向けの実装であることがわかります.データベースによってサポートされる文が異なることは明らかです.したがって,異なるデータベースに対して異なるISqlCommandGeneratorを記述する必要がある.
    SqlCommandDescriptionは単純なデータ構造であり、SqlCommandとParametersの2つの主要な属性を含み、この2つの属性を使用して後続のSql実行を完了することができます.
    注意事項
  • テーブル名の取得は、INpiDaoにおけるTEntityに基づいて行う、TEntity上のSystemを反射する.ComponentModel.DataAnnotations.Schema.テーブル名を取得するには、Table Attibuteフィーチャーを使用します.
  • TableAttributeは多くの一般的なライブラリに存在するため、参照を間違えないように注意してください.
  • Reface.NPIではテーブル名の取得,フィールドの取得などの論理を書き換えることができ,書き換え方法は後述する.

  • メソッド名および期待Sql参照テーブル
    メソッド名
    所望のSql
    説明
    SelectById
    select * from [table] where id = ?
    Idを条件としてエンティティを問合せ
    SelectNameAndAgeById
    select name, age from [table] where id = ?
    Idを条件としてNameフィールドとAgeフィールドのみをクエリー
    SelectByRegistertimeGreaterthan
    select * from [table] where Registertime > ?
    RegisterTimeがパラメータより大きいエンティティのクエリー
    SelectByRegistertimeGteq
    select * from [table] where Registertime >= ?
    クエリーRegisterTimeがパラメータ以上のエンティティ
    SelectByIdAndName
    select * from [table] where id = ? and name = ?
    IdおよびNameを条件としてエンティティを問合せ
    SelectByIdOrName
    select * from [table] where id = ? or name = ?
    IdまたはNameを条件としてエンティティを問合せ
    SelectByIdOrNameLike
    select * from [table] where id = ? or name like ?
    IdまたはName Likeを条件としてエンティティを問合せ
    SelectByIdOrderbyName
    select * from [table] where id = ? order by name
    Idで問合せ、Nameでソート
    SelectByIdOrderByNameDesc
    select * from [table] where id = ? order by name desc
    Idを条件としてNameで並べ替え
    DeleteById
    delete from [table] where id = ?
    Idを条件として削除
    UpdatePasswordById
    update [table] set password = ? where id = ?
    Idを条件としてPasswordを更新
    UpdatePasswordByNameLike
    update [table] set password = ? where name like ?
    Name Likeを条件としてPasswordを更新
    UpdateStateAndTokenByLastoprtimeGt
    update [table] set state=?,token=? where lastoprtime > ?
    条件としてstateとtokenをLastOprTimeより大きい値で更新
    UpdateById
    update [table] set ... where id = ?
    Idを条件とし,Id以外のフィールドをSet句とする.
    UpdateWithoutCreatetimeById
    update [table] set ... where id = ?
    Idを条件とし,IdとCreatetime以外のフィールドをSet句とする.
    UpdateWithoutStateCreatetimeById
    update [table] set ... where id = ?
    Idを条件とし、Id、State、Createtime以外のフィールドをSet句とする
    InsertWithoutIdCreatetime(Entity)
    insert into [table] (...) values(?,...,?)
    IdフィールドとCreatetimeフィールドの新規実装の除外
    関連リンク
  • Reface.NPI @ Github

  • 次号予告:「NPIメソッドルール詳細」では,4つの操作でサポートされる様々な操作について詳細に説明する.