elegant coding
elegant coding with c#, Oracle, delphi and java

导航

 
我除了用DotNet自身的attribute外, 也在项目里写过一些自定义的attribute class, 下面是我写的一个用attribute class来调用oracle stored proc的例子.

我有一个oracle package ”TestPkg”, 包括一个procedure “Get_Peoples” 我传一个company_id 给他, 他返回一个oralce ref_cursor, 里包含几行people记录。

我写了一个DAO (Data Access Object), 代码基本上象这样

Class TestPkg : OraclePackageBase{
..
//定义Get_Peoples的OracleCommandMethodAttribute的meta data
[OracleCommandMethod(CommandType.Text, CommandText = 'begin :function_result := TestPkg.. Get_Peoples (:company_id); end; ')]
Public OracleDataReader Get_Peoples(
//定义company_id的OracleParameterAttribute的meta data
[OracleParameter (ParamType = OracleType.NUMBER, Size = 22)]
int company_id
)
OracleCommand FCmd:
Object[] FParamValues = new Object[1];
//把参数放到一个array里
FParamValues[0] = company_id;
//利用MethodInfo和参数array生成oraclecommand对象
FCmd = OracleCommandGenerator.Create().GenerateCommand(this.Connection,
MethodInfo(MethodBase.GetCurrentMethod), FParamValues);
FCmd.Transaction = this.Transaction;
//调用oracle stored proc
FCMD.ExecuteNonQuery();
//得到返回值
for (i = 0 ; FCMD.Parameters.Count ; i++)
{
if (FCMD.Parameters[i].Direction == ParameterDirection.Output) &&
(FCMD.Parameters[i].ParameterName == “function_result”)
{

return OracleDataReader(FCMD.Parameters[i].Value);

}
}
}

这里用到我另外写的两个attribute class, OracleCommandMethodAttribute和OracleParameterAttribute. 和两个类OraclePackageBase和OracleCommandGenerator.

OraclePackageBase类用来初始化一些环境变量,如connection, transaction啥的, 在DAO method里, 我传递MethodInfo 对象进OracleCommandGenerator.GenerateCommand方法, 在GenerateCommand方法里用OracleCommandMethodAttribute和OracleParameterAttribute得到并较验attribute meta data, 然后生成OracleCommand对象来调用oracle procedure. 并得到返回值

这样一来, DAO class里不同method的代码基本相同, 需要替换的只有以及class method的名字和参数和他上面附加的两个attribute的参数, 我就写了一个code generator根据oracle package来生成这个DAO. Oracle package的meta 信息来自oracle sys view “dba_source”, 我写了一个VS.net的plug-In去仿问这个view, 得到各stored procedure 名字和参数,用一个XSL文件保存DAO code template, 然后用上面得到oracle package的procedure 名字和参数替换掉template 里的动态variable, loop一下就可以了.

上面的code generator也可写成在runtime动态生成代码, Dotnet提供了codeDom类来动态生成代码,象java 里的CGLib, 不过考虑到效率和package变动问题, 我还是用code generator, 就象web sevice里处理wsdl一样。每当oracle package变动, 我只要用plugIn重生成新代码, build时IDE会告诉哪些调用code需修改.
posted on 2004-11-08 11:29  yyanghhong  阅读(1002)  评论(1编辑  收藏  举报