NHibernate - Kích thước lô
Trong chương này, chúng tôi sẽ đề cập đến cập nhật kích thước hàng loạt. Kích thước lô cho phép bạncontrol the number of updates đi một vòng đến cơ sở dữ liệu của bạn để biết các cơ sở dữ liệu được hỗ trợ.
Kích thước lô cập nhật đã được đặt mặc định kể từ NHibernate 3.2.
Nhưng nếu bạn đang sử dụng phiên bản cũ hơn hoặc cần điều chỉnh ứng dụng NHibernate của mình, bạn nên xem kích thước lô cập nhật, đây là một tham số rất hữu ích có thể được sử dụng để điều chỉnh hiệu suất của NHibernate.
Trên thực tế, kích thước hàng loạt kiểm soát số lượng chèn để đẩy ra trong một nhóm vào cơ sở dữ liệu.
Hiện tại, chỉ SQL Server và Oracle hỗ trợ tùy chọn này vì nhà cung cấp cơ sở dữ liệu bên dưới cần hỗ trợ nhóm truy vấn.
Hãy xem xét một ví dụ đơn giản, trong đó chúng tôi đã đặt kích thước lô thành 10 sẽ chèn 10 bản ghi trong một tập hợp.
cfg.DataBaseIntegration(x => {
x.ConnectionString = "default";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.LogSqlInConsole = true;
x.BatchSize = 10;
});
Đây là phần thực hiện hoàn chỉnh, trong đó 25 bản ghi sẽ được thêm vào cơ sở dữ liệu.
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();
}
}
}
}
Bây giờ hãy chạy ứng dụng của bạn và bạn thấy tất cả các bản cập nhật đó đang chuyển sang hồ sơ NHibernate. Chúng tôi có 26 chuyến đi vòng quanh cơ sở dữ liệu 25 để chèn và một lần truy xuất danh sách học sinh.
Bây giờ, tại sao lại như vậy? Lý do là vì NHibernate cần làm mộtselect scope identity vì chúng tôi đang sử dụng chiến lược tạo mã nhận dạng gốc trong tệp ánh xạ cho ID như được hiển thị trong mã sau.
<?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>
Vì vậy, chúng ta cần sử dụng một phương pháp khác, chẳng hạn như guid.combphương pháp. Nếu chúng ta đi đến Guid.comb, chúng ta cần phải chuyển đến khách hàng của mình và thay đổi nó thànhguid. Vì vậy, điều đó sẽ hoạt động tốt. Bây giờ chúng ta hãy thay đổi từ gốc thành Guid.comb bằng cách sử dụng mã sau.
<?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>
Vì vậy, đó là cơ sở dữ liệu chịu trách nhiệm tạo ra các ID đó. Cách duy nhất NHibernate có thể tìm ra ID đã được tạo là chọn nó ngay sau đó. Hoặc nếu chúng tôi đã tạo một loạt sinh viên, nó sẽ không thể khớp với ID của sinh viên đã được tạo.
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
}
}
Chúng tôi chỉ cần cập nhật cơ sở dữ liệu của mình. Hãy thả bảng sinh viên và tạo một bảng mới bằng cách chỉ định truy vấn sau, vì vậy hãy truy cập SQL Server Object Explorer và nhấp chuột phải vào cơ sở dữ liệu và chọnNew Query… Lựa chọn.
Nó sẽ mở trình soạn thảo truy vấn và sau đó chỉ định truy vấn sau.
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)
);
Truy vấn này trước tiên sẽ xóa bảng sinh viên hiện có và sau đó tạo một bảng mới. Như bạn có thể thấy rằng chúng tôi đã sử dụngUNIQUEIDENTIFIER thay vì sử dụng khóa chính số nguyên làm ID.
Thực hiện truy vấn này và sau đó đi đến Designer view và bạn sẽ thấy rằng bây giờ ID được tạo với một mã định danh duy nhất như được hiển thị trong hình sau.
Bây giờ chúng ta cần xóa ID khỏi tệp program.cs trong khi chèn dữ liệu, vì bây giờ nó sẽ tạo guids cho nó tự động.
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();
}
}
}
}
Bây giờ hãy chạy lại ứng dụng và xem hồ sơ NHibernate. Giờ đây, hồ sơ NHibernate thay vì thực hiện 26 chuyến khứ hồi sẽ chỉ tạo ra bốn chuyến.
Nó được chèn mười hàng vào bảng, sau đó là mười hàng khác, và sau đó là năm hàng còn lại. Và sau khi commit, nó đã chèn thêm một cái nữa để lấy tất cả các bản ghi.
Vì vậy, nó chia nó thành các nhóm mười, tốt nhất có thể.
Vì vậy, nếu bạn đang thực hiện nhiều lần chèn, điều này có thể cải thiện đáng kể hiệu suất chèn trong ứng dụng của bạn, vì bạn có thể bổ sung hàng loạt.
Điều này là do NHibernate tự chỉ định các guids đó bằng cách sử dụng guid.comb thuật toán và nó không cần phải dựa vào cơ sở dữ liệu để làm điều này.
Vì vậy, sử dụng kích thước lô là một cách tuyệt vời để điều chỉnh nó.