使用Struts1实现文件下传(二)

使用Struts1实现文件上传(二)

      在使用Struts1实现文件上传(一)中,我将文件保存在服务器端的硬盘里,有没有办法将其保存在Oracle10g数据库中呢?答案是肯定的,只需要对程序稍加改造就可以实现将文件保存在数据库中。用到时再将文件从数据库中还原出来供用户下载。

      在数据库中保存文件的方法和保存其他基本数据类型相差不多,只是要存入即可,但是其对应的数据类型比较特殊,一般选择二进制的数据类型。Oracle10g中提供了RAW和Long RAW数据类型,这两中数据类型用于保存二进制的数据;二进制类型的好处在于当数据在不同系统之间传输时,可以不做任何数据类型的转换,方便了系统之间的操作。RAW类型的最大宽度为2000字节,而Long RAW类型的最大宽度可以达到2GB,非常适合保存图像、声音、视频等数据量较大的数据。

 

      因此,要想将文件保存在数据库中用到时在取出来,就要完成三个步骤:

 

      (1)新建Oracle10g数据表,在表中添加Long RAW类型的字段;

      (2)在程序中将上传的文件以流的形式保存到数据库中;

      (3)将文件从数据库中还原出来。

 

一、新建Oracle10g数据表

 

      在Oracle10g中新建一张数据表,如命名为UploadFiles,在表中添加相应的字段;

create table UploadFiles
(
  fileId      number not null,
  fileName    varchar2(100) not null,
  fileContent long raw not null,
  filePubDate date not null
)

      其中FileContent便是用来存放文件的Long RAW二进制数据类型。

 

二、将上传文件保存在数据库

 

      剩下的工作便是在程序中编写代码将用户上传的文件保存在数据库中了,主要的代码已经在文章“使用Struts1实现文件上传(一)”中实现,现在只需要将原来保存在文件中的部分代码替换为保存在数据库的代码即可。

UploadForm uploadForm = (UploadForm) form;
FormFile uploadFile = uploadForm.getUploadFile();

Connection conn = null;
PreparedStatement ps = null;

try {
	
	Class.forName("oracle.jdbc.driver.OracleDriver");
	conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:DataBaseName","username","password");
	String sql = "insert into pic (fileName,fileContent,filePubDate) values (?,?,?)";
	ps = conn.prepareStatement(sql);
	ps.setString(1, uploadFile.getFileName());
	ps.setBinaryStream(2, uploadFile.getInputStream(), uploadFile.getFileSize());
	ps.setDate(3, new Date());
	ps.executeUpdate();
	
} catch (Exception e) {
	e.printStackTrace();
}

      当用户点击上传后就可以将文件存储在数据库中了。

 

三、将文件从数据库中还原出来

 

      当用户需要用到文件时,就需要从数据中将文件查询出来,方法也很简单,看代码:

 

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

InputStream input = null;

try {
	
	Class.forName("oracle.jdbc.driver.OracleDriver");
	conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:DataBaseName","username","password");
	String sql = "select * from UpLoadFiles where id = 3";
	ps = conn.prepareStatement(sql);
	rs = ps.executeQuery();
	if(rs.next()){
		input = rs.getBinaryStream("pic");
	}
	
	//根据需要操作InputStream对象的代码;

	
} catch (Exception e) {
	e.printStackTrace();
} finally {
	try {
		rs.close();
		ps.close();
		conn.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
}

      将文件从数据库中读取出来后得到的将是一个InputStream类型的对象,可以根据需要操作这个对象还原文件。

 

      (完) xusweeter @ 2010年08月07日 晚 23:45 

1 楼 nao000 2011-09-08  
long raw 在hibernate映射文件的属性的type怎么弄,如下:
<property name="fileContents" type="填什么啊" column="FILECONTENTS" />