NewLife.XCode是一個有10多年曆史的開源資料中介軟體,由新生命團隊(2002~2019)開發完成並維護至今,以下簡稱XCode。
整個系列教程會大量結合示例程式碼和執行日誌來進行深入分析,蘊含多年開發經驗於其中。
開源地址:https://github.com/NewLifeX/X (求star, 620+)
回到目錄
生成物體類
上一章《資料模型》講到模型檔案Model.xml和指令碼Build.tt,(nuget安裝NewLife.XCode後即可擁有)。
把Build.tt和Model.xml(可改名)放在同一個目錄,在Build.tt上右鍵“執行自定義工具”,“顯示所有檔案”,即可看到生成的物體類檔案。
**如果執行Build.tt出錯,可能是因為找不到XCode.dll檔案,可以先編譯一次專案,讓XCode.dll生成到專案輸出目錄即可
我們來試試以下模型(複製到Model.xml裡面):
xml version="1.0" encoding="utf-8"?> <Tables Version="9.9.6940.24706" NameSpace="NewLife.School.Entity" ConnName="School" BaseClass="Entity" Output=""> <Table Name="Class" TableName="xxx_class" Description="班級" DbType="SqlServer"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="Name" ColumnName="xxx_Nameyyy" DataType="String" Master="True" Description="名稱" /> <Column Name="CreateUser" DataType="String" Description="建立者" /> <Column Name="CreateUserID" DataType="Int32" Description="建立者" /> <Column Name="CreateTime" DataType="DateTime" Description="建立時間" /> <Column Name="CreateIP" DataType="String" Description="建立地址" /> <Column Name="UpdateUser" DataType="String" Description="更新者" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新者" /> <Column Name="UpdateTime" DataType="DateTime" Description="更新時間" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="Remark" DataType="String" Length="200" Description="備註" /> Columns> Table> <Table Name="Student" Description="學生" DbType="SqlServer"> <Columns> <Column Name="ID" DataType="Int32" Identity="True" PrimaryKey="True" Description="編號" /> <Column Name="ClassID" DataType="Int32" Description="班級" /> <Column Name="Name" DataType="String" Master="True" Description="名稱" /> <Column Name="Sex" DataType="Int32" Description="性別" Type="XCode.Membership.SexKinds" /> <Column Name="Age" DataType="Int32" Description="年齡" /> <Column Name="Mobile" DataType="String" Description="手機" /> <Column Name="Address" DataType="String" Description="地址" /> <Column Name="CreateUserID" DataType="Int32" Description="建立者" /> <Column Name="CreateTime" DataType="DateTime" Description="建立時間" /> <Column Name="CreateIP" DataType="String" Description="建立地址" /> <Column Name="UpdateUserID" DataType="Int32" Description="更新者" /> <Column Name="UpdateTime" DataType="DateTime" Description="更新時間" /> <Column Name="UpdateIP" DataType="String" Description="更新地址" /> <Column Name="Remark" DataType="String" Length="200" Description="備註" /> Columns> <Indexes> <Index Columns="ClassID" /> Indexes> Table> Tables>
執行build.tt後
每個模型表,生成了四個物體類檔案,選中它們並包含到專案中。
其中Biz常稱之為業務類,多次build.tt生成不改寫;
另一個稱之為資料類,每次build.tt生成均改寫;
這裡採用了C#的分部類(partial)技術,一個類由兩個或多個類檔案組成。
資料類包含表名(類名)欄位名(屬性)等資訊,修改模型檔案後,每次生成都會改寫檔案。
業務類包含其它非表結構資訊,供開發者填寫程式碼,所以只有首次生成,而再次生成時不會改寫。
資料類包括一個介面(如IStudent),以滿足精簡需要的場合。
資料類內部還有兩個內嵌類_和__,可用於快速訪問欄位資訊以及屬性名。
回到目錄
物體靜態建構式
XCode是充血模型,因此物體類除了各個代表著表結構資訊的屬性外,還會有大量使用者程式碼在其中,並且繼承泛型物體基類(如Entity)。
一個常見的物體類建構式如下:
static User() { // 累加欄位 var df = Meta.Factory.AdditionalFields; df.Add(__.Logins); // 過濾器 UserModule、TimeModule、IPModule Meta.Modules.Add(); Meta.Modules.Add(); Meta.Modules.Add(); // 單物件快取 var sc = Meta.SingleCache; sc.FindSlaveKeyMethod = k => Find(__.Name, k); sc.GetSlaveKeyMethod = e => e.Name; }
這裡首先介紹一個最重要的物體類內嵌類Meta,它位於Entity.Meta,記錄著物體類的一切元資料,承載著物體類的一切高階功能!
Meta.Factory.AdditionalFields用於存放累加欄位
一般更新陳述句 update user set Logins=123 where id=1,而把Logins欄位設為累加欄位後,將得到 update user set Logins=Logins+33 where id=1 ,特別適用於併發更新同一行記錄的場合。
物體過濾器EntityModule,用於攔截物體類的添刪改操作,內建最常用的3個過濾器UserModule/TimeModule/IPModule
上一章末尾推薦的8個常用欄位還記得嗎? CreateUser/CreateTime/CreateIP 等,所有CreateAbc將在Insert的時候攔截賦值,所有UpdateAbc將在Insert和Update的時候攔截賦值。
UserModule取當前登入使用者,由ManageProvider驅動;
TimeModule取當前時間;
IPModule取當前訪問IP,由ManageProvider.UserHost提供;
快取配置
單物件快取是一個字典快取,預設以主鍵為key,物體物件為value。
單物件快取支援第二個字典,如上,配置Name為第二字典的主鍵,物體物件為value。
物體基類
當然,物體類靜態建構式還可以用於其它用途,它將會在使用該物體類任意方法(包括成員方法和靜態方法)之前執行。
有時候把一個系統模組放到一個獨立子目錄裡面,獨享一個“Abc.xml”模型檔案,生成的物體類在目錄裡面,這個時候可以讓它們繼承一個相同的物體基類(如EntityBase)。
然後在物體基類EntityBase的靜態建構式中寫入這個模組所共有的程式碼。
回到目錄
初始化資料
有些資料表需要預設初始化一些資料,如類別表、配置表等,便於開發測試。
這個時候可以多載InitData方法,它會在物體類第一次訪問資料庫之前執行。
這裡遇到Meta的第二次用法Meta.Count,該屬性表示當前物體類資料表的總行數。
當總行數在100萬以內時,數字精確等於 select count(*) from table,大於100萬時,將採用特有的快速方法。
Meta.Count帶快取,擁有極好的效能,可用於粗略(數值較小時精確)估算該表總行數。
這裡透過Meta.Count來判斷該表是否為空表,然後對空表插入一些預設資料。
回到目錄
資料驗證Valid
每個物體類在Insert/Update之前,都需要Valid驗證資料 ,引數isNew以區分Insert。
Valid常常可用於判斷主要欄位的有效性,無效時強烈推薦丟擲引數類異常,魔方NewLife.Cube表單將可以捕獲並定位。
除此之外,Valid用得更多的功能是在Insert/Update之前修改完善欄位資料,例如上面對密碼進行MD5雜湊,以及格式化RoleIDs。
這裡出現新技術,IsDirty和Dirtys,這是XCode的臟資料,前者判斷Password欄位是否有臟資料(Password被賦予跟原來不想等的值),後者清空Password臟資料。
臟資料是生成Update陳述句的核心,不髒的欄位不會出現在update set 之中,實現部分欄位更新,後續有專門章節講解。
回到目錄
多載添刪改
物體類的添刪改操作都可以多載(Insert/Update/Delete/OnInsert/OnUpdate/OnDelete)
多載後可以做業務程式碼判斷,也可以級聯更新其它表,還可以記錄添刪改操作日誌,甚至還可以做假刪除(多載OnDelete然後實際執行OnUpdate)
分為兩組多載,實際執行順序是:Insert=>Valid=>EntityModule=>OnInsert
回到目錄
擴充套件屬性
XCode不支援多表關聯Join,取而代之的是擴充套件屬性!
擴充套件屬性的意義,用到該屬性時,再去查詢相應資料,一般標的錶帶有快取,並且擴充套件屬性Extends也有快取
一般擴充套件屬性複雜物件加上XmlIgnore和ScriptIgnore特性,規避Xml序列化和Json序列化。
常常還會加上 AbcName 這樣的字串型屬性,頭上的Map特性將在魔方NewLife.Cube展現資料時發揮極大作用。
__.ClassID表示對映到該欄位,在所有顯示ClassID的地方用當前屬性ClassName替代;
後面的類名和欄位名,表示要關聯的標的表和欄位,在魔方Cube表單中將直接生成下拉選擇;
回到目錄
擴充套件查詢
實際業務中經常會用到根據某一兩個欄位查詢的需求,例如根據主鍵查詢。
一般我們把查詢傳回單個物件的方法命名為 FindByAbc,而把傳回多個物體的方法命名為 FindAllByAbc。
上面的程式碼展示了3種查詢方法:
透過Meta.Count判斷,當總行數小於1000時,全部走Meta.Cache物體快取運算式搜尋,其原理是整表一次性載入記憶體,後續有專門文章介紹;
FindByID和FindByName,當總數大於1000時,走物件快取Meta.SingleCache,按主鍵ID/Name為鍵,快取物體物件;
不常用的FindByMail和FindAllByClassID中,用到了真正的資料庫查詢 Find(__.Mail, mail) 和 FindAll(_.ClassID == classid);
預設生成的程式碼,都帶有物體快取和物件快取的例子,預設情況下,FindByID只需要查一次資料並載入記憶體,即可實現“極速查詢”,後續每10秒非同步更新。
顯然,如果完全不需要用到快取,直接寫資料庫程式碼就好了。
回到目錄
高階查詢
在業務實現中經常出現超過兩個甚至更多查詢條件,這個時候我們推薦Search或SearchAbc
XCode的查詢有一套條件運算式,以WhereExpression為代表,可以動態拼接任意複雜的where查詢陳述句。
FindAll常用兩個引數,第一個條件,第二個PageParameter實現分頁查詢。
至此,簡單羅列了物體類的主要構成,具體各個構成部分都將會在後面有專題文章介紹。
回到目錄
系列教程
NewLife.XCode教程系列[2019版]
- 增刪改查入門。快速展現用法,程式碼配置連線字串
- 資料模型檔案。建立表格欄位和索引,名字以及資料型別規範,推薦欄位(時間,使用者,IP)
- 物體類詳解。資料類業務類,泛型基類,介面
- 功能設定。連線字串,除錯開關,SQL日誌,慢日誌,引數化,執行超時。程式碼與配置檔案設定,連線字串區域性設定
- 反向工程。自動建立資料庫資料表
- 資料初始化。InitData寫入初始化資料
- 高階增刪改。多載攔截,自增欄位,Valid驗證,物體模型(時間,使用者,IP)
- 臟資料。如何產生,怎麼利用
- 增量累加。高併發統計
- 事務處理。單表和多表,不同連線,多種寫法
- 擴充套件屬性。多表關聯,Map對映
- 高階查詢。複雜條件,分頁,自定義擴充套件FieldItem,查總記錄數,查彙總統計
- 資料層快取。Sql快取,更新機制
- 物體快取。全表整理快取,更新機制
- 物件快取。字典快取,適用使用者等資料較多場景。
- 百億級效能。欄位精煉,索引完備,合理查詢,充分利用快取
- 物體工廠。元資料,通用處理程式
- 角色許可權。Membership
- 匯入匯出。Xml,Json,二進位制,網路或檔案
- 分表分庫。常見拆分邏輯
- 高階統計。聚合統計,分組統計
- 批次寫入。批次插入,批次Upsert,非同步儲存
- 物體佇列。寫入級快取,提升效能。
- 備份同步。備份資料,恢復資料,同步資料
- 資料服務。提供RPC介面服務,遠端執行查詢,例如SQLite網路版
- 大資料分析。ETL抽取,排程計算處理,結果持久化
受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可透過二維碼轉賬支援公眾號。