理解 ISession 与 ISessionFactory 的生命周期,并通过封装 SessionManager 辅助类与 NewsDAL 数据层,完成数据库的初步操作准备。
一、 核心概念:ISessionFactory 与 ISession
- ISessionFactory(线程安全):全局对象,通常整个应用只需实例化一次。它负责读取配置并构建,代价较高,可被多线程同时访问。
- ISession(非线程安全):代表与数据库的一次单线程操作(工作单元)。它从
ISessionFactory打开,用完必须关闭,不可被多个线程共享。 - 配置读取:通过
new Configuration().Configure().BuildSessionFactory()构建。默认读取根目录下的hibernate.cfg.xml,也可传入自定义路径。
二、 辅助类 SessionManager 封装
为了全局复用 ISessionFactory 并简化 ISession 的获取,需编写辅助类(通常放在项目根目录或 Helper 文件夹):
using NHibernate;
using NHibernate.Cfg;
namespace NHibernateDemo
{
public class SessionManager
{
// 全局单例 SessionFactory(线程安全,只初始化一次)
private static readonly ISessionFactory _sessionFactory;
// 静态构造函数,程序首次使用时初始化配置
static SessionManager()
{
var config = new Configuration();
// Configure() 默认读取根目录 hibernate.cfg.xml
_sessionFactory = config.Configure().BuildSessionFactory();
}
// 提供打开新 Session(单线程)的方法
public static ISession OpenSession()
{
return _sessionFactory.OpenSession();
}
// 应用关闭时释放资源(可选)
public static void CloseSessionFactory()
{
_sessionFactory?.Close();
}
}
}Code language: JavaScript (javascript)
三、 配置文件 hibernate.cfg.xml
在根目录添加此文件(需设置为“复制到输出目录”),示例内容(适配前序 SQL Server 与 News 表):
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">
Server=.;Database=NHibernateDemo;Integrated Security=true;
</property>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<property name="show_sql">true</property>
<!-- 映射文件程序集 -->
<mapping assembly="NHibernateDemo"/>
</session-factory>
</hibernate-configuration>Code language: HTML, XML (xml)
四、 DAL 操作类(NewsDAL)
新建 DAL 文件夹,添加 NewsDAL.cs,通过 SessionManager 获取 ISession,编写“通过ID获取新闻”方法:
using NHibernate;
using NHibernateDemo.Models;
namespace NHibernateDemo.DAL
{
public class NewsDAL
{
// 通过 ID 获取新闻实体
public News GetNewsById(int id)
{
// 获取单线程 Session
using (ISession session = SessionManager.OpenSession())
{
// Get 方法自动加载,若配置了延迟加载/多对多,可配合 Fetch
News news = session.Get<News>(id);
return news;
} // using 结束自动 Close/Dispose,确保释放
}
// 后续可扩展:Save、Update、Delete、GetAll 等
}
}Code language: JavaScript (javascript)
Previous: 添加实体类和映射文件
Next: 配置 Nhibernate和读取数据表记录