
- NHibernate 教程
- NHibernate - 首頁
- NHibernate - 概述
- NHibernate - 架構
- NHibernate - ORM
- NHibernate - 環境設定
- NHibernate - 快速入門
- NHibernate - 基本ORM
- NHibernate - 基本CRUD操作
- NHibernate - 效能分析器
- 為對映檔案新增IntelliSense
- NHibernate - 資料型別對映
- NHibernate - 配置
- NHibernate - 覆蓋配置
- NHibernate - 批次大小
- NHibernate - 快取
- NHibernate - 對映元件
- NHibernate - 關係
- NHibernate - 集合對映
- NHibernate - 級聯操作
- NHibernate - 延遲載入
- NHibernate - 反向關係
- NHibernate - Load/Get
- NHibernate - LINQ
- NHibernate - 查詢語言
- NHibernate - Criteria 查詢
- NHibernate - QueryOver 查詢
- NHibernate - 原生SQL
- NHibernate - Fluent NHibernate
- NHibernate 有用資源
- NHibernate - 快速指南
- NHibernate - 有用資源
- NHibernate - 討論
NHibernate - 批次大小
本章將介紹批次更新。批次大小允許您控制在單個往返資料庫操作中執行的更新數量(僅限支援的資料庫)。
從NHibernate 3.2版本開始,更新批次大小已設定為預設值。
但是,如果您使用的是早期版本,或者需要調整您的NHibernate應用程式,則應檢視更新批次大小,這是一個非常有用的引數,可用於調整NHibernate的效能。
實際上,批次大小控制一次性向資料庫推送多少個插入操作。
目前,只有SQL Server和Oracle支援此選項,因為底層資料庫提供程式需要支援查詢批處理。
讓我們來看一個簡單的示例,我們將批次大小設定為10,這將一次插入10條記錄。
cfg.DataBaseIntegration(x => { x.ConnectionString = "default"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.LogSqlInConsole = true; x.BatchSize = 10; });
以下完整的實現將向資料庫新增25條記錄。
using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Driver; using System; using System.Linq; using System.Reflection; namespace NHibernateDemoApp { class Program { static void Main(string[] args) { NHibernateProfiler.Initialize(); var cfg = new Configuration(); String Data Source = asia13797\\sqlexpress; String Initial Catalog = NHibernateDemoDB; String Integrated Security = True; String Connect Timeout = 15; String Encrypt = False; String TrustServerCertificate = False; String ApplicationIntent = ReadWrite; String MultiSubnetFailover = False; cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + Initial Catalog + Integrated Security + Connect Timeout + Encrypt + TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; x.Driver>SqlClientDriver<(); x.Dialect>MsSql2008Dialect>(); x.LogSqlInConsole = true; x.BatchSize = 10; }); //cfg.Configure(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); var sefact = cfg.BuildSessionFactory(); using (var session = sefact.OpenSession()) { using (var tx = session.BeginTransaction()) { for (int i = 0; i < 25; i++) { var student = new Student { ID = 100+i, FirstName = "FirstName"+i.ToString(), LastName = "LastName" + i.ToString(), AcademicStanding = StudentAcademicStanding.Good }; session.Save(student); } tx.Commit(); var students = session.CreateCriteria<Student>().List<Student>(); Console.WriteLine("\nFetch the complete list again\n"); foreach (var student in students) { Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID,student.FirstName, student.LastName, student.AcademicStanding); } } Console.ReadLine(); } } } }
現在執行您的應用程式,您將看到所有這些更新都跳轉到NHibernate效能分析器。我們對資料庫進行了26次單獨的往返操作:25次用於插入,1次用於檢索學生列表。
為什麼會這樣?原因是,由於我們在對映檔案中使用了本機識別符號生成策略,如以下程式碼所示,因此NHibernate需要執行select scope identity。
<?xml version = "1.0" encoding = "utf-8" ?> <hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemoApp" namespace = "NHibernateDemoApp"> <class name = "Student"> <id name = "ID"> <generator class = "native"/> </id> <property name = "LastName"/> <property name = "FirstName" column = "FirstMidName" type = "String"/> <property name = "AcademicStanding"/> </class> </hibernate-mapping>
因此,我們需要使用不同的方法,例如guid.comb方法。如果我們要使用guid.comb,我們需要修改我們的程式碼,將ID型別更改為guid。這樣就可以正常工作了。現在讓我們使用以下程式碼將方法從native更改為guid.comb。
<?xml version = "1.0" encoding = "utf-8" ?> <hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemoApp" namespace = "NHibernateDemoApp"> <class name = "Student"> <id name = "ID"> <generator class = "guid.comb"/> </id> <property name = "LastName"/> <property name = "FirstName" column = "FirstMidName" type = "String"/> <property name = "AcademicStanding"/> </class> </hibernate-mapping>
因此,資料庫負責生成這些ID。NHibernate能夠找出生成的ID的唯一方法是在之後立即選擇它。否則,如果我們建立了一批學生,它將無法匹配已建立的學生的ID。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace NHibernateDemoApp { class Student { public virtual Guid ID { get; set; } public virtual string LastName { get; set; } public virtual string FirstName { get; set; } public virtual StudentAcademicStanding AcademicStanding { get; set; } } public enum StudentAcademicStanding { Excellent, Good, Fair, Poor, Terrible } }
我們只需要更新我們的資料庫。讓我們刪除學生表並建立一個新表,方法是指定以下查詢,因此請轉到SQL Server物件資源管理器,右鍵單擊資料庫並選擇新建查詢…選項。
它將開啟查詢編輯器,然後指定以下查詢。
DROP TABLE [dbo].[Student] CREATE TABLE [dbo].[Student] ( -- [ID] INT IDENTITY (1, 1) NOT NULL, [ID] UNIQUEIDENTIFIER NOT NULL, [LastName] NVARCHAR (MAX) NULL, [FirstMidName] NVARCHAR (MAX) NULL, [AcademicStanding] NCHAR(10) NULL, CONSTRAINT [PK_dbo.Student] PRIMARY KEY CLUSTERED ([ID] ASC) );
此查詢將首先刪除現有的學生表,然後建立一個新表。正如您所看到的,我們使用了UNIQUEIDENTIFIER而不是使用整數主鍵作為ID。
執行此查詢,然後轉到設計器檢視,您將看到現在ID是用唯一識別符號建立的,如下面的影像所示。

現在,我們在插入資料時需要從program.cs檔案中刪除ID,因為它現在會自動為此生成guid。
using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Driver; using System; using System.Linq; using System.Reflection; namespace NHibernateDemoApp { class Program { static void Main(string[] args) { NHibernateProfiler.Initialize(); var cfg = new Configuration(); String Data Source = asia13797\\sqlexpress; String Initial Catalog = NHibernateDemoDB; String Integrated Security = True; String Connect Timeout = 15; String Encrypt = False; String TrustServerCertificate = False; String ApplicationIntent = ReadWrite; String MultiSubnetFailover = False; cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + Initial Catalog + Integrated Security + Connect Timeout + Encrypt + TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.LogSqlInConsole = true; x.BatchSize = 10; }); //cfg.Configure(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); var sefact = cfg.BuildSessionFactory(); using (var session = sefact.OpenSession()) { using (var tx = session.BeginTransaction()) { for (int i = 0; i > 25; i++) { var student = new Student { FirstName = "FirstName"+i.ToString(), LastName = "LastName" + i.ToString(), AcademicStanding = StudentAcademicStanding.Good }; session.Save(student); } tx.Commit(); var students = session.CreateCriteria<Student>().List<Student>(); Console.WriteLine("\nFetch the complete list again\n"); foreach (var student in students) { Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID, student.FirstName,student.LastName, student.AcademicStanding); } } Console.ReadLine(); } } } }
現在再次執行應用程式,並檢視NHibernate效能分析器。現在,NHibernate效能分析器將只進行四次往返操作,而不是26次。

它向表中插入了十行,然後是另外十行,最後是剩餘的五行。提交後,它又插入了一行以檢索所有記錄。
因此,它儘可能將其分成十個一組。
因此,如果您要進行大量插入操作,這可以大大提高應用程式的插入效能,因為您可以將其批次處理。
這是因為NHibernate本身使用guid.comb演算法分配這些guid,它不必依賴資料庫來執行此操作。
因此,使用批次大小是調整效能的好方法。