NHibernate-로드 / 가져 오기
이 장에서는로드 및 가져 오기 기능의 작동 방식과 사용 방법에 대해 설명합니다. 이들은에서 제공하는 매우 유사한 두 가지 API입니다.ISession 기본 키로 개체를로드합니다.
Get − 객체 또는 null을 반환합니다.
Load − 객체를 반환하거나 ObjectNotFoundException.
이제이 두 가지 API가있는 이유는 무엇입니까?
하중
Load가 데이터베이스 왕복을 훨씬 더 효율적으로 최적화 할 수 있기 때문입니다.
Load는 실제로 프록시 개체를 반환하며 Load 호출을 실행할 때 데이터베이스에 바로 액세스 할 필요가 없습니다.
해당 프록시에 액세스 할 때 개체가 데이터베이스에 있지 않고 해당 지점에서 ObjectNotFoundException을 throw 할 수 있습니다.
가져 오기
반대로 CLR의 제한으로 인해 Get을 사용하거나 Common Language Runtime NHibernate는 즉시 데이터베이스로 이동하여 개체가 있는지 확인하고 존재하지 않으면 null을 반환해야합니다.
프록시 개체를 반환 할 수없고 사용자가 실제로 액세스 할 때 해당 프록시 개체를 null로 스왑했기 때문에 해당 가져 오기, 데이터베이스로의 왕복을 나중에 지연하는 개체 옵션이 없습니다.
이것이 실제로 어떻게 사용되는지 그리고 Get과 Load의 차이점을 볼 수있는 간단한 예제를 살펴 보겠습니다. 우리는 동일한 도메인 클래스를 계속할 것입니다.Customers 과 Orders 그리고 마찬가지로 지난 장의 동일한 매핑 파일입니다.
이 예에서는 먼저 다음 프로그램과 같이 Get을 사용합니다.
using System;
using System.Data;
using System.Linq;
using System.Reflection;
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
namespace NHibernateDemo {
internal class Program {
private static void Main() {
var cfg = ConfigureNHibernate();
var sessionFactory = cfg.BuildSessionFactory();
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be");
var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
var customer1 = session.Get<Customer>(id1);
Console.WriteLine("Customer1 data");
Console.WriteLine(customer1);
var customer2 = session.Get<Customer>(id2);
Console.WriteLine("Customer2 data");
Console.WriteLine(customer2);
tx.Commit();
}
Console.WriteLine("Press <ENTER> to exit...");
Console.ReadLine();
}
private static Configuration ConfigureNHibernate() {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
cfg.DataBaseIntegration(x => {
x.ConnectionStringName = "default";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.IsolationLevel = IsolationLevel.RepeatableRead;
x.Timeout = 10;
x.BatchSize = 10;
});
cfg.SessionFactory().GenerateStatistics();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
return cfg;
}
}
}
보시다시피 두 가지 GuidID, 첫 번째는 좋은 ID이고 데이터베이스에있는 고객의 ID입니다. 두 번째 ID는 데이터베이스에 없습니다. 이 두 ID는 매개 변수로 전달되어Get() 메소드를 선택하면 결과가 콘솔에 인쇄됩니다.
위의 코드가 컴파일되고 실행되면 다음 출력이 표시됩니다.
Customer1 data
Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be)
Points: 74
HasGoldStatus: True
MemberSince: 4/4/2009 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52be
Customer2 data
Press <ENTER> to exit...
Customer1 데이터가 인쇄되지만 Customer2 데이터가 비어 있음을 알 수 있듯이 데이터베이스에서 Customer2 레코드를 사용할 수 없기 때문입니다.
애플리케이션을 다시 실행할 때 commit 문 앞에 중단 점을 삽입 한 다음 Watch 창에서 두 고객을 살펴 보겠습니다.
Customer1 데이터를 사용할 수있는 반면 Customer2는 null이고 유형은 NHibernateDemo.Customer 모두.
이제 다음 코드에 표시된 것과 동일한 예제에서 Get 대신 Load 메서드를 사용하겠습니다.
using System;
using System.Data;
using System.Linq;
using System.Reflection;
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
namespace NHibernateDemo {
internal class Program {
private static void Main() {
var cfg = ConfigureNHibernate();
var sessionFactory = cfg.BuildSessionFactory();
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be");
var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
var customer1 = session.Load<Customer>(id1);
Console.WriteLine("Customer1 data");
Console.WriteLine(customer1);
var customer2 = session.Load<Customer>(id2);
Console.WriteLine("Customer2 data");
Console.WriteLine(customer2);
tx.Commit();
}
Console.WriteLine("Press <ENTER> to exit...");
Console.ReadLine();
}
private static Configuration ConfigureNHibernate() {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
cfg.DataBaseIntegration(x => {
x.ConnectionStringName = "default";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.IsolationLevel = IsolationLevel.RepeatableRead;
x.Timeout = 10;
x.BatchSize = 10;
});
cfg.SessionFactory().GenerateStatistics();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
return cfg;
}
}
}
이제이 예제를 실행하면 스크린 샷에 표시된대로 다음 예외가 발생하는 것을 볼 수 있습니다.
이제 Watch 창을 보면 유형이 두 개체 모두에 대한 고객 프록시라는 것을 알 수 있습니다. 또한 콘솔 창에서 Customer1에 대한 동일한 데이터를 볼 수 있습니다.
Customer1 data
Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be)
Points: 74
HasGoldStatus: True
MemberSince: 4/4/2009 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52be
Customer2 data