歡迎光臨
每天分享高質量文章

[NewLife.XCode]物體類詳解

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版]

  1. 增刪改查入門。快速展現用法,代碼配置連接字串
  2. 資料模型檔案。建立表格欄位和索引,名字以及資料型別規範,推薦欄位(時間,用戶,IP)
  3. 物體類詳解。資料類業務類,泛型基類,接口
  4. 功能設置。連接字串,除錯開關,SQL日誌,慢日誌,引數化,執行超時。代碼與配置檔案設置,連接字串區域性設置
  5. 反向工程。自動建立資料庫資料表
  6. 資料初始化。InitData寫入初始化資料
  7. 高級增刪改。多載攔截,自增欄位,Valid驗證,物體模型(時間,用戶,IP)
  8. 臟資料。如何產生,怎麼利用
  9. 增量累加。高併發統計
  10. 事務處理。單表和多表,不同連接,多種寫法
  11. 擴展屬性。多表關聯,Map映射
  12. 高級查詢。複雜條件,分頁,自定義擴展FieldItem,查總記錄數,查彙總統計
  13. 資料層快取。Sql快取,更新機制
  14. 物體快取。全表整理快取,更新機制
  15. 物件快取。字典快取,適用用戶等資料較多場景。
  16. 百億級性能。欄位精煉,索引完備,合理查詢,充分利用快取
  17. 物體工廠。元資料,通用處理程式
  18. 角色權限。Membership
  19. 匯入匯出。Xml,Json,二進制,網絡或檔案
  20. 分表分庫。常見拆分邏輯
  21. 高級統計。聚合統計,分組統計
  22. 批量寫入。批量插入,批量Upsert,異步儲存
  23. 物體佇列。寫入級快取,提升性能。
  24. 備份同步。備份資料,恢復資料,同步資料
  25. 資料服務。提供RPC接口服務,遠程執行查詢,例如SQLite網絡版
  26. 大資料分析。ETL抽取,調度計算處理,結果持久化

 

受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可通過二維碼轉賬支持公眾號。

    赞(0)

    分享創造快樂