webwork+spring+ibatis存取BLOB字段

来源:百度文库 编辑:神马文学网 时间:2024/04/27 19:39:33

webwork+spring+ibatis顺利的存取BLOB字段- -
项目开发马上就要用到文件的上传、下载、照片的显示等功能,可是手头还是没有现成的解决方案,心一横,就决定今天要搞定它。
分两步走的:
1,先把文件拿到webwork的action里面。
这个我想了许多办法,多半是因为自己无知吧,先是给文件的属性设置为byte[],页面上则是,这样提交到action里面时,通过request死活拿不到文件数据,伤心了一会,上网google,终于找到一段有价值的文字,可能是robbin的原话, 在action里面定义一个 java.io.File类型的变量,名字对应你的页面中的HTML标记,这样在Action中就可以直接通过这个File对象进行文件内容的读取了,这可以用webwork自带的FileUploadInterceptor来实现,要注意的是需要在action中配置一下,而且fileUpload拦截器要放在parameter拦截器前面。嗯,喜滋滋的配之。大问题来了!!uploadManager业务类总是不能实例化,一点提交按钮,就会毫不犹豫的抛出一个nullPointException出来,更伤心了,检查了约有2-3个小时,eclipse重启n遍,脾气也火爆起来了……最后,在同事的提醒下,很不好意思的发现,在配置了FileUploadInterceptor和parameter拦截器之后,以前action共用的自动装配拦截器就给屏蔽了,这样spring就不会帮我把uploadManager给实例化……晕倒,加上autowire拦截器之后,ok,文件数据顺利到达action。
class="com.hisign.webapp.action.common.TestReportAction" method="submit">

/pages/intoReport.action





2,然后就要想办法把文件送到数据库了。
这里我先是参考http://opensource.atlassian.com/confluence/oss/display/IBATIS/How+do+I+use+a+Custom+Type+Handler+with+a+BLOB+or+CLOB%3F这里提供的方法试了一下,发现上传的文件大小果然有限制,最大为4k!!My god!赶紧放弃了……看来pojo里文件的属性不能设置为byte[]了……还是改oracle.sql.BLOB吧……
这样就出现了oracle.sql.BLOB+ibatis如何实现大文件存取的问题。我的POJO为
/**
* 主键ID
*/
private String id;
/**
* 取得主键
* @return Returns the id.
*/
public String getId() {
return id;
}
/**
* 设置主键
* @param id The id to set.
*/
public void setId(String id) {
this.id = id;
}
/**
* 二进制文件数据
*/
private BLOB data;
/**
* 获得二进制文件数据
* @return
*/
public BLOB getData() {
return this.data;
}
/**
* 设置二进制文件数据
* @param data
*/
public void setData(BLOB data) {
this.data = data;
}
先是参考http://blog.csdn.net/rosen/archive/2005/02/18/293151.aspx里提到的方法。对应的sql-map写成了







INSERT INTO
TEST_REPORT (
id, name,data)
values (
#id#,#name#, empty_blob())

按照oracle的习惯,存取一个比较大的二进制文件到数据库的blob字段中,必须先送进去一个empty_blob(),然后再马上读出来,同时锁住该记录,得到blob字段的二进制输出流,用文件的输入流往里写数据,即可。上面的SQL正好也是符合那个操作流程,其中插入数据库的业务方法主要代码如下:
dao.getSqlMapClientTemplate().insert("insertReportWithEmptyData", report);
report = (TestReport) dao.getSqlMapClientTemplate().queryForObject("findReportById",id);
BLOB blob = report.getData();
OutputStream out = blob.getBinaryOutputStream();
byte[] b = new byte[ blob.getBufferSize()];
InputStream fin = new FileInputStream(file);
int len = 0;
byte[] data  = new byte[(int)fin.available()];
fin.read(data);
out.write(data);
fin.close();
out.close();
因此以为大功即将告成,一运行马上报错,说是类型转换出错,就在从数据库中把数据读出来的时候出错的,因此问题很可能出在那个typeHandler上,找来源文件一看,里面出来的数据类型为java.sql.Blob,有些担心是不是因为java.sql.Blob不能自动转换为oracle.sql.BLOB类型,于是自做主张又写了一个typeHandler,OracleBLOBTypeHandlerCallBack类,在这个类里面,强行将java.sql.Blob转换为oracle.sql.BLOB,还是不成功,55555,这时候晚上都8点多了,晚饭还没吃,郁闷死了。
偏偏此时在google上又发现了一些关于ibatis操作blob字段的悲观看法,心理也是悲观了,就想直接去拿ibatis的java.sql.Connection来做算了,这样的话,网上的例子到处都是……
可又不太甘心,于是顺手无意把我的pojo中data的属性设置为Object,去掉了typeHandler,是想我在外边才对出来的二进制数据进行BLOB的强行转换,死马当活马医吧……
于是就好象杨过的黯然销魂掌一般,点下了提交按钮……………………
^_^,惊喜的是,系统没有报出异常信息,一查数据库,数据进去了,大于4k的!!!接连又试了几个文件,都ok,于是这一步顺利完成。
3,紧接着使用webwork的stream-result顺利实现了二进制文件在浏览器中的打开。
主要就是首先在action中得到二进制文件的输入流:
this.inputStream =this.testReportManager.getReportDataById("8CF3C311952BB91D16316E37B43659C1");
然后在xwork中作如下配置:

${fileName}
filename=${fileName}

于是大功告成,既可以显示图片,也可以实现文件下载,呵呵呵
 
- 作者:mingo 2005年07月16日, 星期六 23:36
你可以使用这个链接引用该篇日志 http://publishblog.blogdriver.com/blog/tb.b?diaryID=820453
Sat Apr 29 16:41:44 CST 2006
你好,我现在也在学习webwork+spring+ibatis,能不能给发个例子呀,真羡慕你呀,我即将可能再在开发中面临和你遇到的一样的问题,请高手多关照
Sun Aug 14 22:51:33 CST 2005
整个过程应该没有问题,因为事务的控制都是由Spring来控制的。在spring配置文件中有下面的事务控制配置:
〈property name="transactionAttributes"〉
〈props〉
〈prop key="insert*"〉PROPAGATION_REQUIRED,-AppBaseException〈/prop〉
〈prop key="update*"〉PROPAGATION_REQUIRED,-AppBaseException〈/prop〉
〈prop key="delete*"〉PROPAGATION_REQUIRED,-AppBaseException〈/prop〉
〈prop key="getNextId"〉PROPAGATION_REQUIRED〈/prop〉
〈prop key="*"〉PROPAGATION_REQUIRED,readOnly〈/prop〉
〈/props〉
〈/property〉
Fri Aug 12 10:39:13 CST 2005
你的IBATIS用法,会不会有问题,因为对ORACLE的大对象操作,在UPDATE之前是要有COMMIT(FALSE)的,你整个过程都没有提交。在你 dao.getSqlMapClientTemplate().insert("insertReportWithEmptyData", report);
和后面的语句是一个事务中么,我只是有些怀疑,如果一切正常,我会尝试用你的方法。
Tue Jul 19 19:50:36 CST 2005
发现webwork的这个文件上传拦截器的一个bug:
如果在xwork中配置了fileUpload的拦截器,那么没有选择文件就提交的话,会报空指针异常……然而我的form里还有别的数据要提交……想到webwork是开源的,喜之,改了一些webwork的源文件后重新编译,放到jar包里……可是问题又来了,改过之后即使选择了要上传的文件,后台的action里也拿不到那个file了……郁闷
只好去拿文件的filepath,然后new 一个file(path);