日期:2014-05-16 浏览次数:20544 次
最近学Oracle,正好单位OA中Word文件是将文件用BASE64方式编码后用CLOB型写入数据库的,因此有心测试JDBC对CLOB型的操作(百度的排版好像不太好用,凑合看吧)。
准备工作:
一、去http://commons.apache.org/codec/下载BASE64的编解码包
二、去http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html下载10G以后的ojdbc14.jar,用9i自带的的ojdbc14.jar在使用第二种方法的时候不能超过4000字节
三、登录到Oracle,将hr用户解锁,建立测试表test,SQLPLUS怎么用俺就不说了
conn / as sysdba;
alter user hr account unlock;
alter user hr identified by hr;
create table test(c1 varchar2(10),t1 clob);
四、建立JAVA程序
import java.io.IOException;
import java.io.*;
import java.sql.*;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.EncoderException;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Base64Encode {
public static void main(String[] args) throws EncoderException,
DecoderException, IOException, SQLException {
//打开文件
FileInputStream fsin=new FileInputStream("oracle 体系结构.doc");
//看看可以读出多少字节
int fbytes=fsin.available();
//请求分配内存并读入文件到inbuf
byte[] inbuf=new byte[fbytes];
fsin.read(inbuf);
//关闭文件
fsin.close();
//新建一个BASE64编解码对象
Base64 base64 = new Base64();
//对inbuf中的内容进行编码
byte[] bytes = base64.encode(inbuf);
//测试写入数据库
dbwriter.writedb(bytes);
//从数据库读取数据
bytes=dbwriter.readdb();
//将读到的数据解码
byte[] outbuf=base64.decode(bytes);
//将解码后的数据输出到文件output.doc
FileOutputStream fsout=new FileOutputStream("output.doc");
fsout.write(outbuf);
fsout.flush();
fsout.close();
}
}
class dbwriter{
static Connection conn;
//方法一和方法二只能选一个编译
//方法一:使用游标对CLOB型进行操作,此方法网上流传甚广,虽然正确,但无比麻烦,对数据库的操作也很啰嗦
static void writedb(byte[] arg) throws SQLException,IOException
{
// 使用Class对象的forName方法动态加载类
try
{
Class.forName ("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
//连接Oracle
conn = DriverManager.getConnection ("jdbc:oracle:thin:@127.0.0.1:1521:student", "hr", "hr");
// @machine:port:SID,??? userid,?? password
//关闭自动提交,JDBC默认竟然是自动提交,嘿嘿,如果不关闭自动提交,后面更新数据时会出现更新顺序错误,ORACLE的错误号不记得了
conn.setAutoCommit(false);
//插入一行数据,必须先插入一个空的CLOB数据,便于后面获取CLOB的locator ????????????????????
PreparedStatement stmt = conn.prepareStatement("insert into test(c1,t1) values ('1',empty_clob())");
stmt.executeUpdate();
//注意SQL语句中的For update,使游标可更新,我对JAVA不熟,应该这样就是可更新游标了吧
stmt=conn.prepareStatement("select t1 from test where c1=? for update");
stmt.setString(1,"1");
ResultSet rset=stmt.executeQuery();
rset.next();
oracle.sql.CLOB lclob=(oracle.sql.CLOB)rset.getClob("t1");
//从CLOB型获取写入流
OutputStream writer = lclob.getAsciiOutputStream();
//将数据写入CLOB
writer.write(arg);
//关闭写入流
writer.close();
//提交等维护工作
conn.commit();
rset.close();
stmt.close();
conn.close();
}
//方法二:使用preparedStatement.setString()方法,比第一种方法简单清楚太多,推荐
static void writedb(byte[] arg) throws SQLException,IOException
{
// 使用Class对象的forName方法动态加载类
try
{
Class.forName ("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
conn = DriverManager.getConnection
("jdbc:oracle:thin:@127.0.0.1:1521:student", "hr", "hr");
// @machine:port:SID,??? userid,?? password
conn.setAutoCommit(false);??????????????????????
PreparedStatement stmt = conn.prepareStatement("insert into test(c1,t1) values ('1',?)");
stmt.setString(1,new String(arg)); //要用10g以后的ojdbc14.jar
stmt.executeUpdate();
conn.commit();
st