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

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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 ]

2010050918230853.jpg2010050918245992.jpg2010050918302126.jpg

说明:以上分别是表结构与项目结构,与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:     

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
<? 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 类      

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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会自动去找这个文件,配置如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
<? 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>里面:

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
< 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数据处理类:

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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 类:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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>里。

       

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
< 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(); // 初始化日志配置

}

前端页面控件如下:

2010050919205291.jpg

 

 

 

 

 

 

 

 

 

 

 

后端页面代码如下:

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
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
= " 插入失败 " ;
}

}

简单的获取数据传参。

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

 

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

转载于:https://www.cnblogs.com/kinms/archive/2010/05/09/1731262.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值