NHibernate初体验
Hibernate是Java下久负盛名的开源持久层开发框架,使用起来是相当顺手,那么.Net下的NHibernate如何呢?带着点好奇,开始了NHibernate之初体验。
按照QuickStart中描述的过程,却不能顺利通过,经常出现各种个样的错误,网上的资料还奇缺,搜索来搜索去也大半都是遇到同样困惑的人互相提问,毫无出路,经过2天的烦恼之后,终于还是通过了,过程如下:
1.下载Nhibernate1.2.0GA,安装。并没有什么界面出现,这个安装就是解压一样,早知道下载zip版本的。
2.建立数据库,建立表,图省事,就用易装网的用户表了。定义如下:
3.接下来这个步骤是根据数据库写实体类和映射文件,难度不大,但比较繁琐,还是启动CodeSmith Professional 4.1,交给他做。下载的版本中已经包含了很多模板,其中就有NHibernate,找到NHibernate.cst,右键菜单,点击Execute。
在弹出的界面中配置如下:
其中Database旁边有个按钮,按下之后弹出数据库配置界面,新增一个,名字随便取,这里取名ezweb,Provider type 选SqlSchemaProvider,Connect string 就是连接到数据库的连接字符串。配置结束,点击Generate,这个时候CodeSmith并不会询问你要Generate谁,数据库中的所有用户表他都Generate,感觉稍欠妥当,经过3到5秒钟之后(看表有多少了),代码和映射文件就出现在文件夹中了。这个地方有个问题,实体类名称就是表名称,而我的习惯是表名都有前缀,所以生成的实体类名称就是ez_User,看起来非常的不合胃口,java中的hibernate也有这个毛病,所以如果要使用Hibernate,设计数据表的时候起名就要注意了。更改表名称,重来一遍,得到了User实体类和User.hbm.xml映射文件。
4.启动vs2005,新建项目,模板是类库。名称,如前在CodeSmith中的名字:qs.model。
把User.cs和User.hbm.xml拷贝到项目中,添加到项目中。此时进行编译是没有问题的,但使用是有问题的,要做一些修改:
打开user.hbm.xml,找到这句<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">,注意最后的数字,如果是1.2版本的Nhibernate此处要改成2.2
<class name="qs.model.User, qs.model" table="`User`">,这个地方要写清楚程序集名称和类名称,table="'User'"是说要到哪个表中查询数据,其中还带了单引号,是加到查询语句中的,例如:select 'user' ....,所以可有可无。
打开User.cs,将所有公开属性都加virtual,变成虚的
至此准备结束,开始测试。
5.新建一个控制台项目,引入Nhibernate.dll,注意版本,要引入for .Net 2.0的,引入qs.model.dll
在main方法中写入如下代码
Console.ReadLin()没有特殊含义,就是Run完的时候让他停下来,要不窗口一闪而过。执行,通过。
总结:
1.Nhibernate并不会像hibernate那样生成工厂类,如果按照分层次开发,Nhibernate就充当了数据访问层,对实体的操作,可直接弄到逻辑层了。
2.顺便一下hibernate的实体层和数据访问层都在一起,而实体层往往要在各层都要用到,还是用点功夫提出来。
2.出现could not compile mapping document、could not find entity classes等错误,多半是映射文件不正确。
3.如果有could not execute sql等错误,要注意表中是否有不允许空值的字段,尤其是时间类型的。
源码与数据库下载
按照QuickStart中描述的过程,却不能顺利通过,经常出现各种个样的错误,网上的资料还奇缺,搜索来搜索去也大半都是遇到同样困惑的人互相提问,毫无出路,经过2天的烦恼之后,终于还是通过了,过程如下:
1.下载Nhibernate1.2.0GA,安装。并没有什么界面出现,这个安装就是解压一样,早知道下载zip版本的。
2.建立数据库,建立表,图省事,就用易装网的用户表了。定义如下:
1CREATE TABLE [dbo].[User] (
2 [UserID] [int] IDENTITY (1, 1) NOT NULL ,
3 [UserName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
4 [Password] [varchar] (64) COLLATE Chinese_PRC_CI_AS NULL ,
5 [GroupId] [int] NOT NULL ,
6 [DeptId] [int] NOT NULL ,
7 [SettingString] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL ,
8 [PermitString] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL ,
9 [LastActive] [datetime] NULL ,
10 [CreateDate] [datetime] NULL ,
11 [Remark] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
12 [LoginCount] [int] NULL
13) ON [PRIMARY]
2 [UserID] [int] IDENTITY (1, 1) NOT NULL ,
3 [UserName] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
4 [Password] [varchar] (64) COLLATE Chinese_PRC_CI_AS NULL ,
5 [GroupId] [int] NOT NULL ,
6 [DeptId] [int] NOT NULL ,
7 [SettingString] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL ,
8 [PermitString] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL ,
9 [LastActive] [datetime] NULL ,
10 [CreateDate] [datetime] NULL ,
11 [Remark] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
12 [LoginCount] [int] NULL
13) ON [PRIMARY]
3.接下来这个步骤是根据数据库写实体类和映射文件,难度不大,但比较繁琐,还是启动CodeSmith Professional 4.1,交给他做。下载的版本中已经包含了很多模板,其中就有NHibernate,找到NHibernate.cst,右键菜单,点击Execute。
在弹出的界面中配置如下:
其中Database旁边有个按钮,按下之后弹出数据库配置界面,新增一个,名字随便取,这里取名ezweb,Provider type 选SqlSchemaProvider,Connect string 就是连接到数据库的连接字符串。配置结束,点击Generate,这个时候CodeSmith并不会询问你要Generate谁,数据库中的所有用户表他都Generate,感觉稍欠妥当,经过3到5秒钟之后(看表有多少了),代码和映射文件就出现在文件夹中了。这个地方有个问题,实体类名称就是表名称,而我的习惯是表名都有前缀,所以生成的实体类名称就是ez_User,看起来非常的不合胃口,java中的hibernate也有这个毛病,所以如果要使用Hibernate,设计数据表的时候起名就要注意了。更改表名称,重来一遍,得到了User实体类和User.hbm.xml映射文件。
4.启动vs2005,新建项目,模板是类库。名称,如前在CodeSmith中的名字:qs.model。
把User.cs和User.hbm.xml拷贝到项目中,添加到项目中。此时进行编译是没有问题的,但使用是有问题的,要做一些修改:
打开user.hbm.xml,找到这句<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">,注意最后的数字,如果是1.2版本的Nhibernate此处要改成2.2
<class name="qs.model.User, qs.model" table="`User`">,这个地方要写清楚程序集名称和类名称,table="'User'"是说要到哪个表中查询数据,其中还带了单引号,是加到查询语句中的,例如:select 'user' ....,所以可有可无。
打开User.cs,将所有公开属性都加virtual,变成虚的
至此准备结束,开始测试。
5.新建一个控制台项目,引入Nhibernate.dll,注意版本,要引入for .Net 2.0的,引入qs.model.dll
在main方法中写入如下代码
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using NHibernate;
6using NHibernate.Cfg;
7using qs.model;
8
9namespace test
10{
11 class Program
12 {
13 static void Main(string[] args)
14 {
15
16 try
17 {
18 Configuration config = new Configuration().AddAssembly("qs.model");
19 ISessionFactory factory = config.BuildSessionFactory();
20 ISession session = factory.OpenSession();
21
22 User u = new User();
23 u.UserName = "lordel";
24 u.GroupId = 2;
25 u.Password = "asdf";
26 u.PermitString = "sdf";
27 u.Remark = "df";
28 u.SettingString = "fd";
29 u.CreateDate = DateTime.Now;
30 u.LastActive = DateTime.Now;
31 u.LoginCount = 0;
32 u.Id = 3;
33
34 ITransaction trans = session.BeginTransaction();
35 session.Save(u);
36 trans.Commit();
37 Console.WriteLine("OK!");
38
39 Console.Read();
40 }
41 catch (Exception ex)
42 {
43 trans.Rollback();
44 Console.WriteLine(ex.Message);
45 Console.WriteLine(ex.StackTrace);
46 }
47 finally
48 {
49 Console.ReadLine();
50 }
51 }
52 }
53}
2using System.Collections.Generic;
3using System.Text;
4
5using NHibernate;
6using NHibernate.Cfg;
7using qs.model;
8
9namespace test
10{
11 class Program
12 {
13 static void Main(string[] args)
14 {
15
16 try
17 {
18 Configuration config = new Configuration().AddAssembly("qs.model");
19 ISessionFactory factory = config.BuildSessionFactory();
20 ISession session = factory.OpenSession();
21
22 User u = new User();
23 u.UserName = "lordel";
24 u.GroupId = 2;
25 u.Password = "asdf";
26 u.PermitString = "sdf";
27 u.Remark = "df";
28 u.SettingString = "fd";
29 u.CreateDate = DateTime.Now;
30 u.LastActive = DateTime.Now;
31 u.LoginCount = 0;
32 u.Id = 3;
33
34 ITransaction trans = session.BeginTransaction();
35 session.Save(u);
36 trans.Commit();
37 Console.WriteLine("OK!");
38
39 Console.Read();
40 }
41 catch (Exception ex)
42 {
43 trans.Rollback();
44 Console.WriteLine(ex.Message);
45 Console.WriteLine(ex.StackTrace);
46 }
47 finally
48 {
49 Console.ReadLine();
50 }
51 }
52 }
53}
Console.ReadLin()没有特殊含义,就是Run完的时候让他停下来,要不窗口一闪而过。执行,通过。
总结:
1.Nhibernate并不会像hibernate那样生成工厂类,如果按照分层次开发,Nhibernate就充当了数据访问层,对实体的操作,可直接弄到逻辑层了。
2.顺便一下hibernate的实体层和数据访问层都在一起,而实体层往往要在各层都要用到,还是用点功夫提出来。
2.出现could not compile mapping document、could not find entity classes等错误,多半是映射文件不正确。
3.如果有could not execute sql等错误,要注意表中是否有不允许空值的字段,尤其是时间类型的。
源码与数据库下载