NHibernate学习一入门

    看过不少NHibernate入门的介绍文章,由于版本原因和步骤省略,依葫芦画瓢,却不能写入数据,最后终于调通,特写随笔记下。

    环境: vs2008 sp1 + sqlserver 2005 + NHibernate-2.1.2.GA-bin

    下载: NHibernate-2.1.2.GA-bin下载地址http://downloads.sourceforge.net/project/nhibernate/NHibernate/2.1.2GA/NHibernate-2.1.2.GA-bin.zip

    准备: 先在数据库 建立 database: Nhibernate 建立 table: Person

代码
USE [Nhibernate]
GO
/****** 对象: Table [dbo].[Person] 脚本日期: 05/09/2010 18:17:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Person](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[Age] [int] NULL,
[Birthday] [datetime] NULL,
[Address] [nvarchar](200) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
[PersonId] ASC
)
WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
)
ON [PRIMARY]

说明:以上分别是表结构与项目结构,与lib文件夹列表,在项目里单独开一个lib文件,方便项目引用。他们来自NHibernate-2.1.2.GA-bin\Required_Bins 与 NHibernate-2.1.2.GA-bin\Required_For_LazyLoading\Castle

步骤:

    一 先建立解决方案 NhibernatePractice,建立3个类库与1个 aspnet 站点

    二 建立模型: NHDemoDomain 

        建立实体类 Person:     

代码
namespace NHDemoDomain.Entities
{
public class Person
{
// 注意:virtual 声明,否则会报错
public virtual int PersonId { get; set; }
public virtual string Name { get; set; }
public virtual int Age { get; set; }
public virtual DateTime Birthday { get; set; }
public virtual string Address { get; set; }
}
}

    建立实体类 person的 关系映射 xml : Person.hbm.xmls 

代码
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHDemoDomain" namespace="NHDemoDomain.Entities">
<class name="Person" table="Person">
<id name="PersonId" column="PersonId">
<generator class="native"></generator>
</id>
<property name="Name" column="Name"/>
<property name="Age" column="Age"/>
<property name="Birthday" column="Birthday"/>
<property name="Address" column="Address"/>
</class>
</hibernate-mapping>

请注意: assembly和namespace 因为我有文件夹所以是不同的,请根据自己实际情况指定相应名称。

             下面配置除了 id 特殊点,其他都是属性,column 对应 数据库的列,table对应数据库的表

              class="native" 按数据库组件处理。

             再这一层特别注意保留字,我开始因为建了个User,结果因为保留字而一直报错,不能保存。

特别注意:Person.hbm.xmls 在vs里按右键属性,进行设置,“复制到输出目录”,选择“始终复制”,“生成的操作”,选择“嵌入的资源”,否则会报错,找不到指定文件。

二 建立NHDemoNHDAL,数据处理。

          引用前面提到的 lib 文件夹里的所有dll,建立NHibernateHelper 类      

代码
using NHibernate;
using NHibernate.Cfg;

namespace NHDemoNHDAL
{
public sealed class NHibernateHelper
{
private static ISessionFactory sessionFactory;

static NHibernateHelper()
{
sessionFactory
= new Configuration().Configure().BuildSessionFactory();
}

public static ISession GetSession()
{
return sessionFactory.OpenSession();
}
}
}

 记得添加对 NHibernate 的引用,sessionFactory = new Configuration().Configure().BuildSessionFactory();

 新版本不再有对 hibernate.cfg.xml 文件指定,此文件设置好了,就把它复制到 web 站点的 bin 目录下,NH会自动去找这个文件,配置如下:

 

代码
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.connection_string">
server=.;uid=sa;pwd=;database=Nhibernate;
</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
<mapping assembly="NHDemoDomain"/>
</session-factory>
</hibernate-configuration>

注意: 新版必须设置 factory_class ,我这里引用的是Castle,可根据需要引用另外2个工厂。

          但必须吧NHibernate-2.1.2.GA-bin\Required_For_LazyLoading你所引用的相应工厂里的dll引用进来。

         NHibernate.Dialect.MsSql2005Dialect,表示我用的是sqlserver2005数据库,采用此数据库方言。大家可根据实际情况修改自己的数据库方言。

当然,你也可以选择用web.config来进行统一设置:

<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>

这句加到 <configSections>里面:

代码
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.connection_string">
server=.;uid=sa;pwd=;database=Nhibernate;
</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
<mapping assembly="NHDemoDomain"/>
</session-factory>
</hibernate-configuration>

在 <appSettings/> 前面加上上面的配置代码。

建立 PersonHelper,person数据处理类:

代码
using NHDemoDomain.Entities;
using NHibernate;
using NHibernate.Cfg;

namespace NHDemoNHDAL
{
public class PersonHelper
{
static PersonHelper()
{
}

public static int Insert(Person pson)
{
int id = 0;
ISession session
= NHibernateHelper.GetSession();
ITransaction ts
= session.BeginTransaction();
session.Save(pson);
ts.Commit();
session.Close();
id
= pson.PersonId;
return id;
}
}
}

注意添加引用,domain 和 NH 引用,这个类就是NH处理数据的核心,建立 session 通道,对数据进行保存插入数据库,启用了事物BeginTransaction,保存完毕后 NH会自动跟新 Person,所以id = pson.PersonId; 可以获取自动生成ID。

 

三 建立 NHDemonLogic 逻辑处理

    建立 PersonHandle 类:

 

代码
using NHDemoNHDAL;
using NHDemoDomain.Entities;

namespace NHDemonLogic
{
public class PersonHandle
{
private static log4net.ILog ilog = null;

static PersonHandle()
{
ilog
= log4net.LogManager.GetLogger(typeof(PersonHandle));
}
/// <summary>
/// 插入数据
/// </summary>
/// <param name="pName"></param>
/// <param name="pAge"></param>
/// <param name="pBirthday"></param>
/// <param name="pAddress"></param>
/// <returns></returns>
public static int Insert(string pName, string pAge, string pBirthday, string pAddress)
{
int id = 0;
try
{
int age = Convert.ToInt32(pAge);
DateTime birthday
= Convert.ToDateTime(pBirthday);

Person ps
= SetPesson(pName, age, birthday, pAddress);
id
=PersonHelper.Insert(ps);
}
catch(Exception ex){
ilog.Error(
"error:",ex);
}
return id;
}

/// <summary>
/// 组装 person
/// </summary>
/// <param name="name"></param>
/// <param name="age"></param>
/// <param name="birthday"></param>
/// <param name="address"></param>
/// <returns></returns>
public static Person SetPesson(string name,int age,DateTime birthday,string address)
{
Person ps
= new Person();
ps.Name
= name;
ps.Age
= age;
ps.Birthday
= birthday;
ps.Address
= address;
return ps;
}

}
}

这个类,主要负责从web 抓到的文本数据,进行类型转换,组装 person 然后交给PersonHelper 去处理。监控异常,写日志。

 四: 完善 NHDemoWeb

        NH的配置前面已经说了,下面主要是吧 log4net 配置加进去:

        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

加在 <configSections>里。

       

代码
<log4net>
<appender name="NHibernateFileLog" type="log4net.Appender.RollingFileAppender">
<file value="Logs/nhibernate.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{yyyy-MM-dd HH:mm} %-5p %c [%L] - %m%n" />
</layout>
</appender>

<appender name="GeneralLog" type="log4net.Appender.RollingFileAppender">
<file value="Logs/general.txt" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{yyyy-MM-dd HH:mm} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<appender name="LogicLog" type="log4net.Appender.RollingFileAppender">
<file value="Logs/logic.txt" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{yyyy-MM-dd HH:mm} %-5p %c [%L] - %m%n" />
</layout>
</appender>

<!-- levels: DEBUG, INFO, WARN, ERROR, FATAL -->

<root>
<level value="DEBUG"/>
<appender-ref ref="GeneralLog" />
</root>

<logger name="NHibernate" additivity="false">
<level value="WARN"/>
<appender-ref ref="NHibernateFileLog"/>
</logger>
<logger name="NHDemonLogic" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="LogicLog"/>
</logger>
</log4net>

加在 <appSettings/> 前面,logger name="NHibernate" 是针对 命名空间为NHibernate的日志,logger name="NHDemonLogic" 主要记录业务逻辑日志。

增加 Global.asax 文件,对log4net 初始化。

void Application_Start(object sender, EventArgs e)
{
//在应用程序启动时运行的代码
log4net.Config.DOMConfigurator.Configure(); // 初始化日志配置

}

前端页面控件如下:

 

 

 

 

 

 

 

 

 

 

 

后端页面代码如下:

代码
public partial class _Default : System.Web.UI.Page
{
log4net.ILog ilog
= null;//
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
ilog
= log4net.LogManager.GetLogger(typeof(_Default));
}
}

protected void btn_insert_Click(object sender, EventArgs e)
{
string name = tb_name.Text;
string age = tb_age.Text;
string birthday = tb_birthday.Text; //DateTime.Now.ToString();
string address = tb_address.Text;
int id = 0;
try
{
id
= PersonHandle.Insert(name, age, birthday, address);
//ilog.Info("id=" + id.ToString() + "插入成功");
}
catch(Exception ex)
{
ilog.Error(
"insert error", ex);
}
if (id > 0)
lb_insertResult.Text
= "id=" + id.ToString() + "插入成功";
else
lb_insertResult.Text
= "插入失败";
}

}

简单的获取数据传参。

下面附上源码,以供参考:

 

https://files.cnblogs.com/kinms/Practice_simple.rar

posted @ 2010-05-09 19:25  KinM  阅读(1276)  评论(3编辑  收藏  举报