在持久化类中,二进制大对象可以声明为byte[]或java.sql.Blob类型;字符串大对象可以声明为java.lang.String或java.sql.Clob类型。
java.sql.Blob和java.sql.Clob是JDBC API中的接口。在默认情况下,Blob和Clob接口的实现会使用SQL定位器,这意味着当程序从数据库加载Blob类型或Clob类型的数据时,实际上加载的仅是Blob类型或Clob类型的数据的逻辑指针。接下来程序需要通过Blob.getBinaryStream()或Clob.getCharacterStream()方法得到Blob或Clob类型的数据的输入流,才可以真正读取到大对象数据。
对于以下程序代码:
Customer customer=entityManager.find(Customer.class,
Long.valueOf(1); //第1行
Blob image=customer.getImage(); //第2行
InputStream in=image.getBinaryStream(); //第3行
第2行的image变量引用的只是数据库中Blob类型的数据的逻辑指针。第3行通过image.getBinaryStream()方法得到Blob类型的数据的输入流,才可以真正读取到数据库中的大对象数据。
org.hibernate.LobHelper接口提供了一系列用于创建Blob和Clob对象的方法:
- public Blob createBlob(byte[] bytes)
- public Blob createBlob(InputStream stream, long length)
- public Clob createClob(String string)
- public Clob createClob(Reader reader, long length)
Hibernate的Session接口的getLobHelper()方法返回一个LobHelper对象。
假定Customer类的image属性为java.sql.Blob类型,在MySQL数据库中CUSTOMERS表的IMAGE字段为BLOB类型。在Customer类中,映射image属性的代码如下:
@Column(name="IMAGE")
@Type(type="blob")
private Blob image;
此外,JPA API还提供了一个@Lob注解,用来映射Blob或Clob类型的属性。因此,也可以用@Lob注解来映射image属性:
@Column(name="IMAGE")
@Lob
private Blob image;
以下BusinessService类演示了保存和加载具有Blob类型的image属性的Customer对象的过程。
/* BusinessService.java */
public class BusinessService{
public static EntityManagerFactory entityManagerFactory;
static{……} //初始化Hibernate
public Long saveCustomer()throws Exception{ //保存Customer对象
//读取photo.gif文件的二进制数据
InputStream in=this.getClass()
.getResourceAsStream("photo.gif");
byte[] buffer = new byte[in.available()];
in.read(buffer);
in.close();
EntityManager entityManager =
entityManagerFactory.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
Customer customer=new Customer();
customer.setName("Tom");
Session session=entityManager.unwrap(Session.class);
customer.setImage(
session.getLobHelper().createBlob(buffer));
entityManager.persist(customer);
tx.commit();
entityManager.close();
return customer.getId();
}
public void loadCustomer(Long id) throws Exception{
EntityManager entityManager =
entityManagerFactory.createEntityManager();
EntityTransaction tx = entityManager.getTransaction();
tx.begin();
Customer customer=
entityManager.find(Customer.class,id);
getBlob(customer);
tx.commit();
entityManager.close();
}
public void getBlob(Customer customer)throws Exception{
//把Blob对象保存到photo_bak.gif文件中
Blob image=customer.getImage();
InputStream in=image.getBinaryStream();
FileOutputStream fout = new FileOutputStream("photo_bak.gif");
int b=-1;
while((b=in.read())!=-1)
fout.write(b);
fout.close();
in.close();
}
public void test() throws Exception{
Long id=saveCustomer();
loadCustomer(id);
}
public static void main(String args[]) throws Exception {
new BusinessService().test();
entityManagerFactory.close();
}
}

这篇博客详细介绍了如何在JPA和Hibernate中处理Blob和Clob类型的数据。通过Java.sql.Blob和Java.sql.Clob接口,以及Hibernate的LobHelper,讨论了数据的逻辑指针和实际读取过程。文中还展示了如何在持久化类中映射这些大对象,并提供了示例代码,包括使用@Lob注解的方式。
590

被折叠的 条评论
为什么被折叠?



