分享自己的超輕量級高性能ORM數據訪問框架Deft


Deft 簡介

Deft是一個超輕量級高性能O/R mapping數據訪問框架,簡單易用,幾分鍾即可上手。

Deft包含如下但不限於此的特點:

1、按照Transact-SQL的語法語義風格來設計,只要調用者熟悉基本的Transact-SQL語法即可瞬間無憂開碼,大大降低了學習Deft的成本,甚至零成本。
2、性能十分不錯(個人覺得易用性很重要,只要性能不拖后腿就好了),通過緩存+Emit反射IDataReader,極速獲取List<T>。
3、強大的查詢功能,支持使用Lambda表達式任意組裝where條件,支持各種各樣的運算符和括號優先級,支持給查詢字段取別名。
4、支持SQLServer、MySQL、Oracle、SQLite等多數據庫類型,同時也支持一個業務系統里面存在多個數據庫。
5、支持事務、分頁查詢、排序等。
6、支持like,in等sql操作符,支持avg,count,max,min,sum等sql函數。
7、顏值高,整套語法接口設計的十分巧妙,支持Lambda 表達式,鏈式編程,任意組裝sql,極度美觀。
8、支持手寫sql, List<T> Select<T>(string sql)。
9、各種映射能力,包括任意查詢的結果映射,支持dynamic。
10、實體類非常簡單,手寫即可,不需要借助工具,也沒有特性標記或者繼承BaseEntity等雜七雜八的東西。
11、參數化賦值,防止sql注入。
12、開放DbHelper,滿足特定使用場景(比如考勤報表),可以直接執行成百上千行的復雜sql。
13、對象化操作,編譯時檢查。使用Lambda 表達式做寫入操作時,只會對表達式指定的字段做寫入操作。
14、調用代碼極其簡單,干凈清爽,可讀性強,方便維護。
15、對外拋出OnDbExecute事件,調用方可自行處理日志埋點、sql監控等。
16、開發效率快,基本無配置,無工具支持也可以開發。
17、超輕量、體積小。
18、......等您來發現

不需要xxx入門系列,不需要xxx開發文檔,不需要xxx使用教程,不需要繁瑣的配置,不需要晦澀難懂的使用方式,不需要xxx。。。一切從簡。
因為Deft的設計使用初衷就是一個初學者花30秒鍾配置數據庫連接信息,然后花3分鍾掃一眼和Transact-SQL極度相似的鏈式語法就可以做到對數據庫的訪問。

編譯后的Release版本只有59KB

 

為什么叫Deft?
 

Deft 核心類介紹

Deft共計有4個核心類
Jugg      用於對外提供ORM核心方法的靜態類
JuggContext      用於對外提供ORM核心方法的實例類
JuggDbHelper    用於數據庫訪問的幫助類
JuggConfig    用於設置一些配置項的靜態類

Jugg一詞來源於游戲中的劍聖,是一個敏捷且攻擊屬性都很強的戰斗英雄

 

Deft 3分鍾即可上手使用

實體類

public class UserInfo
{
    public Int32 Id { get; set; }

    public String Name { get; set; }

    public Byte? Age { get; set; }

    public Byte? Sex { get; set; }

    public String Email { get; set; }

    public String Address { get; set; }

    public String Remark { get; set; }

    public Object Test { get; set; } //無意義字段
}

 

.config文件中配置數據庫連接信息

硬編碼也可以配置數據庫連接信息,遵守約定大於配置

JuggConfig.DefaultDbConCfg = new ConnectionStringSettings { ProviderName = "System.Data.SqlClient", ConnectionString = "server=.;database=Northwind;integrated security=SSPI" };

 

強大靈活且易用的語法 

//簡單查詢
var list = Jugg.Select<UserInfo>().Query();

//查詢指定的幾個字段
list = Jugg.Select<UserInfo>(x => x.Name).Query();
list = Jugg.Select<UserInfo>(x => new { x.Id, x.Name, x.Email }).Query();

//查詢的時候,給字段取別名
list = Jugg.Select<UserInfo>(x => new { UserId = x.Id, UserName = x.Name, x.Email }).Query();

//查詢的時候取表別名,訂單拆表,查詢2016年8月份的訂單
list = Jugg.Select<Order>().
            From("Order_201608").
            Where(x => x.Id != null).
            OrderBy(x => x.Id).
            GetPage(8, 50).
            Query();

//帶簡單where條件
int idParameter = 23;
list = Jugg.Select<UserInfo>().Where(x => x.Id != idParameter).Query();

//強大的查詢功能,任意組裝where條件
int[] aryId = { 1, 2, 3 };
list = Jugg.Select<UserInfo>().
            Where(x =>
                    x.Id != null &&                          // where Id is not null
                    (x.Age > 18 || x.Email == null) &&       // and ( Age>18 or Email is null )
                    x.Id.ToString().Contains("8") &&         // and Id like '%8%'
                    aryId.Contains(x.Id) &&                  // and Id in (1,2,3)
                    x.Name.StartsWith("") &&               // and Name like '張%'
                    x.Remark.EndsWith("test") &&             // and Remark like '%test'
                    x.Email.Contains("@qq.com") ||           // and Email like '%@qq.com%'
                    x.Address != null                        // or  Address is not null
                    ).
            Query();

//排序
list = Jugg.Select<UserInfo>().Where(x => x.Id > 0).OrderBy(x => x.Id).Query();
list = Jugg.Select<UserInfo>().
            Where(x => x.Id > 0).
            OrderByDesc(x => x.Id).
            Query();

//分頁查詢
list = Jugg.Select<UserInfo>().
            Where(x => x.Id != null && (x.Age > 18 || x.Email == null)).
            GetPage().            //查詢第1頁,每頁記錄數讀取JuggConfig.PageRecordCount配置的值
            Query();
list = Jugg.Select<UserInfo>().
            GetPage(5, 80).       //查詢第5頁,每頁80條記錄
            Query();

//查詢某一個范圍的記錄
list = Jugg.Select<UserInfo>().
            GetRange(337, 100).       //查詢第337~437條記錄
            Query();


//手寫sql查詢,支持dynamic映射
List<dynamic> listDynamic = Jugg.Select("select * from UserInfo where Id>99;");
list = Jugg.Select<UserInfo>("select * from UserInfo where Id>99;");

listDynamic = Jugg.GetPage("select * from UserInfo where Id>99;");
list = Jugg.GetPage<UserInfo>("select * from UserInfo where Id>99;");

listDynamic = Jugg.GetRange("select * from UserInfo where Id>99;");
list = Jugg.GetRange<UserInfo>("select * from UserInfo where Id>99;");


//單條記錄查詢
var u = Jugg.Find<UserInfo>(x => x.Id == 0);
u = Jugg.Single<UserInfo>(x => x.Id == 239);

//根據條件判斷記錄是否存在
bool b = Jugg.Exists<UserInfo>(x => x.Id == 105);

//Max 函數返回一列中的最大值。null 值不包括在計算中。
int uid = Jugg.Max<UserInfo>(x => x.Id).Query<int>();

//Min 函數返回一列中的最小值。null 值不包括在計算中。
uid = Jugg.Min<UserInfo>(x => x.Id).Where(x => x.Id > 1000).Query<int>();

//Avg 函數返回數值列的平均值。null 值不包括在計算中。
int age = Jugg.Avg<UserInfo>(x => x.Age).Query<int>();

//Sum 函數返回數值列的總數(總額)。
age = Jugg.Sum<UserInfo>(x => x.Age).Query<int>();

//Count(*) 函數返回表中的記錄數。
int count = Jugg.Count<UserInfo>().Query<int>();

//Count(column_name) 函數返回指定列的值的數目(null 不計入)。
count = Jugg.Count<UserInfo>(x => x.Name).Query<int>();


//增刪改            
int id = Jugg.Insert(new UserInfo { Name = "張三" });//根據傳入的對象來新增
id = Jugg.Insert<UserInfo>(x => new { x.Name, x.Age }, "李四", 18);//根據Lambda 表達式,只新增指定的字段


int affectedRowsNum = Jugg.Delete(new UserInfo { Id = 668 });//根據傳入對象的Id刪除
affectedRowsNum = Jugg.Delete<UserInfo>().Where(x => x.Id == 23 && x.Name != null).Execute();//根據where條件刪除
affectedRowsNum = Jugg.Delete<UserInfo>().Execute();//全表刪除


affectedRowsNum = Jugg.Update(new UserInfo { Id = 569, Name = "張三update" });//根據傳入的對象來更新

affectedRowsNum = Jugg.Update<UserInfo>(x => new { x.Name }, "張三").
                        Where(x => x.Id == 23).Execute();//根據Lambda 表達式,只更新指定的字段


//通過JuggContext上下文來執行事務
using (JuggContext context = new JuggContext())
{
    try
    {
        context.BeginTransaction();

        id = context.Insert<UserInfo>(a => new { a.Name, a.Email, a.Age }, "張三", "123456@qq.com", 22);

        int r1 = context.Update<UserInfo>(x => new { x.Name }, "張三98261571").
                            Where(x => x.Id == id).
                            Execute();

        int r2 = context.Delete<UserInfo>().
                            Where(a => a.Id == id).
                            Execute();

        bool r3 = context.Exists<UserInfo>(x => x.Id == id);

        if (id > 0 && r1 == 1 && r2 == 1 && !r3)
        {
            context.Commit();
        }
        else
        {
            context.Rollback();
        }
    }
    catch
    {
        context.Rollback();
    }
}

 

其他可選的配置參數

JuggConfig.Debug = true;//開啟調試,默認是未開啟

//添加類型無效值,用於過濾不必要的字段
JuggConfig.PropertyTypeInvalidValue.Add(typeof(byte), default(byte));
JuggConfig.PropertyTypeInvalidValue.Add(typeof(int), default(int));//public int Age { get; set; },如果屬性值為0,則會被Deft自動忽略

JuggConfig.DefaultPrimaryKeyColumnName = "Id";//設置主鍵名稱,默認是 Id

JuggConfig.DeftDbConStrKeyName = "DeftDbCon";//配置.config文件中connectionStrings的key,Deft會自動去加載,默認是DeftDbCon

//硬編碼配置數據庫連接對象
JuggConfig.DefaultDbConCfg = new ConnectionStringSettings { ProviderName = "System.Data.SqlClient", ConnectionString = "server=.;database=Northwind;integrated security=SSPI" };

JuggConfig.PageRecordCount = 50;//設置分頁的每頁記錄數,默認是50

JuggDbHelper.OnDbExecute += OnDbExecute;//數據庫執行事件,必須先通過設置JuggConfig.Debug開啟調試模式才會起效果,默認是訂閱的

static void OnDbExecute(DbConnection con, string sql, DbParameterCollection dbParameters)
{
    //TODO sql日志埋點
    string dbParamsStr = null;
    foreach (DbParameter item in dbParameters)
    {
        dbParamsStr += string.Format("{0}:{1}  ", item.ParameterName, item.Value);
    }
    Console.WriteLine(string.Format("{0}{1}{2}{1}", sql, Environment.NewLine, dbParamsStr));
}

  

性能測試



Deft還有很多不足之處,希望大家多給些意見和需求,cnblogs社區的熱度是我強勁的動力。

多表語法的設計和解析早就已經完成了,另外多表mapping還在優化中,暫時沒有開放。
關於多表語法設計請前往我的另一篇技術博文:http://www.cnblogs.com/StrangeCity/p/4795117.html

謝謝大家的支持,打算自己用,不再放出來了。是否開源純屬個人意願,無關個體對錯,望諒解!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM