数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

JDBC+Hibernate将Blob数据写入Oracle


发布日期:2024年03月17日
 
JDBC+Hibernate将Blob数据写入Oracle

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) {}

}

}

}

               

上一篇:在单机上创建物理Oracle数据库9istandby

下一篇:浅谈Oracle数据库的建模与设计