[NewLife.XCode]增刪改查入門
NewLife.XCode是一個有15年歷史的開源數據中間件,支持netcore/net45/net40,由新生命團隊(2002~2019)開發完成并維護至今,以下簡稱XCode。
整個系列教程會大量結合示例代碼和運行日志來進行深入分析,蘊含多年開發經驗于其中,代表作有百億級大數據實時計算項目。
開源地址:https://github.com/NewLifeX/X (求star, 620+)
增刪改查入門
新建控制臺項目(.NET Core),從nuget引用NewLife.XCode,(也可以從別的項目引用下載后拷貝XCode.dll和NewLife.Core.dll來使用,區分nfx和netcore版本),敲入以下代碼
// 啟用控制臺日志 XTrace.UseConsole(); // 添加 var user = new UserX { Name = "大石頭", Enable = true }; user.Insert(); // 自增字段user.ID已經取得值 XTrace.WriteLine("用戶ID:{0}", user.ID); // 查詢 var user2 = UserX.Find(UserX._.Name == "大石頭"); // 更新 user2.Logins++; user2.LastLogin = DateTime.Now; user2.Update(); // 刪除 var user3 = UserX.FindByID(user.ID); user3.Delete(); Console.ReadLine();
先跑起來看看效果:
#Software: ConsoleApp4 #ProcessID: 21252 x64 #AppDomain: ConsoleApp4 #FileName: C:\Program Files\dotnet\dotnet.exe #BaseDirectory: D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\ #CommandLine: D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\ConsoleApp4.dll #ApplicationType: Console #CLR: 4.0.30319.42000, #OS: Microsoft Windows NT 6.2.9200.0, X3/Stone #CPU: 8 #GC: IsServerGC=False, LatencyMode=Interactive #Date: 2019-02-25 #字段: 時間 線程ID 線程池Y網頁W普通N 線程名 消息內容 #Fields: Time ThreadID IsPoolThread ThreadName Message 22:57:13.089 1 N - NewLife.Core v8.0.2019.0101 Build 2019-01-26 23:22:36 22:57:13.104 1 N - 新生命X組件核心庫 ?2002-2019 新生命開發團隊 22:57:13.114 1 N - ConsoleApp4 v1.0.0.0 Build 2000-01-01 22:57:13.115 1 N - ConsoleApp4 22:57:13.115 1 N - Setting的配置文件Config\Core.config 不存在,準備用默認配置覆蓋! 22:57:13.277 1 N - Setting的配置文件Config\XCode.config 不存在,準備用默認配置覆蓋! 22:57:13.282 1 N - XCode v9.10.2019.0101 Build 2019-01-26 23:22:38 22:57:13.282 1 N - 數據中間件 ?2002-2019 新生命開發團隊 22:57:13.628 1 N - 自動為[Membership]設置SQLite連接字符串:Data Source=.\Membership.db;Migration=On 22:57:13.652 1 N - System.Data.SQLite.dll不存在或平臺版本不正確,準備聯網獲取 http://x.newlifex.com/ 22:57:13.835 1 N - 下載鏈接 http://x.newlifex.com/,目標 System.Data.SQLite.win-x64,System.Data.SQLite.win,System.Data.SQLite.st,System.Data.SQLite 22:57:13.964 4 Y 1 WebClientX.Get http://x.newlifex.com/ 22:57:15.660 1 N - 分析得到文件 System.Data.SQLite.win-x64_20180823112512.zip,準備下載 http://x.newlifex.com/System.Data.SQLite.win-x64_20180823112512.zip 22:57:15.663 4 Y 19 WebClientX.Get http://x.newlifex.com/System.Data.SQLite.win-x64_20180823112512.zip 22:57:16.897 1 N - 下載完成,共924,475字節,耗時1,232毫秒 22:57:16.897 1 N - 解壓縮到 D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Plugins 22:57:17.074 1 N - TypeX.GetType("System.Data.SQLite.SQLiteFactory") => Plugins\System.Data.SQLite.dll 22:57:17.074 1 N - System.Data.SQLite驅動D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Plugins\System.Data.SQLite.dll 版本v1.0.109.0 22:57:17.145 1 N - Data Source=D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Membership.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 22:57:17.154 4 Y 198 檢查實體XCode.Membership.UserX的數據表架構,模式:CheckTableWhenFirstUse 22:57:17.160 4 Y 198 創建數據庫:Membership 22:57:17.161 4 Y 198 創建數據庫:D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Membership.db 22:57:17.181 4 Y 198 select * from sqlite_master 22:57:17.284 4 Y 198 創建表:User(用戶) 22:57:17.298 4 Y 198 Create Table User( ID integer Primary Key AUTOINCREMENT, Name nvarchar(50) NOT NULL COLLATE NOCASE, Password nvarchar(50) NULL COLLATE NOCASE, DisplayName nvarchar(50) NULL COLLATE NOCASE, Sex int NOT NULL, Mail nvarchar(50) NULL COLLATE NOCASE, Mobile nvarchar(50) NULL COLLATE NOCASE, Code nvarchar(50) NULL COLLATE NOCASE, Avatar nvarchar(200) NULL COLLATE NOCASE, RoleID int NOT NULL, RoleIDs nvarchar(200) NULL COLLATE NOCASE, DepartmentID int NOT NULL, Online bit NOT NULL, Enab...etime NULL, LastLoginIP nvarchar(50) NULL COLLATE NOCASE, RegisterTime datetime NULL, RegisterIP nvarchar(50) NULL COLLATE NOCASE, Ex1 int NOT NULL, Ex2 int NOT NULL, Ex3 real NOT NULL, Ex4 nvarchar(50) NULL COLLATE NOCASE, Ex5 nvarchar(50) NULL COLLATE NOCASE, Ex6 nvarchar(50) NULL COLLATE NOCASE, UpdateUser nvarchar(50) NULL COLLATE NOCASE, UpdateUserID int NOT NULL, UpdateIP nvarchar(50) NULL COLLATE NOCASE, UpdateTime datetime NULL, Remark nvarchar(200) NULL COLLATE NOCASE ) 22:57:17.309 4 Y 198 Create Unique Index IU_User_Name On User (Name) 22:57:17.311 4 Y 198 Create Index IX_User_RoleID On User (RoleID) 22:57:17.312 4 Y 198 Create Index IX_User_UpdateTime On User (UpdateTime) 22:57:17.320 4 Y 198 UserX.Count 快速計算表記錄數(非精確)[User/Membership] 參考值 -2 22:57:17.332 4 Y 198 開始檢查連接[Membership/SQLite]的數據庫架構…… 22:57:17.355 4 Y 198 [Membership]的所有實體類(5個):Parameter,UserX,Menu,Role,Department 22:57:17.356 4 Y 198 [Membership]需要檢查架構的實體類(1個):Parameter 22:57:17.357 4 Y 198 Membership待檢查表架構的實體個數:1 22:57:17.358 4 Y 198 select * from sqlite_master 22:57:17.365 4 Y 198 創建表:Parameter(字典參數) 22:57:17.368 4 Y 198 Create Table Parameter( ID integer Primary Key AUTOINCREMENT, Category nvarchar(50) NULL COLLATE NOCASE, Name nvarchar(50) NULL COLLATE NOCASE, Value nvarchar(200) NULL COLLATE NOCASE, LongValue nvarchar(2000) NULL COLLATE NOCASE, Kind int NOT NULL, Enable bit NOT NULL, Ex1 int NOT NULL, Ex2 int NOT NULL, Ex3 real NOT NULL, Ex4 nvarchar(50) NULL COLLATE NOCASE, Ex5 nvarchar(50) NULL COLLATE NOCASE, Ex6 nvarchar(50) NULL COLLATE NOCASE, CreateUser nvarchar(50) NULL COLLATE NOCASE, CreateUserID int NOT NULL, CreateIP nvarchar(50) NULL COLLATE NOCASE, CreateTime datetime NULL, UpdateUser nvarchar(50) NULL COLLATE NOCASE, UpdateUserID int NOT NULL, UpdateIP nvarchar(50) NULL COLLATE NOCASE, UpdateTime datetime NULL, Remark nvarchar(200) NULL COLLATE NOCASE ) 22:57:17.369 4 Y 198 Create Unique Index IU_Parameter_Category_Name On Parameter (Category, Name) 22:57:17.370 4 Y 198 Create Index IX_Parameter_Name On Parameter (Name) 22:57:17.370 4 Y 198 Create Index IX_Parameter_UpdateTime On Parameter (UpdateTime) 22:57:17.372 4 Y 198 檢查連接[Membership/SQLite]的數據庫架構耗時38ms 22:57:17.383 4 Y 198 Select * From User Order By ID Desc limit 1 22:57:17.388 4 Y 198 Select Count(*) From User 22:57:17.398 4 Y 198 Select Count(*) From User 22:57:17.401 4 Y 198 開始初始化UserX用戶數據…… 22:57:17.455 4 Y 198 Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('admin', '21232F297A57A5A743894A0E4A801FC3', '管理員', 0, null, null, null, null, 1, '', 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.479 4 Y 198 自動為[Log]設置SQLite連接字符串:Data Source=.\Log.db;Migration=On 22:57:17.491 4 Y 198 Data Source=D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Log.db;Cache Size=-524288;Synchronous=Off;Journal Mode=WAL 22:57:17.514 4 Y 198 完成初始化UserX用戶數據! 22:57:17.548 1 N - Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('大石頭', null, null, 0, null, null, null, null, 0, null, 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.561 1 N - 用戶ID:2 22:57:17.574 1 N - Select * From User Where Name='大石頭' Order By ID Desc limit 1 22:57:17.601 1 N - Update User Set Logins=Logins+1, LastLogin='2019-02-25 22:57:17' Where ID=2 22:57:17.613 1 N - Select * From User Order By ID Desc 22:57:17.620 1 N - Delete From User Where ID=2 22:57:18.519 6 Y 199 檢查實體XCode.Membership.Log的數據表架構,模式:CheckTableWhenFirstUse 22:57:18.520 6 Y 199 創建數據庫:Log 22:57:18.521 6 Y 199 創建數據庫:D:\Test\ConsoleApp4\ConsoleApp4\bin\Debug\netcoreapp2.1\Log.db 22:57:18.532 6 Y 199 創建表:Log(日志) 22:57:18.537 4 Y EQ 開始檢查連接[Log/SQLite]的數據庫架構…… 22:57:18.555 4 Y EQ [Log]的所有實體類(3個):Log,UserOnline,VisitStat 22:57:18.555 4 Y EQ [Log]需要檢查架構的實體類(2個):UserOnline,VisitStat 22:57:18.558 4 Y EQ Log待檢查表架構的實體個數:2 22:57:18.559 4 Y EQ 創建表:UserOnline(用戶在線) 22:57:18.561 4 Y EQ 創建表:VisitStat(訪問統計) 22:57:18.564 4 Y EQ 檢查連接[Log/SQLite]的數據庫架構耗時24ms
這是前述代碼的完整執行日志,這里我們不做過多分析。
日志大意是:自動配置SQLite數據庫,下載平臺要求的SQLite驅動,建庫建表,增刪改查
這里特別需要關注的是這幾行:
22:57:17.548 1 N - Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('大石頭', null, null, 0, null, null, null, null, 0, null, 0, 0, 1, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid 22:57:17.561 1 N - 用戶ID:2 22:57:17.574 1 N - Select * From User Where Name='大石頭' Order By ID Desc limit 1 22:57:17.601 1 N - Update User Set Logins=Logins+1, LastLogin='2019-02-25 22:57:17' Where ID=2 22:57:17.613 1 N - Select * From User Order By ID Desc 22:57:17.620 1 N - Delete From User Where ID=2
一句user.Insert,生成了一個Insert Into語句,并取得自增字段賦值給ID。
一個簡單的Find單字段查找,通過user2.Update更新了兩個字段,user3.Delete則刪除了這行數據。
這就是一個完整的增刪改查!
短短的一段代碼,也許帶給你許多疑問,這些疑問都將在后續文章中得到詳細解答:
- UserX類來自哪里?(XCode內置權限體系Membership)
- 為何不需要配置數據庫?(無配置時默認使用SQLite)
- 下載了什么東西?(SQLite驅動分為.Net2.0/.Net4.0/.Net4.5等,還有.netstandard以及Linux版本之分,XCode根據平臺自動下載正確版本)
- 為何會自動建表?(這是XCode最為強大的反向工程,2008年開始支持,類似于EF后來的數據遷移)
- 自增ID。Insert后會即刻取回新插入的自增值
- Logins=Logins+1。這叫做累加字段
- UserX.FindByID為何生成不帶where的Select查詢?(UserX.FindByID內部帶有實體緩存,并非簡單的Find(ID==2))
數據訪問層DAL
整個XCode明確分隔為上下兩層(實體層Entity和數據訪問層DAL),前面介紹了實體層添刪改查。
由于XCode只支持單表查詢,存在不支持多表Join等制約,有時候不得不直接寫SQL來解決問題(特別是新手)。
實體層的所有添刪改查操作,本質上都是根據目標連接數據庫類型來生成不同的SQL語句,交給數據訪問層DAL執行。
顯然,可以越過實體層,直接操作數據訪問層DAL。
DAL是單例模式,只有一個獲取辦法 DAL.Create(connName),每個連接名對應一個DAL對象。
(少數同學習慣把連接字符串當作連接名connName傳遞給DAL.Create)
DAL基本數據操作:
- DataSet Select(sql)。根據指定sql查詢得到DataSet,這就是標準的DbHelper必備
- DbTable Query(sql)。根據指定sql查詢得到DbTable,這是XCode自定義內存數據表,比DataTable更輕量級,并易于網絡傳輸以及保存二進制文件
- Int32 SelectCount(sql)。滿足指定sql的總行數,常用于分頁,或者判斷指定主鍵的數據是否存在
- Int32 Execute(sql)。執行添刪改查操作,或者執行存儲過程
- Int32 InsertAndGetIdentity(sql)。執行插入并取得自增數字
很多人問過,XCode怎么做多表關聯查詢?
var dal=DAL.Creat("member"); var db=dal.Query("select a.*, b.* from member a left join department b on a.did=b.id where enable=1"); var list=Member.LoadData(db);
這是一個典型多表Join,可以借助DAL.Query實現查詢,然后通過實體類的LoadData方法,把結果集映射為實體列表。
數據結果集DataSet/DbTable理論上可以LoadData映射到任意實體類,只填充實體類中存在的字段,不存在的字段則把數據存放在實體對象的擴展屬性Extends中。
什么時候使用數據訪問層?
- 需要進行多表Join等復雜查詢
- 只需要偶爾查詢或寫入數據,不想生成實體類
- 方便遷移舊版DbHelper代碼
系列教程
NewLife.XCode教程系列[2019版]
- 增刪改查入門。快速展現用法,代碼配置連接字符串
- 數據模型文件。建立表格字段和索引,名字以及數據類型規范,推薦字段(時間,用戶,IP)
- 實體類詳解。數據類業務類,泛型基類,接口
- 功能設置。連接字符串,調試開關,SQL日志,慢日志,參數化,執行超時。代碼與配置文件設置,連接字符串局部設置
- 反向工程。自動建立數據庫數據表
- 數據初始化。InitData寫入初始化數據
- 高級增刪改。重載攔截,自增字段,Valid驗證,實體模型(時間,用戶,IP)
- 臟數據。如何產生,怎么利用
- 增量累加。高并發統計
- 事務處理。單表和多表,不同連接,多種寫法
- 擴展屬性。多表關聯,Map映射
- 高級查詢。復雜條件,分頁,自定義擴展FieldItem,查總記錄數,查匯總統計
- 數據層緩存。Sql緩存,更新機制
- 實體緩存。全表整理緩存,更新機制
- 對象緩存。字典緩存,適用用戶等數據較多場景。
- 百億級性能。字段精煉,索引完備,合理查詢,充分利用緩存
- 實體工廠。元數據,通用處理程序
- 角色權限。Membership
- 導入導出。Xml,Json,二進制,網絡或文件
- 分表分庫。常見拆分邏輯
- 高級統計。聚合統計,分組統計
- 批量寫入。批量插入,批量Upsert,異步保存
- 實體隊列。寫入級緩存,提升性能。
- 備份同步。備份數據,恢復數據,同步數據
- 數據服務。提供RPC接口服務,遠程執行查詢,例如SQLite網絡版
- 大數據分析。ETL抽取,調度計算處理,結果持久化
End.

浙公網安備 33010602011771號