论坛首页 Java版

一个自定义attribute class的例子

浏览 9690 次
该帖已经被评为精华帖
作者 正文
时间:2004-09-14
我除了用DotNet自身的attribute外, 也在项目里写过一些自定义的attribute class, 下面是我写的一个用attribute class来调用oracle stored proc的例子.

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

我写了一个DAO, 代码基本上象这样

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需修改.
   
时间:2004-09-14
代码生成绝对不是一个好的做法。为什么要有attribute?就是为了让你可以在runtime resolve一些metadata,避免依赖代码生成。
   
0 请登录后投票
时间:2004-09-14
gigix 写道
代码生成绝对不是一个好的做法。为什么要有attribute?就是为了让你可以在runtime resolve一些metadata,避免依赖代码生成。


不能一概而论, 代码生成在某些情况使用下还是很好的, 前题是生成的代码在独立文件中, 不可手工修改, 比如在web service中无论java还是.net都用代码生成器利用wsdl生成client端proxy class, 我的这个例子也是用来生成oracle stored proc的client端proxy class。 这种方法在CORBA里也广泛用到
   
0 请登录后投票
时间:2004-09-14
但是client端proxy根本不需要代码生成,只要用动态代理就可以了,你想想是不是这么个道理?总之client从某个工厂去取proxy,取到的是具有业务接口的一个动态代理,至于怎么调用远程方法,都在动态代理里做。你看看Hessian的ProxyFactory就知道了。

client端proxy是个很好的例子,它非常有力地说明:需要代码生成的大多数情况是Java 1.1或者1.2时的情况,当我们拥有动态代理之后,很多代码生成都是不必要的。
   
0 请登录后投票
时间:2004-09-14
gigix 写道
但是client端proxy根本不需要代码生成,只要用动态代理就可以了,你想想是不是这么个道理?总之client从某个工厂去取proxy,取到的是具有业务接口的一个动态代理,至于怎么调用远程方法,都在动态代理里做。你看看Hessian的ProxyFactory就知道了。

client端proxy是个很好的例子,它非常有力地说明:需要代码生成的大多数情况是Java 1.1或者1.2时的情况,当我们拥有动态代理之后,很多代码生成都是不必要的。


动态代理会丢掉compile checking的优势, 想想我们为啥做daily build, 在大型项目里用动态代理绝对不是个好主意
   
0 请登录后投票
时间:2004-09-14
这话奇怪了,动态代理怎么会丢掉compile checking呢?比如Hessian,我们首先定义一个接口:

[code:1]
public interface IMyService {
public void doSomething() {
[/code:1]

然后实现server端:

[code:1]
public class MyServiceImpl
extends HessianServlet
implements IMyService
{
public void doSomething() {
[/code:1]

最后client端这样进行RPC:

[code:1]
IMyService service = HessianProxyFactory.createProxy(url, IMyService.class);
service.doSomething();
[/code:1]

请问,我在哪个环节上失去了compile checking?哪个环节不适合在大型项目使用?
   
0 请登录后投票
时间:2004-09-14
我问你, 你这个IMyService 是哪来的, 你这个doSomething() 又是那来的,
当你拿到一个别人的wsdl, 你怎样写个动态proxy出来
   
0 请登录后投票
时间:2004-09-14
原来你的意思是使用外部的web service,那肯定要生成代码了,没办法的事。
   
0 请登录后投票
时间:2004-09-14
gigix 写道
原来你的意思是使用外部的web service,那肯定要生成代码了,没办法的事。


外部内部有区别吗?
   
0 请登录后投票
时间:2004-09-14
当然有区别。如果是我自己的几个application之间需要remoting,我就可以在它们之间共享同样的Java接口,于是就变成我举的代码示例那样,不需要生成任何代码。
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐