惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
S
Securelist
D
Docker
The Register - Security
The Register - Security
GbyAI
GbyAI
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
罗磊的独立博客
博客园 - 【当耐特】
F
Full Disclosure
WordPress大学
WordPress大学
腾讯CDC
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
SecWiki News
SecWiki News
L
Lohrmann on Cybersecurity
I
InfoQ
MyScale Blog
MyScale Blog
量子位
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
The Hacker News
The Hacker News
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
博客园_首页
H
Help Net Security
K
Kaspersky official blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Blog — PlanetScale
Blog — PlanetScale
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
The Cloudflare Blog
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
爱范儿
爱范儿
P
Privacy International News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
B
Blog RSS Feed

博客园 - 一江秋水

oracle 数据库 web 开发 正则表达式 职业生涯【3】认真对待选择 职业生涯【2】选择行业、领导 职业生涯【1】选择职业 IE8正在连接(二级页面无法打开) Win7允许/禁用 PING命令 SQL2008 安装后启用 Sa 用户的方法 - 一江秋水 项目计划管理--(摘录) 如何收缩和删除SQL日志文件 IBatis—源码解析【DataMapper】 Ibatis—源码解析【Common】 JavaScript中Eval详解 JavaScript调用WebServices sql server中的varchar和Nvarchar有什么区别 自动从起数据库服务 DataGridView显示行号 中国移动的短信息服务中心 - 一江秋水 - 博客园 Socket(同步与异步) C# 中用Socket实现判断网络是否断开的实例
IBatis—源码解析【DataAccess】
一江秋水 · 2009-06-08 · via 博客园 - 一江秋水

   DataAccess是一个DAO框架,可以通过配置文件配置应用程序使用的DAO实现,并且自己提供了几个具体数据访问方式的包装,以简化DAO实现层开发。
   DataAccess的源代码相对于DataMapper要简单的多。
一.关键类
1.Configuration目录
   定义了DataAccess的模型,该模型和xml配置文件对应,因此该目录同时提供了从xml配置文件解析为DataAccess对象模型和将对象模型序列化为xml文件的功能。
2.Exceptions目录
   Exceptions目录中只有一个DataAccessException异常类。DataAccess框架产生的异常会被包装为该类。
3.Interfaces目录
  Interfaces目录定义了两个接口:IDao和IDaoSessionHandler。IDao是我们自己的DAO实现类必须继承的标志接口。IDaoSessionHandler定义了不同会话处理器(SessionHandler)的通用接口。用于从配置Dao管理器相关的信息,并获取当前的DaoSession。
4.Scope目录
   维护当前的配置和错误信息。
5.DaoSessionHandlers目录
   DaoSessionHandlers目录包含对ADO.NET和SqlMap的包装。比如SimpleDaoSession 是 An ADO.NET implementation of the DataAccess Session .SqlMapDaoSession 是 An SqlMappper implementation of the DataAccess Session.这两个类都实现了IDaoSession,用来处理会话相关的连接,事务等。SimpleDaoSessionHandler和SqlMapDaoSessionHandler类都实现了IDaoSessionHandler接口,用于从解析后的配置信息中获取DaoSession和其相关的配置。
6.主目录
   SessionHolder类和java中的ThreadLocal类似,为每个线程维护一个IDalSession。
DaoManager是一个Facade类,复杂读取配置文件并初始化框架;为不同的context维护不同的配置信息;提供访问DAO实现的方法;提供访问当前Session中的连接(connection)和事务(transaction)方法。

二.使用简介和框架执行流程
DataAccess框架(图略):
由于DataAccess可以和任何DAO实现工作,核心库中提供了对ADO.NET和SqlMap(也就是DataMapper)的封装,扩展库中提供了对NHibernate的封装,利用这些封装编成很更简单,更实用。DataAccess文档上说:
if your application is using raw ADO, the DAO framework will hide classes like DataReader, DataAdapter, Connection, and Command. Similarly, if your application is using the NHibernate object persistence library, the DAO framework will hide classes like Configuration, SessionFactory, Session, and HibernateException. All of these implementation details will be hidden behind a consistent DAO interface layer. Furthermore, the number of different data sources that are being used can be hidden from the view of the application.
这里只简单介绍DataAccess和DataMapper配合使用,DataMapper的类和配置利用以上介绍的DataMapper中的例子。
DataAccess的使用需要以下几个步骤:
1.设计DAO接口。
2.选择一种DAO实现。
3.编写dao.config配置文件。
4.利用DAO进行数据操作。
由于DataAccess框架要求每个DAO实现类,必须实现IDao接口,即然利用DAO框架编程,我们必须定义自己的DAO接口。作为最佳实践可以这样设计:
1).我们自己的DAO接口应该是和任何框架无关的,也就是我们的DAO接口不需要继承自IDao接口,而且所有的DAO接口在一个或几个项目中,最后打包为一个或几个dll中,例如:
namespace dao
{
public interface IProduct
{
IList GetProductList();
void UpdateProduct(Product pro);
}
}
2).设计一个BaseDao基类,该类封装了一种具体的DAO实现的数据访问方法并且实现IDao标志接口,例如我们利用SqlMapper作为数据持久层,BaseDao可以这样设计:
namespace impl
{
public class BaseDao : IDao
{
protected const int PAGE_SIZE = 4;
///
/// Looks up the parent DaoManager, gets the local transaction
/// (which should be a SqlMapDaoTransaction) and returns the
/// SqlMap associated with this DAO.
///
/// The SqlMap instance for this DAO.
protected SqlMapper GetLocalSqlMap()
{
DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
builder.Configure();
DaoManager daoManager = DaoManager.GetInstance(this);
SqlMapDaoSession sqlMapDaoSession = (SqlMapDaoSession)daoManager.LocalDaoSession;
return sqlMapDaoSession.SqlMap;
}
///
/// Simple convenience method to wrap the SqlMap method of the same name.
/// Wraps the exception with a DataAccessException to isolate the SqlMap framework.
///
protected IList ExecuteQueryForList(string statementName, object parameterObject)
{
SqlMapper sqlMap = GetLocalSqlMap();
try
{
return sqlMap.QueryForList(statementName, parameterObject);
}
catch (Exception e)
{
throw new DataAccessException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e);
}

/// Simple convenience method to wrap the SqlMap method of the same name.
/// Wraps the exception with a DataAccessException to isolate the SqlMap framework.
///
protected IList ExecuteQueryForList(string statementName, object parameterObject, int skipResults, int maxResults)
{
SqlMapper sqlMap = GetLocalSqlMap();
try
{
return sqlMap.QueryForList(statementName, parameterObject, skipResults, maxResults);
}
catch (Exception e)
{
throw new DataAccessException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e);
}
}
...................
}
}
3).我们的具体DAO实现类继承自BaseDao,并实现自己的DAO接口。并利用BaseDao提供的基础功能工作,而且所有的DAO实现在一个或几个项目中,最后打包为一个或几个dll中,这样以后可以简化维护并方便修改daofactory的配置,例如:
namespace impl
{
public class ProductDAO : BaseDao, IProduct
{
#region IProduct Members
public IList GetTheProductList()
{
IList prods = base.ExecuteQueryForList("getProduct", null);
Console.WriteLine("public System.Collections.IList GetProductList():");
foreach (Product p in prods)
{
Console.WriteLine("id:{0};Org:{1};PlatId:{2}", p.Id, p.Org, p.PlatId);
}
return prods;
}
public void UpdateTheProduct(Product pro)
{
base.ExecuteUpdate("updateNews", pro);
Console.WriteLine("public void UpdateProduct(Domain.Product pro) finished.");
}
#endregion
}
}
配置文件--dao.config
xml version="1.0" encoding="utf-8"?>
<daoConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<providers resource="providers.config"/>
<context id="SqlMapDao" default="true">
<database>
<provider name="oracle9.2"/>
<dataSource name="ibatisDemo" connectionString="Data Source=DATA-89;Persist Security Info=True;User ID=data;password=data"/>
database>
<daoSessionHandlers>
<daoSessionHandler id="SqlMap">
<property name="resource" value="sqlMap.config"/>
daoSessionHandler>
daoSessionHandlers>
<daoFactory>
<dao interface="dao.IProduct,dao" implementation="impl.ProductDAO,impl"/>
daoFactory>
context>
daoConfig>
使用DAO实现操作数据存储
namespace OraTest
{
class Program
{
public static void Main()
{
public static void Main()
{
//读取配置文件创建DaoManager,并获取SqlMapDao context实例。
DomDaoManagerBuilder builder = new DomDaoManagerBuilder();
builder.Configure();
DaoManager daoManager = DaoManager.GetInstance("SqlMapDao");
//获取IProductDAO接口的具体实现类,并初始化。
IProduct dao = daoManager[typeof(IProduct)] as IProduct;
//利用DAO编程。
dao.GetProductList();
Product p = new Product();
p.Id = "FR20T0000003000000096426";
p.Org = "orgid2";
dao.UpdateProduct(p);
}
}
}