DotNet企业级架构实战之5——基于接口的访问层实现
2009-02-18 14:01
603 查看
前几节的内容比较务虚,这一节主要讲讲怎么应用Spring.net和nHibernate及我们写的模板,来搭建一个数据访问层,以及在页面中的调用。
先来看一个层级图:
这里有一个model(实体)层,一个DAO(数据访问)层,中间还有一个Interface(接口)层。
这又回到了最初的探索:接口的做用,一是隐藏实现的细节;二是更利于装配——在spring.net的配置文件中,你可以随时装配一个不同的实现,只要它完成接口规定的方法,好处不言而喻——于页面而言,它并不知道谁来实现了这些功能,它只知道接口的存在(你们都去实现接口吧,我不关心谁在做这件事,要的只是结果!)
◆欧克,现在页面需要一个对用户表访问的东西(TB_USER_MAIN表,对应的实体是woodigg.model.USERMAIN),先做一个接口,在woodigg.Interface层添加一个接口:
Code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Data;
using
woodigg.model;
namespace
woodigg.Interface.DAO
{
///
<summary>
///
user main DAO Interface
///
</summary>
public
interface
IUserMainDAO
{
///
<summary>
///
存
///
</summary>
bool
Save(USERMAIN mb);
///
<summary>
///
事务级添加
///
</summary>
///
<param name="art"></param>
///
<param name="from"></param>
///
<returns></returns>
bool
TransactionSave(USERMAIN art,
string
from);
///
<summary>
///
更新
///
</summary>
bool
Update(USERMAIN mb);
///
<summary>
///
事务级删除
///
</summary>
bool
Delete(USERMAIN mb);
///
<summary>
///
读
///
</summary>
USERMAIN LoadFromId(
int
id);
///
<summary>
///
搜索
///
</summary>
IList
<
USERMAIN
>
SearchByWhere(
string
where
);
///
<summary>
///
搜索排序
///
</summary>
IList
<
USERMAIN
>
SearchByWhereOrder(
string
where
,
string
propertyName,
bool
ascending);
///
<summary>
///
分页
///
</summary>
DataTable GetPagerByStoreProc(
string
Columns,
int
pageSize,
int
pageIdx
,
string
OrderColumn,
bool
orderType,
string
condition);
///
<summary>
///
获取记录数
///
</summary>
int
GetRecordCount(
string
where
);
}
}
◆显然,它的功能都是上一节那个DaoTemplate泛型模板已经有的,要实现真的很easy——编译刚才的woodigg.Interface项目,并在woodigg.DAO层中引用此项目,然后添加一个实现:
Code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Data;
using
Spring.Context;
using
Spring.Context.Support;
using
Spring.Dao;
using
Spring.Data.NHibernate.Support;
using
woodigg.model;
using
woodigg.Interface.DAO;
using
Spring.Transaction.Interceptor;
namespace
woodigg.DAO
{
///
<summary>
///
user main DAO
///
</summary>
public
class
UserMainDaoSpring : IUserMainDAO
{
#region
注入的DaoTemplate
private
DaoTemplate _DaoTemplate;
public
DaoTemplate DaoTemplate
{
get
{
return
_DaoTemplate; }
set
{ _DaoTemplate
=
value; }
}
#endregion
private
const
string
TableName
=
"
TB_USER_MAIN
"
;
//
表名
private
const
string
PrimaryKey
=
"
Id
"
;
//
主键
public
UserMainDaoSpring() { }
///
<summary>
///
存
///
</summary>
public
bool
Save(USERMAIN art)
{
return
DaoTemplate.Save
<
USERMAIN
>
(art);
}
///
<summary>
///
事务级添加
///
</summary>
///
<param name="art"></param>
///
<param name="from">
从哪来
</param>
///
<returns></returns>
[Transaction()]
public
bool
TransactionSave(USERMAIN art,
string
from)
{
if
(DaoTemplate.Save
<
USERMAIN
>
(art))
{
USEROTHER ot
=
new
USEROTHER();
ot.UserId
=
art.Id;
ot.UserFrom
=
from;
return
DaoTemplate.Save
<
USEROTHER
>
(ot);
}
else
return
false
;
}
///
<summary>
///
更新
///
</summary>
///
<param name="art"></param>
///
<returns></returns>
public
bool
Update(USERMAIN art)
{
return
DaoTemplate.Update
<
USERMAIN
>
(art);
}
///
<summary>
///
删除
///
</summary>
///
<param name="art"></param>
[Transaction()]
public
bool
Delete(USERMAIN art)
{
DaoTemplate.Delete
<
USEROTHER
>
(
"
UserId=
"
+
art.Id);
return
DaoTemplate.Delete
<
USERMAIN
>
(art);
}
///
<summary>
///
读
///
</summary>
public
USERMAIN LoadFromId(
int
id)
{
return
DaoTemplate.LoadFromId
<
USERMAIN
>
(id);
}
///
<summary>
///
查
///
</summary>
public
IList
<
USERMAIN
>
SearchByWhere(
string
where
)
{
return
DaoTemplate.Search
<
USERMAIN
>
(
where
);
}
///
<summary>
///
查排序
///
</summary>
public
IList
<
USERMAIN
>
SearchByWhereOrder(
string
where
,
string
propertyName,
bool
ascending)
{
return
DaoTemplate.SearchWithOrder
<
USERMAIN
>
(
where
,propertyName,ascending);
}
///
<summary>
///
分页
///
</summary>
///
<param name="pageSize"></param>
///
<param name="pageIdx"></param>
///
<param name="OrderColumn"></param>
///
<param name="orderType"></param>
///
<param name="condition"></param>
///
<returns></returns>
public
DataTable GetPagerByStoreProc(
string
Columns,
int
pageSize,
int
pageIdx
,
string
OrderColumn,
bool
orderType,
string
condition)
{
return
DaoTemplate.GetPageEntitesByStoredProc
(TableName, PrimaryKey, Columns, OrderColumn, pageSize, pageIdx, orderType, condition);
}
///
<summary>
///
获取记录数
///
</summary>
///
<param name="where"></param>
public
int
GetRecordCount(
string
where
) {
return
DaoTemplate.GetRecordCount
<
USERMAIN
>
(
where
);
}
}
}
◆为这种类型的DAL制作一个配置文件business.xml,以便在需要时,由spring.net的对象工厂实例化并派发它:
Code
<?
xml version="1.0" encoding="utf-8"
?>
<
objects
xmlns
="http://www.springframework.net"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"
>
<
object
id
="UserMainDaoSpring"
type
="woodigg.DAO.UserMainDaoSpring,woodigg.DAO"
autowire
="byName"
/>
</
objects
>
◆至此,一个所谓的DAL打造完成,把它应用到.aspx页面中去(当然,实例中比这复杂得多,以后我们会在ASP.NET MVC中应用这些,页面只是个壳)。为了.aspx页面,做一个配置文件pageConfig.xml吧,在这个xml里,登记所有需要注入的页面路径,以便植入实现了接口的DAL:
假设这页面在/下,叫test.aspx:
Code
<?
xml version="1.0" encoding="utf-8"
?>
<
objects
xmlns
="http://www.springframework.net"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"
>
<!--
页面调用
-->
<
object
type
="~/test.aspx"
autowire
="byName"
/>
</
objects
>
如前所述,byName的意思是:页面上写什么接口,就自动去配置环境中查找相应接口实现,并把它在工厂中的实例注入页面中。
◆然后,我们整合一下应用环境,把它配置到web.config中:
Code
<
configSections
>
<
sectionGroup
name
="spring"
>
<
section
name
="context"
type
="Spring.Context.Support.WebContextHandler, Spring.Web"
/>
<
section
name
="objects"
type
="Spring.Context.Support.DefaultSectionHandler, Spring.Core"
/>
</
sectionGroup
>
<
section
name
="SpringOverrideProperty"
type
="System.Configuration.NameValueSectionHandler"
/>
<
section
name
="nhibernate"
type
="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
<!--
log4net
-->
<
section
name
="log4net"
type
="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/>
</
configSections
>
<
SpringOverrideProperty
>
<
add
key
="DbProvider.ConnectionString"
value
="Data Source=(local);Database=Music;User ID=sa;Password=system;Trusted_Connection=False"
/>
<
add
key
="SystemInit.IsDebug"
value
="true"
/>
<
add
key
="SystemInit.Level"
value
="4"
/>
</
SpringOverrideProperty
>
<!--
Spirng.Net 配置
-->
<
spring
>
<
context
>
<
resource
uri
="config://spring/objects"
/>
<
resource
uri
="~/config/applicationContext.xml"
/>
<
resource
uri
="~/config/business.xml"
/>
<
resource
uri
="~/config/pageConfig.xml"
/>
</
context
>
<
objects
xmlns
="http://www.springframework.net"
/>
</
spring
>
<
system.web
>
<
httpModules
>
<
add
name
="Spring"
type
="Spring.Context.Support.WebSupportModule, Spring.Web"
/>
</
httpModules
>
<
httpHandlers
>
<
add
verb
="*"
path
="*.aspx"
type
="Spring.Web.Support.PageHandlerFactory, Spring.Web"
/>
</
system.web
>
</
httpHandlers
>
</
system.web
>
◆最后,test.aspx.cs中,这样引用前面基于IUserMainDAO接口的实现,就能让它跑起来了:
Code
#region
注入对象
private
IUserMainDAO _UserMainDaoSpring;
public
IUserMainDAO UserMainDaoSpring
{
get
{
return
_UserMainDaoSpring; }
set
{ _UserMainDaoSpring
=
value; }
}
#endregion
看起来,似乎是繁琐到发指的一些工作,不过形成习惯了应该就会喜欢上它的,眼下的麻烦只是为了避免未来更大的麻烦,图难图其易图巨图其细嘛~
先来看一个层级图:
这里有一个model(实体)层,一个DAO(数据访问)层,中间还有一个Interface(接口)层。
这又回到了最初的探索:接口的做用,一是隐藏实现的细节;二是更利于装配——在spring.net的配置文件中,你可以随时装配一个不同的实现,只要它完成接口规定的方法,好处不言而喻——于页面而言,它并不知道谁来实现了这些功能,它只知道接口的存在(你们都去实现接口吧,我不关心谁在做这件事,要的只是结果!)
◆欧克,现在页面需要一个对用户表访问的东西(TB_USER_MAIN表,对应的实体是woodigg.model.USERMAIN),先做一个接口,在woodigg.Interface层添加一个接口:
Code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Data;
using
woodigg.model;
namespace
woodigg.Interface.DAO
{
///
<summary>
///
user main DAO Interface
///
</summary>
public
interface
IUserMainDAO
{
///
<summary>
///
存
///
</summary>
bool
Save(USERMAIN mb);
///
<summary>
///
事务级添加
///
</summary>
///
<param name="art"></param>
///
<param name="from"></param>
///
<returns></returns>
bool
TransactionSave(USERMAIN art,
string
from);
///
<summary>
///
更新
///
</summary>
bool
Update(USERMAIN mb);
///
<summary>
///
事务级删除
///
</summary>
bool
Delete(USERMAIN mb);
///
<summary>
///
读
///
</summary>
USERMAIN LoadFromId(
int
id);
///
<summary>
///
搜索
///
</summary>
IList
<
USERMAIN
>
SearchByWhere(
string
where
);
///
<summary>
///
搜索排序
///
</summary>
IList
<
USERMAIN
>
SearchByWhereOrder(
string
where
,
string
propertyName,
bool
ascending);
///
<summary>
///
分页
///
</summary>
DataTable GetPagerByStoreProc(
string
Columns,
int
pageSize,
int
pageIdx
,
string
OrderColumn,
bool
orderType,
string
condition);
///
<summary>
///
获取记录数
///
</summary>
int
GetRecordCount(
string
where
);
}
}
◆显然,它的功能都是上一节那个DaoTemplate泛型模板已经有的,要实现真的很easy——编译刚才的woodigg.Interface项目,并在woodigg.DAO层中引用此项目,然后添加一个实现:
Code
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Data;
using
Spring.Context;
using
Spring.Context.Support;
using
Spring.Dao;
using
Spring.Data.NHibernate.Support;
using
woodigg.model;
using
woodigg.Interface.DAO;
using
Spring.Transaction.Interceptor;
namespace
woodigg.DAO
{
///
<summary>
///
user main DAO
///
</summary>
public
class
UserMainDaoSpring : IUserMainDAO
{
#region
注入的DaoTemplate
private
DaoTemplate _DaoTemplate;
public
DaoTemplate DaoTemplate
{
get
{
return
_DaoTemplate; }
set
{ _DaoTemplate
=
value; }
}
#endregion
private
const
string
TableName
=
"
TB_USER_MAIN
"
;
//
表名
private
const
string
PrimaryKey
=
"
Id
"
;
//
主键
public
UserMainDaoSpring() { }
///
<summary>
///
存
///
</summary>
public
bool
Save(USERMAIN art)
{
return
DaoTemplate.Save
<
USERMAIN
>
(art);
}
///
<summary>
///
事务级添加
///
</summary>
///
<param name="art"></param>
///
<param name="from">
从哪来
</param>
///
<returns></returns>
[Transaction()]
public
bool
TransactionSave(USERMAIN art,
string
from)
{
if
(DaoTemplate.Save
<
USERMAIN
>
(art))
{
USEROTHER ot
=
new
USEROTHER();
ot.UserId
=
art.Id;
ot.UserFrom
=
from;
return
DaoTemplate.Save
<
USEROTHER
>
(ot);
}
else
return
false
;
}
///
<summary>
///
更新
///
</summary>
///
<param name="art"></param>
///
<returns></returns>
public
bool
Update(USERMAIN art)
{
return
DaoTemplate.Update
<
USERMAIN
>
(art);
}
///
<summary>
///
删除
///
</summary>
///
<param name="art"></param>
[Transaction()]
public
bool
Delete(USERMAIN art)
{
DaoTemplate.Delete
<
USEROTHER
>
(
"
UserId=
"
+
art.Id);
return
DaoTemplate.Delete
<
USERMAIN
>
(art);
}
///
<summary>
///
读
///
</summary>
public
USERMAIN LoadFromId(
int
id)
{
return
DaoTemplate.LoadFromId
<
USERMAIN
>
(id);
}
///
<summary>
///
查
///
</summary>
public
IList
<
USERMAIN
>
SearchByWhere(
string
where
)
{
return
DaoTemplate.Search
<
USERMAIN
>
(
where
);
}
///
<summary>
///
查排序
///
</summary>
public
IList
<
USERMAIN
>
SearchByWhereOrder(
string
where
,
string
propertyName,
bool
ascending)
{
return
DaoTemplate.SearchWithOrder
<
USERMAIN
>
(
where
,propertyName,ascending);
}
///
<summary>
///
分页
///
</summary>
///
<param name="pageSize"></param>
///
<param name="pageIdx"></param>
///
<param name="OrderColumn"></param>
///
<param name="orderType"></param>
///
<param name="condition"></param>
///
<returns></returns>
public
DataTable GetPagerByStoreProc(
string
Columns,
int
pageSize,
int
pageIdx
,
string
OrderColumn,
bool
orderType,
string
condition)
{
return
DaoTemplate.GetPageEntitesByStoredProc
(TableName, PrimaryKey, Columns, OrderColumn, pageSize, pageIdx, orderType, condition);
}
///
<summary>
///
获取记录数
///
</summary>
///
<param name="where"></param>
public
int
GetRecordCount(
string
where
) {
return
DaoTemplate.GetRecordCount
<
USERMAIN
>
(
where
);
}
}
}
◆为这种类型的DAL制作一个配置文件business.xml,以便在需要时,由spring.net的对象工厂实例化并派发它:
Code
<?
xml version="1.0" encoding="utf-8"
?>
<
objects
xmlns
="http://www.springframework.net"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"
>
<
object
id
="UserMainDaoSpring"
type
="woodigg.DAO.UserMainDaoSpring,woodigg.DAO"
autowire
="byName"
/>
</
objects
>
◆至此,一个所谓的DAL打造完成,把它应用到.aspx页面中去(当然,实例中比这复杂得多,以后我们会在ASP.NET MVC中应用这些,页面只是个壳)。为了.aspx页面,做一个配置文件pageConfig.xml吧,在这个xml里,登记所有需要注入的页面路径,以便植入实现了接口的DAL:
假设这页面在/下,叫test.aspx:
Code
<?
xml version="1.0" encoding="utf-8"
?>
<
objects
xmlns
="http://www.springframework.net"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"
>
<!--
页面调用
-->
<
object
type
="~/test.aspx"
autowire
="byName"
/>
</
objects
>
如前所述,byName的意思是:页面上写什么接口,就自动去配置环境中查找相应接口实现,并把它在工厂中的实例注入页面中。
◆然后,我们整合一下应用环境,把它配置到web.config中:
Code
<
configSections
>
<
sectionGroup
name
="spring"
>
<
section
name
="context"
type
="Spring.Context.Support.WebContextHandler, Spring.Web"
/>
<
section
name
="objects"
type
="Spring.Context.Support.DefaultSectionHandler, Spring.Core"
/>
</
sectionGroup
>
<
section
name
="SpringOverrideProperty"
type
="System.Configuration.NameValueSectionHandler"
/>
<
section
name
="nhibernate"
type
="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
<!--
log4net
-->
<
section
name
="log4net"
type
="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/>
</
configSections
>
<
SpringOverrideProperty
>
<
add
key
="DbProvider.ConnectionString"
value
="Data Source=(local);Database=Music;User ID=sa;Password=system;Trusted_Connection=False"
/>
<
add
key
="SystemInit.IsDebug"
value
="true"
/>
<
add
key
="SystemInit.Level"
value
="4"
/>
</
SpringOverrideProperty
>
<!--
Spirng.Net 配置
-->
<
spring
>
<
context
>
<
resource
uri
="config://spring/objects"
/>
<
resource
uri
="~/config/applicationContext.xml"
/>
<
resource
uri
="~/config/business.xml"
/>
<
resource
uri
="~/config/pageConfig.xml"
/>
</
context
>
<
objects
xmlns
="http://www.springframework.net"
/>
</
spring
>
<
system.web
>
<
httpModules
>
<
add
name
="Spring"
type
="Spring.Context.Support.WebSupportModule, Spring.Web"
/>
</
httpModules
>
<
httpHandlers
>
<
add
verb
="*"
path
="*.aspx"
type
="Spring.Web.Support.PageHandlerFactory, Spring.Web"
/>
</
system.web
>
</
httpHandlers
>
</
system.web
>
◆最后,test.aspx.cs中,这样引用前面基于IUserMainDAO接口的实现,就能让它跑起来了:
Code
#region
注入对象
private
IUserMainDAO _UserMainDaoSpring;
public
IUserMainDAO UserMainDaoSpring
{
get
{
return
_UserMainDaoSpring; }
set
{ _UserMainDaoSpring
=
value; }
}
#endregion
看起来,似乎是繁琐到发指的一些工作,不过形成习惯了应该就会喜欢上它的,眼下的麻烦只是为了避免未来更大的麻烦,图难图其易图巨图其细嘛~
相关文章推荐
- .net企业级架构实战之5——基于接口的访问层实现
- [转].net企业级架构实战之5——基于接口的访问层实现
- .net企业级架构实战之5——基于接口的访问层实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- DotNet企业级架构实战之4—Spring.net下的nHibernate数据访问模板
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- 基于.NET平台的分层架构实战(五)接口的设计与实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- 基于.NET平台的分层架构实战(五)——接口的设计与实现
- Yii2 advanced版API接口开发 基于RESTful架构的 配置、实现、测试
- 基于.NET平台的分层架构实战(八)——数据访问层的第二种实现:SQLServer+存储过程
- 基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET平台开发指南 - 实现业务
- 基于.NET平台的分层架构实战(六)——依赖注入机制及IoC的设计与实现
- 基于.NET平台的分层架构实战(七-外一篇)——对数据访问层第一种实现(Access+SQL)的重构
- 基于.NET平台的分层架构实战(九)——数据访问层的第三种实现:基于NBear框架的ORM实现
- 基于.NET平台的分层架构实战(十一)——表示层的实现
- .net企业级架构实战之4——Spring.net下的nHibernate数据访问模板