开发手册 欢迎您!
软件开发者资料库

NHibernate - 批量大小

NHibernate批量大小 - 从概述,架构,Orm,环境设置,入门,基本Orm,基本Crud操作,Profiler,添加Intelliesnse到映射文件,数据类型映射,配置,覆盖配置,批量大小,缓存,映射来学习NHibernate组件,关系,集合映射,级联,延迟加载,反向关系,加载/获取,Linq,Hibernate查询语言,条件查询,QueryOver查询,本机Sql,流利Hibernate。

在本章中,我们将介绍批量大小更新.通过批量大小,您可以控制更新的数量,这些更新数量将在您的数据库的单次往返中用于支持的数据库.

  • 自NHibernate 3.2起,更新批量大小已默认.

  • 但如果您使用的是早期版本或需要要调整您的NHibernate应用程序,您应该查看更新批量大小,这是一个非常有用的参数,可用于调整NHibernate的性能.

  • 实际批处理size控制将组中推出的插入数量到数据库.

  • 目前,只有SQL Server和Oracle支持此选项,因为底层数据库提供程序需要支持查询批处理.

让我们看一个简单的例子,我们将批量大小设置为10一组中的10条记录.

cfg.DataBaseIntegration(x => {      x.ConnectionString = "default";    x.Driver();    x.Dialect();    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().List();                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进行插入和一次检索学生列表.

现在,为什么?原因是因为NHibernate需要执行选择范围标识,因为我们在ID的映射文件中使用本机标识符生成策略,如下面的代码所示.

                                                             

因此我们需要使用其他方法,例如 guid.comb 方法.如果我们要去guid.comb,我们需要转到我们的客户并将其更改为 guid .这样就可以了.现在让我们使用以下代码从native更改为guid.comb.

                                                       

所以这是负责生成这些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.

执行此查询然后转到 Designer查看,您将看到现在使用唯一标识符创建ID,如下图所示.

Designer View

现在我们需要在插入数据时从program.cs文件中删除ID,因为现在它将为它生成 guids 自动.

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();             x.Dialect();             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().List();               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 profiler Round Trips

它在表中插入了十行,然后是另外十行,后来是剩下的五行.在提交之后,它又插入了一个用于检索所有记录.

  • 所以它被分成十组,尽管它可以.

  • 因此,如果您正在进行大量插入操作,这可以显着提高应用程序中的插入性能,因为您可以批量处理

  • 这是因为NHibernate使用 guid.comb 算法分配这些guid本身,而且不需要依靠数据库来做到这一点.

  • 因此,使用批量大小是调整它的好方法.