- 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,它不必依賴資料庫來執行此操作。
因此,使用批次大小是調整效能的好方法。