Oracle的Blob字段比较特殊他比long字段的性能要好很多可以用来保存例如图片之类的二进制数据
写入Blob字段和写入其它类型字段的方式非常不同因为Blob自身有一个cursor你必须使用cursor对blob进行操作因而你在写入Blob之前必须获得cursor才能进行写入那么如何获得Blob的cursor呢?
这需要你先插入一个empty的blob这将创建一个blob的cursor然后你再把这个empty的blob的cursor用select查询出来这样通过两步操作你就获得了blob的cursor可以真正的写入blob数据了
看下面的JDBC的demo把oraclejdbcjar这个二进制文慈胧菘獗韏avatest的content字段(这是一个blob型字段)
import javasql*;
import javaio*;
import oraclesql*;
public class WriteBlob {
public static void main(String[] args) {
try {
DriverManagerregisterDriver(new oraclejdbcdriverOracleDriver());
Connection conn = DriverManagergetConnection(jdbc:oracle:thin:@localhost::orclfankaifankai);
connsetAutoCommit(false);
BLOB blob = null;
PreparedStatement pstmt = connprepareStatement(insert into javatest(namecontent) values(?empty_blob()));
pstmtsetString(fankai);
pstmtexecuteUpdate();
pstmtclose();
pstmt = connprepareStatement(select content from javatest where name= ? for update);
pstmtsetString(fankai);
ResultSet rset = pstmtexecuteQuery();
if (rsetnext()) blob = (BLOB) rsetgetBlob();
String fileName = oraclejdbcjar;
File f = new File(fileName);
FileInputStream fin = new FileInputStream(f);
Systemoutprintln(file size = + finavailable());
pstmt = connprepareStatement(update javatest set content=? where name=?);
OutputStream out = blobgetBinaryOutputStream();
int count = total = ;
byte[] data = new byte[(int)finavailable()];
finread(data);
outwrite(data);
/*
byte[] data = new byte[blobgetBufferSize()]; 另一种实现方法节省内存
while ((count = finread(data)) != ) {
total += count;
outwrite(data count);
}
*/
finclose();
outclose();
pstmtsetBlob(blob);
pstmtsetString(fankai);
pstmtexecuteUpdate();
pstmtclose();
mit();
connclose();
} catch (SQLException e) {
Systemerrprintln(egetMessage());
eprintStackTrace();
} catch (IOException e) {
Systemerrprintln(egetMessage());
}
}
}
仔细看上例分三步
插入空blob
into javatest(namecontent) values(?empty_blob());
获得blob的cursor
select content from javatest where name= ? for update;
注意!!!必须加for update这将锁定该行直至该行被修改完毕保证不产生并发沖突
update javatest set content=? where name=
用cursor往数据库写数据
这里面还有一点要提醒大家
JDK带的JDBC规范是不完善的只有读Blob的接口而没有写Blob的接口JDK带的JDBC加入了写Blob的接口你可以使用JDBC的接口也可以直接使用Oracle的JDBC的API我在上例中使用了Oracle的JDBC的API
另外要注意的是
javasqlBlob
oraclesqlBLOB
注意看blob的大小写是不一样的写程序的时候不要搞混了
下面看看用Hibernate怎么写原理是一样的也要分三步但是代码简单很多
这是Cat对象定义
package comfankai;
import javasqlBlob;
public class Cat {
private String id;
private String name;
private char sex;
private float weight;
private Blob image;
public Cat() { }
public String getId() { return id; }
public void setId(String id) { thisid = id; }
public String getName() { return name; }
public void setName(String name) { thisname = name; }
public char getSex() { return sex; }
public void setSex(char sex) { thissex = sex; }
public float getWeight() { return weight; }
public void setWeight(float weight) { thisweight = weight; }
public Blob getImage() { return image; }
public void setImage(Blob image) { thisimage = image;}
}
这是Cathbmxml
<?xml version=?>
<!DOCTYPE hibernatemapping SYSTEM >
<hibernatemapping>
<class name=comfankaiCat table=cat>
<!jcscache usage=readonly/>
<id name=id unsavedvalue=null>
<generator class=uuidhex/>
</id>
<property name=name length= notnull=true/>
<property name=sex length= notnull=true/>
<property name=weight />
<property name=image />
</class>
</hibernatemapping>
下面是完整的用Hibernate写入Blob的例子相比JDBC已经简单轻松多了也不用写那些Oracle特殊的sql了
package comfankai;
import javasqlBlob;
import netsfhibernate*;
import oraclesql*;
import javaio*;
public class TestCatHibernate {
public static void testBlob() {
Session s = null;
byte[] buffer = new byte[];
buffer[] = ;
try {
SessionFactory sf = HibernateSessionFactorygetSessionFactory();
s = sfopenSession();
Transaction tx = sbeginTransaction();
Cat c = new Cat();
csetName(Robbin);
csetImage(HibernatecreateBlob(buffer));
ssave(c);
sflush();
srefresh(c LockModeUPGRADE);
BLOB blob = (BLOB) cgetImage();
OutputStream out = blobgetBinaryOutputStream();
String fileName = oraclejdbcjar;
File f = new File(fileName);
FileInputStream fin = new FileInputStream(f);
int count = total = ;
byte[] data = new byte[(int)finavailable()];
finread(data);
outwrite(data);
finclose();
outclose();
sflush();
mit();
} catch (Exception e) {
Systemoutprintln(egetMessage());
} finally {
if (s != null)
try {
sclose();
} catch (Exception e) {}
}
}
}