[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

http://www.cnblogs.com/taven/archive/2010/09/28/1837478.html

本文将开始一步一步地使用Asp.net MVC 2 + Castle + NHibernate 开发一个项目。

 

在开始之前,我先对这三个组件做一个简单的介绍:

 Asp.net MVC 

它是微软提供的一个基于MVC标准的Web开发模式,其典型特点是有控制器和视图;在这之前,.NET下的Web开发模式大多是采用WebForm,其典型特点是服务端控件和后台触发事件; 

 NHibernate

它是一个ORM框架,使用Java的SSH做过项目开发的人就非常熟悉了,当前最新版本为NHibernate 3.0,听说完全支持Linq查询语句了,以前只支持HQL语句。 

 Castle

它是一个非常大的框架,包含IoC、MVC、ORM、AOP等,这次我只用到其IoC的功能。

 

关于IoC

IoC的英文是Inversion of Control,中文意思是控制反转,也有称其为Dependence Injection,中文意思是依赖注入,也就是DI;

除了Castle可以作IoC 外,还有著名的Spring.Net、Unity等,在我另外一个开源博客项目 http://rorowo.codeplex.com/ 中就用到了微软的Unity 2.0作为IoC。

 

好了,废话不多说,下面开始。 

 

首先,第一步是创建一个解决方案,项目结构如下:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1) 

需要引用的DLL库文件,我们全部放在RoRoWo.Common.DependLib下:

 [转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

 根据表的结构,如图: 

 [转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

 

现在我们开始为表结构创建实体类,以BlogCategory表为例,我们根据该表的字段名称和数据类型创建一个POCO类,放在RoRoWo.Domain.Entities下,代码内容如下:

 ExpandedBlockStart.gif代码

namespace
 RoRoWo.Domain {

    
    

public
 
class
 Blogcategory {

        

public
 Blogcategory() { }
        

public
 
virtual
 
int
 Cateid { 
get
; 
set
; }
        

public
 
virtual
 IList
<
Blogarticle
>
 Blogarticles { 
get
; 
set
; }
        

public
 
virtual
 
string
 Catename { 
get
; 
set
; }
        

public
 
virtual
 
int
 Parentid { 
get
; 
set
; }
        

public
 
virtual
 
int
 State { 
get
; 
set
; }
        

public
 
virtual
 
int
 Sortid { 
get
; 
set
; }
        

public
 
virtual
 
int
 Articlecount { 
get
; 
set
; }
        

public
 
virtual
 System.DateTime Createtime { 
get
; 
set
; }
        

public
 
virtual
 
string
 Note { 
get
; 
set
; }

    }

}

 

 在这里,我推荐一个可以生成NHibernate映射对象代码的工具(开源的),项目地址:NHibernate Mapping Generator(它同时支持 hbm.xml文件的方式、Fluent Mapping方式、Castle ActiveRecord方式)

接下来,要为这个类创建一个映射关系,我这里使用配置文件的方式,但是正式项目推荐使用Fluent方式。我们创建一个XML文件,文件名为“Blogcategory.hbm.xml”,放在RoRoWo.Domain.Mappings下,内容如下:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
ExpandedBlockStart.gif
代码

<?
xml version
=
“
1.0
“
 encoding
=
“
utf-8
“
?>


<
hibernate
–
mapping assembly
=
“
RoRoWo.Domain
“
 
namespace
=
“
RoRoWo.Domain
“
 xmlns
=
“
urn:nhibernate-mapping-2.2
“
 
default
–
lazy
=
“
false
“
>

    

<
class
 name
=
“
Blogcategory
“
 table
=
“
BlogCategory
“
>

        

<
id name
=
“
Cateid
“
 column
=
“
CateID
“
>

            

<
generator 
class
=
“
native
“
 
/>

        

</
id
>

        

<
property name
=
“
Catename
“
 column
=
“
CateName
“
 
/>

        

<
property name
=
“
Parentid
“
 column
=
“
ParentID
“
 
/>

        

<
property name
=
“
State
“
 column
=
“
State
“
 
/>

        

<
property name
=
“
Sortid
“
 column
=
“
SortID
“
 
/>

        

<
property name
=
“
Articlecount
“
 column
=
“
ArticleCount
“
 
/>

        

<
property name
=
“
Createtime
“
 column
=
“
CreateTime
“
 
/>

        

<
property name
=
“
Note
“
 column
=
“
Note
“
 
/>

    

</
class
>


</
hibernate
–
mapping
>

 

 

这里就是一个典型的映射关系了,如果有一对多,多对多的表关系,也是在这个配置中进行维护。

创建这个XML后,还有个很重要的操作,就是将其设为“嵌入的资源” ,鼠标右键查看“Blogcategory.hbm.xml”文件属性,将“生成操作”项的“内容”改为“嵌入的资源”,如图:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1) 

 到此,一个映射关系的实体就建立好了,下面我们就要来实现NHibernate对该表的增删改查操作了,我们把这些操作的实现放在RoRoWo.Data中。

注意,RoRoWo.Data需要添加对 “Castle.Core.dll” 
“
Castle.DynamicProxy2.dll
“
 
“
NHibernate.dll
“
 
“
RoRoWo.Domain
“
 的引用。

 

在创建数据库操作类之前,我们需要创建一个 “SessionManager”类,它负责维护整个ORM中的上下文,这里我使用李永京的一个类,其代码如下:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
ExpandedBlockStart.gif
代码

using
 System;

using
 System.Collections.Generic;

using
 System.Linq;

using
 System.Text;


using
 NHibernate;

using
 NHibernate.Cfg;


namespace
 RoRoWo.Data

{

    

public
 
class
 SessionManager

    {

        

private
 ISessionFactory _sessionFactory;
        

public
 SessionManager()

        {


            _sessionFactory 
=
 GetSessionFactory();

        }
        

private
 ISessionFactory GetSessionFactory()

        {

            

return
 (
new
 Configuration()).Configure().BuildSessionFactory();

        }
        

public
 ISession GetSession()

        {

            

return
 _sessionFactory.OpenSession();

        }

    }

}

 

 

我们创建一个“BlogCategoryRespository.cs”文件,其代码如下:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
ExpandedBlockStart.gif
代码

using
 System;

using
 System.Collections.Generic;

using
 System.Linq;

using
 System.Text;


using
 NHibernate;

using
 NHibernate.Cfg;

using
 NHibernate.Criterion;

using
 RoRoWo.Domain;


namespace
 RoRoWo.Data

{

    

public
 
class
 BlogCategoryRespository

    {

        

private
 ISession _session;
        

public
 ISession Session

        {

            

set


            {


                _session 
=
 value;

            }

        }

        
public
 BlogCategoryRespository(ISession session)

        {


            _session 
=
 session;

        }

        
public
 Blogcategory GetById(
int
 cateId)

        {

            
return
 _session.Get
<
Blogcategory
>
(cateId);

        }

        
public
 
void
 Create(Blogcategory dto)

        {


            _session.Save(dto);

            _session.Flush();

        }

        
public
 
int
 CreateAndReturn(Blogcategory dto)

        {

            

int
 newid 
=
 (
int
)_session.Save(dto);

            _session.Flush();
            

return
 newid;

        }

        
///
 
<summary>

        

///
 使用事务
        

///
 
</summary>

        

///
 
<param name=”dto”></param>

        

///
 
<returns></returns>


        
public
 
int
 CreateTransaction(Blogcategory dto)

        {

            

using
 (ITransaction tx 
=
 _session.BeginTransaction())

            {

                

try


                {

                    

int
 newId 
=
 (
int
)_session.Save(dto);

                    _session.Flush();

                    tx.Commit();
                    

return
 newId;

                }
                

catch
 (HibernateException)

                {


                    tx.Rollback();
                    

throw
;

                }

            }

        }

        
public
 
void
 UpdateCustomer(Blogcategory dto)

        {


            _session.Update(dto);

            _session.Flush();

        }

        
public
 
void
 SaveOrUpdate(IList
<
Blogcategory
>
 dtos)

        {

            

foreach
 (var c 
in
 dtos)

            {


                _session.SaveOrUpdate(c);

            }

            _session.Flush();

        }

        
public
 
void
 Delete(Blogcategory dto)

        {


            _session.Delete(dto);

            _session.Flush();

        }

        
public
 IList
<
Blogcategory
>
 From()

        {

            

//
返回所有Blogcategory类的实例


            
return
 _session.CreateQuery(
“
from Blogcategory
“
)

                .List
<
Blogcategory
>
();

        }

        
public
 IList
<
int
>
 Select()

        {

            

//
返回所有Blogcategory的CateId


            
return
 _session.CreateQuery(
“
select c.CateId from Blogcategory c
“
)

                .List
<
int
>
();

        }

        
public
 IList
<
Blogcategory
>
 Where()

        {

            

return
 _session.CreateQuery(
“
from Blogcategory c where c.CateId=’3′
“
)

                .List
<
Blogcategory
>
();

        }

        
public
 IList
<
Blogcategory
>
 GetGreaterThan(
int
 CateId)

        {

            

//
return _session.CreateQuery(“select from Blogcategory c where c.CateId > :cid”)
            

//
    .SetInt32(“cid”, CateId)
            

//
    .List<Blogcategory>();



            

return
 _session.CreateCriteria(
typeof
(Blogcategory))

            .Add(Restrictions.Gt(
“
CateId
“
, CateId))

            .List
<
Blogcategory
>
();


        }

        
public
 IList
<
Blogcategory
>
 CreateCriteria()

        {


            ICriteria crit 
=
 _session.CreateCriteria(
typeof
(Blogcategory));

            crit.SetMaxResults(
50
);

            IList
<
Blogcategory
>
 blogcategorys 
=
 crit.List
<
Blogcategory
>
();
            

return
 blogcategorys;

        }

        
public
 IList
<
Blogcategory
>
 Narrowing()

        {


            IList
<
Blogcategory
>
 blogcategorys 
=
 _session.CreateCriteria(
typeof
(Blogcategory))

                .Add(Restrictions.Like(
“
Catename
“
, 
“
s%
“
))

                .Add(Restrictions.Between(
“
Parentid
“
, 
“
1
“
, 
“
3
“
))

                .List
<
Blogcategory
>
();
            

return
 blogcategorys;

        }

        
public
 IList
<
Blogcategory
>
 Query()

        {


            Blogcategory dtoSample 
=
 
new
 Blogcategory() { Catename 
=
 
“
sss
“
, Parentid 
=
 
0
 };
            

return
 _session.CreateCriteria(
typeof
(Blogcategory))

                .Add(Example.Create(dtoSample))

                .List
<
Blogcategory
>
();

        }

        
public
 IList
<
Blogcategory
>
 UseQueryByExample_Get(Blogcategory dtoSample)

        {


            Example example 
=
 Example.Create(dtoSample)

                .IgnoreCase()

                .EnableLike()

                .SetEscapeCharacter(
‘
&
‘
);
            

return
 _session.CreateCriteria(
typeof
(Blogcategory))

               .Add(example)

               .List
<
Blogcategory
>
();

        }


    }

}

 

 

该代码具有了对一个表的基本操作,现在我们就来创建一个单元测试,测试一下插入数据。

在创建插入操作时,我们要能使NHibernate正常工作,还需要创建一个配置文件,我们创建一个XML文件,文件名为“hibernate.cfg.xml”,放在RoRoWo.UnitTest下,其内容为:

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
ExpandedBlockStart.gif
代码

<?
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”
>


            Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;
        

</
property
>

        

<
property 
name
=”adonet.batch_size”
>
10
</
property
>

        

<
property 
name
=”show_sql”
>
true
</
property
>

        

<
property 
name
=”dialect”
>
NHibernate.Dialect.MsSql2005Dialect
</
property
>

        

<
property 
name
=”use_outer_join”
>
true
</
property
>

        

<
property 
name
=”command_timeout”
>
10
</
property
>

        

<
property 
name
=”query.substitutions”
>
true 1, false 0, yes ‘Y’, no ‘N’
</
property
>

        

<
property 
name
=”proxyfactory.factory_class”
>


            NHibernate.ByteCode.Castle.ProxyFactoryFactory,

            NHibernate.ByteCode.Castle
        

</
property
>

        

<
mapping 
assembly
=”RoRoWo.Domain”
/>

    

</
session-factory
>


</
hibernate-configuration
>

 

 其中“Data Source=.;Initial Catalog=RoRoWoDB;User ID=sa;Password=2010;”是我的数据库连接,您可以改为您的。

 

现在我们添加一个单元测试(不明白如何添加的请参考相关资料),先测试插入方法,其代码如下:

 ExpandedBlockStart.gif代码

        
///
 
<summary>

        

///
Create 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 CreateTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);

            Blogcategory dto 
=
 
new
 Blogcategory();


            dto.Catename 
=
 
“
新分类
“
 
+
 
new
 Random().Next(
100000
, 
999999
).ToString();

            dto.Parentid 
=
 
0
;

            dto.State 
=
 
0
;

            dto.Createtime 
=
 DateTime.Now;

            
int
 newid 
=
 target.CreateAndReturn(dto);

            Assert.IsTrue(newid 
>
 
0
);

        }

 

 执行单元测试,可以通过测试,并且在数据库中已经成功插入了一条记录,结果完全正确;

我们接着对查询方法进行测试,我们将测试代码如下:

 

[转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)
ExpandedBlockStart.gif
代码

        
///
 
<summary>

        

///
GetById 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 GetByIdTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);
            

int
 cateId 
=
 
3
;

            Blogcategory actual;

            actual 
=
 target.GetById(cateId);

            Assert.AreEqual(cateId, actual.Cateid);


        }

        
///
 
<summary>

        

///
From 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 FromTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);

            IList
<
Blogcategory
>
 actual;

            actual 
=
 target.From();

            Assert.IsTrue(actual.Count 
>
 
0
);


        }

        
///
 
<summary>

        

///
Select 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 SelectTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);

            IList
<
int
>
 actual;

            actual 
=
 target.Select();

            Assert.IsTrue(actual.Count 
>
 
0
);

        }

        
///
 
<summary>

        

///
Where 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 WhereTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);


            IList
<
Blogcategory
>
 actual;

            actual 
=
 target.Where();

            Assert.IsTrue(actual.Count 
>
 
0
);

        }

        
///
 
<summary>

        

///
GetGreaterThan 的测试
        

///
</summary>


        [TestMethod()]
        

public
 
void
 GetGreaterThanTest()

        {


            SessionManager sessionManager 
=
 
new
 SessionManager();

            ISession session 
=
 sessionManager.GetSession();

            BlogCategoryRespository target 
=
 
new
 BlogCategoryRespository(session);
            

int
 CateId 
=
 
0
; 
//
 TODO: 初始化为适当的值


            IList
<
Blogcategory
>
 actual;

            actual 
=
 target.GetGreaterThan(CateId);

            Assert.IsTrue(actual.Count 
>
 
0
);


        }

 

 

 测试结果全部绿灯通过:

 [转载]Asp.net MVC 2 + Castle + NHibernate 项目实战(1)

下一篇,我将谈谈如何配置一对多和多对多的表映射关系。

 

该例子的完整代码可以到开源平台下载,地址: http://rorowoproject.codeplex.com

文章中如有不足之处,望大家多指正。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/110505.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux删除历史操作命令「建议收藏」

    linux删除历史操作命令「建议收藏」 在linux系统里一旦操作了任何命令,都会被记录下来,可以通过history命令来查看历史命令,  查看手册可知history-c便是清除历史命令,但是重新进入系统查看历史命令时,历史信息依然会存在,  那么history-c只是清除当前shell的历史纪录,因为系统一般会把信息保存在一个文件中,只要文件中  内容没有改变,那么信息也不会变。linux中存放历史命令的文件是….

    2022年6月22日
  • java运行环境安装及配置教程

    java运行环境安装及配置教程用来进行web开发的工具有很多,Tomcat是其中一个开源的且免费的javaWeb服务器,是Apache软件基金会的项目。电脑上安装配置Tomcat的方法和java有些相同,不过首先需要配置好java的环境才行。一.java环境的配置1.下载安装javaJDK,注意安装的路径,我们需要进行环境变量的配置(安装jdk随意选择目录只需把默认安装目录\java之前的目录修改即可)

    2022年7月17日
  • Java BigDecimal的使用[通俗易懂]

    Java BigDecimal的使用[通俗易懂]BigDecimal加减乘除BigDecimalbignum1=newBigDecimal(“10”);BigDecimalbignum2=newBigDecimal(“5”);BigDecimalbignum3=null;//加法bignum3=bignum1.add(bignum2);System.out.pr…

    2022年6月7日
  • python中产生随机数的代码_python生成1~10的随机偶数

    python中产生随机数的代码_python生成1~10的随机偶数Python产生随机数:一.Python自带的random库1.参生n–m范围内的一个随机数:random.randint(n,m)2.产生0到1之间的浮点数:random.random()3.产生n—m之间的浮点数:random.uniform(1.1,5.4)4.产生从n—m间隔为k的整数:…

    2022年10月5日
  • sqlserver事务锁死_sql触发器格式

    sqlserver事务锁死_sql触发器格式一、触发器触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表 事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表 进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务 规则等。 触发器可以从 DBA_TRIGGERS ,USER_TR…

    2022年8月18日
  • gtest框架_软件测试框架

    gtest框架_软件测试框架gtest下载与安装gitclonehttps://github.com/google/googletest.gitcdgoogletestmkdirbuildcmake..makesudomakeinstall以上命令会将gtest编译好,并将动态链接库放在/usr/local/lib目录下:zhouhao@ubuntu:/usr/loc…

    2022年9月29日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号