DapperPoco -- 基於Dapper的、輕量級的、高效能的、簡單的、靈活的ORM框架
為什麼要重複造輪子
因為現有的輪子都在某些方面不太令我滿意,下面我來一一點評一下,歡迎拍磚。
Entity Framework
我喜歡傻瓜化使用方式的框架,同時又不失靈活性。
EF雖然使用起來足夠簡單,但卻不夠靈活。例如,在EF Core中你無法用原生SQL寫一個多表連線查詢(返回的結果是多表連線的結果)
單表簡單條件查詢還好,多表查詢時生成的SQL效能實在不敢恭維,我更喜歡自己寫SQL,可控性更高,心裡有底
EF的設計不利於專案的分層;我理想的設計是隔離、低耦合,和資料庫打交道的事就交給Db層好了,所有資料庫的特性都隔離在Db層內部,對外按業務提供傻瓜化的介面。
而使用EF你沒法做到真正的隔離
Dapper
我喜歡它的輕量級,高效能。但它"只支援"原生SQL讀寫資料庫,使用起來還是不太方便。
很多常用的情景其實可以封裝一下不用寫SQL的,像EF一樣,直接Add一個Entity
雖然現在Dapper已經有了這樣一個封裝,但目前來看實在過於粗糙
PetaPoco
它可以像EF一樣直接Add一個Entity,也可以像Dapper一樣自己寫原生SQL,按理說這已經很完美了。
但是,它不支援批量插入、更新啊
DapperPoco
在實在找不到滿意框架的情況下,於是DapperPoco就誕生了,它是基於Dapper高度封裝的,有Dapper的一切優點,同時也彌補了它的不足,它有如下特點:
- 高效能(與Dapper一致),以熱啟動後計算(第一次啟動有快取過程)
- 像EF一樣使用簡單,也可像Dapper一樣靈活使用原生SQL
- 支援使用Fluent API定義實體對映
- 內部模組化靈活、可擴充套件
現已將其開源並放到了github上,地址為:https://github.com/md-frank/DapperPoco
如何使用
首先定義一個Poco類
//表示文章表裡的一條記錄 public class Article { public long Id { get; set; } public string Title { get; set; } public stringContent { get; set; } }
建立DbContext
class MasterDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseConnectionString("連線字串"); //使用SQL Server資料庫 optionsBuilder.UseSqlAdapter(new SqlServerAdapter(SqlClientFactory.Instance)); } //如果不使用Poco可以不重寫此方法 protected override void OnEntitiesBuilding(EntitiesBuilder entityBuilder) { //屬性名與表列名(列名)不一樣,可在此對映別名 entityBuilder.Entity<Article>() .TableName("T_Article") .ColumnName(p => p.Id, "article_id"); } }
插入資料
var masterDb = new MasterDbContext(); //插入一個Poco物件 var a = new Article { Title = "hello", Content = "hello word" }; masterDb.Insert(a); //插入了2條記錄 masterDb.Insert(new Article[] { a, a }); //也可以顯式指定表名 masterDb.Insert(a, "T_Article"); //原生SQL插入 this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a); //插入了2條記錄 this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a, a); //插入了2條記錄 this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", new Article[] { a, a }); //也可以直接寫引數值 this.Execute("insert T_Article(Title, Content) values (@p0, @p1)", "hello", "hello word");
更新資料
var masterDb = new MasterDbContext(); //先查出來準備更新 var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1); //更新除主鍵外的所有列 article.Title = "hello 2"; article.Content = "content 1"; masterDb.Update(article); //僅更新指定列,指定表列名 article.Title = "hello 2"; masterDb.Update(article, new [] { "Title" }); //僅更新指定列,指定實體屬性名 article.Title = "hello 3"; article.Content = "content 1"; masterDb.Update(article, null, null, p=> p.Title, p=> p.Content);
儲存資料
var masterDb = new MasterDbContext(); var article = new Article { Id = 1, Title = "hello", Content = "hello word" }; //如果記錄存在則更新,不存在則插入 masterDb.Save(article); //儲存並指定列名 masterDb.Save(article, new [] { "Title" });
刪除資料
var masterDb = new MasterDbContext(); var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1); //刪除實體記錄 masterDb.Delete(article); //刪除實體記錄,顯式指定主鍵名 masterDb.Delete(article, "article_id");
查詢資料(立即執行)
var masterDb = new MasterDbContext(); //查詢T_Article表所有記錄 var articles = masterDb.FetchAll<Article>(); //指定條件查詢,直接寫引數值 var articles = masterDb.Fetch<Article>("select * from T_Article where [email protected] and [email protected]", "hello", "hello word"); //指定條件查詢,支援列表(實現了IEnumerable介面的) var articles = masterDb.Fetch<Article>("select * from T_Article where article_id in @p0", new [] { 1, 2, 3 }); //查詢單條記錄 masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1); //查詢單列 var count = masterDb.ExecuteScalar<long>("select count(*) from T_Article"); //查詢分頁的結果(第1頁,每頁20條) Paged<Article> paged = masterDb.Paged<Article>(1, 20, "select * from T_Article where [email protected]", "hello"); //Paged的定義如下 public class Paged<T> where T : new() { //當前頁碼 public int CurrentPage { get; set; } //總頁數 public int TotalPages { get; set; } ///總記錄數 public long TotalItems { get; set; } //每頁記錄數 public int ItemsPerPage { get; set; } //當前頁記錄列表 public List<T> Items { get; set; } }
查詢資料(延遲執行)
延遲查詢使用Query,與Fetch不同的是Query返回的結果只有在使用時才會真正查詢資料庫
var masterDb = new MasterDbContext(); //延遲查詢 var articles = masterDb.Query<Article>("select * from T_Article where [email protected]", "hello");
動態查詢條件
var title = "此變數來自使用者輸入"; var sb = new SqlBuilder(); sb.Append("select * from T_Article"); if(!string.IsNullOrEmpty(title)) sb.Append("where [email protected]", title); var sql = sb.Build(); var articles = masterDb.Fetch<Article>(sql.Statement, sql.Parameters);
事務支援
using (var trans = this.GetTransaction()) { //這裡修改資料庫 //提交事務 trans.Complete(); }
相關推薦
DapperPoco -- 基於Dapper的、輕量級的、高效能的、簡單的、靈活的ORM框架
為什麼要重複造輪子 因為現有的輪子都在某些方面不太令我滿意,下面我來一一點評一下,歡迎拍磚。 Entity Framework 我喜歡傻瓜化使用方式的框架,同時又不失靈活性。 EF雖然使用起來足夠簡單,但卻不夠靈活。例如,在EF Core中你無法用原生SQL寫一個
出位的template.js 基於jquery的模板渲染插件,簡單、好用
oid 易懂 light ~~ 支持 jin explore tro inux 找了好幾款基於jquery的模板渲染插件,無一感覺很難用(教程較少、綁定不統一),也可能我智商問題,比如jquery template.js 、jtemplate.js。 然後在github上
基於COM的輕量級元件技術的簡單實現
0 引言 在軟體開發中,元件是一些小的二進位制可執行程式,它們可以給應用程式、作業系統以及其他元件提供服務。實際應用中主要採用COM技術開發軟體元件。這是由Microsoft提出的一種元件標準,它定義了元件程式之間進行互動的標準。標準的COM技術主要用於Microsof
有可能是最最最簡單優美的ORM框架-quill(基於scala)
Quill provides a Quoted Domain Specific Language (QDSL) to express queries in Scala and execute them in a target language. The l
再學ajax--第二天 | 基於php+mysql+ajax的表單註冊、登錄、註銷
常量 insert 寫在前面 break 證明 收獲 localhost 技能 tex 寫在前面 ajax學習到了第二天,這次是用第一天封裝的ajax函數,後端使用了php+mysql實現基本的註冊,登錄,註銷。 php是我前幾個月get到的技能,我已經學習到了
apache分別基於三種方案實現tomcat的代理、負載均衡及會話綁定
tomcat apacheapache分別基於mod_proxy_ajp, mod_proxy_http, mod_jk三種方案實現代理、負載均衡、會話綁定及Tomcat session cluster1、nginx, haproxy, apache(mod_proxy_ajp, mod_proxy_http
SVNKit學習——基於Repository的操作之print repository tree、file content、repository history(四)
oge rgs 新版本 val 技術分享 array class and 解析 此篇文章同樣是參考SVNKit在wiki的官方文檔做的demo,每個類都可以單獨運行。具體的細節都寫到註釋裏了~ 開發背景: SVNKit版本:1.7.14 附上官網下載鏈接:https
【Vj作業】【拓撲排序經典理解題】Ordering Tasks 1、Kahn算法;2、基於DFS的算法。
pri from have for 失敗 dep empty enc there 2018-02-13 鏈接 https://cn.vjudge.net/contest/211129#problem/D John has n tasks to do. Unfortuna
Apache虛擬目錄、用戶認證、基於端口/IP/域名的虛擬主機、SSL
mage nss pda noexec serve 啟動 enable clu adc 環境配置: 配置DNS以便域名解析 安裝Bind軟件包。 yum install -y bind 2. 修改Bind配置文件。 vim /etc/named.conf liste
Java鎖---偏向鎖、輕量級鎖、自旋鎖、重量級鎖
center jdk1 startup 例如 單元 cati 保護 讀鎖 text 之前做過一個測試,反復執行過多次,發現結果是一樣的: 1. 單線程下synchronized效率最高(當時感覺它的效率應該是最差才對); 2. AtomicInteger效率最不穩定,不同並
基於ffmpeg和libvlc的視頻剪輯、播放器
mage 開發工具 希望 lib 感覺 layer 有時 設置 clas 以前研究的時候,寫過一個簡單的基於VLC的視頻播放器。後來因為各種項目,有時為了方便測試,等各種原因,陸續加了一些功能,現在集成了視頻播放、視頻加減速、視頻剪切,視頻合並(增加中)等功能在一起。有時
項目一:第十二天 1、常見權限控制方式 2、基於shiro提供url攔截方式驗證權限 3、在realm中授權 5、總結驗證權限方式(四種) 6、用戶註銷7、基於treegrid實現菜單展示
eal 重復數 規則 認證通過 delete get 數據庫 filter 登陸 1 課程計劃 1、 常見權限控制方式 2、 基於shiro提供url攔截方式驗證權限 3、 在realm中授權 4、 基於shiro提供註解方式驗證權限 5、 總結驗證權限方式(四種) 6、
java 偏向鎖、輕量級鎖及重量級鎖synchronized原理
bubuko 固定 使用情況 防止 不能 image 過程 記錄 原因 Java對象頭與Monitor java對象頭是實現synchronized的鎖對象的基礎,synchronized使用的鎖對象是存儲在Java對象頭裏的。 對象頭包含兩部分:Mark Word 和
[日常練習] 2. 基於函式輸出9*9乘法表、交換兩數、判斷閏年、清空/初始化陣列、判斷素數的C語言實現
在C語言學習中,我們知道它是面向過程進行程式設計的,強調的是功能行為,其主要框架為:資料結構+演算法。在此也可以理解成:資料+函式。其實,函式在C語言學習中無時無刻不在使用,最為簡單的#include<stdio.h>,這便是我們程式的開頭,也是我們所呼叫的第一個函式,稱為:庫函式。
Scrapy框架 基於管道 儲存資料到本地檔案流程、案例
流程思路 將解析資料存到items物件 使用yield 將items交給管道檔案處理 在管道檔案pipelines編寫程式碼儲存 在setting配置檔案開啟管道 案例 setting.py配置檔案 取消註釋,數字為優先順序
基於OkHttp網路通訊工具類(傳送get、post請求、檔案上傳和下載)
一、為什麼要用OkHttp? okhttp是專注於提升網路連線效率的http客戶端。 優點: 1、它能實現同一ip和埠的請求重用一個socket,這種方式能大大降低網路連線的時間,和每次請求都建立socket,再斷開socket的方式相比,降低了伺服器伺服器的壓力。 2、okhttp 對
MyBatis學習總結(九)---基於XML多表聯合查詢(一對一、一對多、多對多)
1、一對一的關聯 使用association,association元素用於處理“has-one”(一對一)這種型別關係。 作用:針對pojo物件屬性的對映,它的兩個主要引數此時對應的值: javaType對應pojo類名, property對應pojo的
Java併發程式設計:Synchronized底層優化(偏向鎖、輕量級鎖) Java併發程式設計:Synchronized底層優化(偏向鎖、輕量級鎖)
轉自:https://www.cnblogs.com/paddix/p/5405678.html Java併發程式設計:Synchronized底層優化(偏向鎖、輕量級鎖) Java併發程式設計系列: J
sklearn 學習實踐之——基於自帶資料集(波士頓房價、鳶尾花、糖尿病等)構建分類、迴歸模型
只要是接觸機器學習的,很少有沒聽過sklearn的,這個真的可以稱得上是機器學習快速進行的神器了,在研究生的時候搭建常用的機器學習模型用的就是sklearn,今天應部門的一些需求,簡單的總結了一點使用方法,後面還會繼續更新,今天僅使用sklearn自帶的資料
基於httpclient4.5.6實現ssl雙向訪問、單向訪問
1.引入包 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId>