操纵Blob和Clob类型数据(1)
http://book.51cto.com/art/201001/179042.htm
本章11.1.3节介绍了二进制大对象及字符串大对象的映射方法。在持久化类中,二进制大对象可以声明为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=(Customer)session.get(Customer.class,new Long(1);//第1行 Blob image=customer.getImage(); //第2行 InputStream in=image.getBinaryStream(); //第3行 第2行的image变量引用的只是数据库中Blob类型的数据的逻辑指针。第3行通过image.getBinaryStream()方法得到Blob类型的数据的输入流,才可以真正读取到数据库中的大对象数据。
org.hibernate.Hibernate类提供了一系列用于创建Blob和Clob对象的静态方法:
public static Blob createBlob(byte[] bytes) public static Blob createBlob(InputStream stream, int length) public static Blob createBlob(InputStream stream) public static Clob createClob(String string) public static Clob createClob(Reader reader, int length) 假定Customer类的image属性为java.sql.Blob类型,在MySQL数据库中CUSTOMERS表的IMAGE字段为BLOB类型,在Customer.hbm.xml文件中映射image属性的代码如下:
<property name="image" type="blob" column="IMAGE"/> 以下例程11-12的BusinessService类演示了保存和加载具有Blob类型的image属性的Customer对象的过程。
例程11-12 BusinessService.java
package mypack; …… public class BusinessService{ public static SessionFactory sessionFactory; 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(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=new Customer(); customer.setName("Tom"); //创建一个Blob对象 customer.setImage(Hibernate.createBlob(buffer)); session.save(customer); tx.commit(); session.close(); return customer.getId(); } public void loadCustomer(Long id) throws Exception{ //加载Customer对象 Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=(Customer)session.get(Customer.class,id); getBlob(customer); tx.commit(); session.close(); } public void getBlob(Customer customer)throws Exception{ //把Blob对象保存到chapter11/11.3/photo_bak.gif文件中 Blob image=customer.getImage(); InputStream in=image.getBinaryStream(); FileOutputStream fout = new FileOutputStream("11.3\\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(); sessionFactory.close(); } } 本节范例位于配套光盘的sourcecode/chapter11/11.3目录下。在DOS下转到本例的根目录/chapter11下,输入命令:ant -file build3.xml run,该命令将依次执行prepare target、compile target、schema target和run target。run target命令则运行BusinessService类。
对于MySQL数据库系统,可以通过以下方式,在保存Customer对象的同时保存它的Blob类型的属性:
Customer customer=new Customer(); customer.setName("Tom"); //创建一个Blob对象 customer.setImage(Hibernate.createBlob(buffer)); session.save(customer); 对于有些数据库系统,可能需要先保存一个空的Blob或Clob实例。然后锁定数据库中的相应记录,更新它的Blob或Clob实例,把二进制数据或长文本数据写到Blob或Clob实例中。以下是按这种方式保存Customer对象的saveCustomer()方法:
public Long saveCustomer() throws Exception{ //读取photo.gif文件的二进制数据 InputStream in=this.getClass().getResourceAsStream("photo.gif"); byte[] buffer = new byte[in.available()]; in.read(buffer); in.close(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=new Customer(); customer.setName("Tom"); //创建一个空的Blob对象 customer.setImage(Hibernate.createBlob(new byte[1])); session.save(customer); //保存Customer对象 session.flush(); //清理缓存 //锁定这条记录 session.refresh(customer, LockMode.UPGRADE); java.sql.Blob image = customer.getImage(); OutputStream out=image.setBinaryStream(1); out.write(buffer); //把图片文件的二进制数据写到Blob对象中 out.close(); tx.commit(); session.close(); return customer.getId(); }
http://book.51cto.com/art/201001/179042.htm
本章11.1.3节介绍了二进制大对象及字符串大对象的映射方法。在持久化类中,二进制大对象可以声明为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=(Customer)session.get(Customer.class,new Long(1);//第1行 Blob image=customer.getImage(); //第2行 InputStream in=image.getBinaryStream(); //第3行 第2行的image变量引用的只是数据库中Blob类型的数据的逻辑指针。第3行通过image.getBinaryStream()方法得到Blob类型的数据的输入流,才可以真正读取到数据库中的大对象数据。
org.hibernate.Hibernate类提供了一系列用于创建Blob和Clob对象的静态方法:
public static Blob createBlob(byte[] bytes) public static Blob createBlob(InputStream stream, int length) public static Blob createBlob(InputStream stream) public static Clob createClob(String string) public static Clob createClob(Reader reader, int length) 假定Customer类的image属性为java.sql.Blob类型,在MySQL数据库中CUSTOMERS表的IMAGE字段为BLOB类型,在Customer.hbm.xml文件中映射image属性的代码如下:
<property name="image" type="blob" column="IMAGE"/> 以下例程11-12的BusinessService类演示了保存和加载具有Blob类型的image属性的Customer对象的过程。
例程11-12 BusinessService.java
package mypack; …… public class BusinessService{ public static SessionFactory sessionFactory; 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(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=new Customer(); customer.setName("Tom"); //创建一个Blob对象 customer.setImage(Hibernate.createBlob(buffer)); session.save(customer); tx.commit(); session.close(); return customer.getId(); } public void loadCustomer(Long id) throws Exception{ //加载Customer对象 Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=(Customer)session.get(Customer.class,id); getBlob(customer); tx.commit(); session.close(); } public void getBlob(Customer customer)throws Exception{ //把Blob对象保存到chapter11/11.3/photo_bak.gif文件中 Blob image=customer.getImage(); InputStream in=image.getBinaryStream(); FileOutputStream fout = new FileOutputStream("11.3\\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(); sessionFactory.close(); } } 本节范例位于配套光盘的sourcecode/chapter11/11.3目录下。在DOS下转到本例的根目录/chapter11下,输入命令:ant -file build3.xml run,该命令将依次执行prepare target、compile target、schema target和run target。run target命令则运行BusinessService类。
对于MySQL数据库系统,可以通过以下方式,在保存Customer对象的同时保存它的Blob类型的属性:
Customer customer=new Customer(); customer.setName("Tom"); //创建一个Blob对象 customer.setImage(Hibernate.createBlob(buffer)); session.save(customer); 对于有些数据库系统,可能需要先保存一个空的Blob或Clob实例。然后锁定数据库中的相应记录,更新它的Blob或Clob实例,把二进制数据或长文本数据写到Blob或Clob实例中。以下是按这种方式保存Customer对象的saveCustomer()方法:
public Long saveCustomer() throws Exception{ //读取photo.gif文件的二进制数据 InputStream in=this.getClass().getResourceAsStream("photo.gif"); byte[] buffer = new byte[in.available()]; in.read(buffer); in.close(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Customer customer=new Customer(); customer.setName("Tom"); //创建一个空的Blob对象 customer.setImage(Hibernate.createBlob(new byte[1])); session.save(customer); //保存Customer对象 session.flush(); //清理缓存 //锁定这条记录 session.refresh(customer, LockMode.UPGRADE); java.sql.Blob image = customer.getImage(); OutputStream out=image.setBinaryStream(1); out.write(buffer); //把图片文件的二进制数据写到Blob对象中 out.close(); tx.commit(); session.close(); return customer.getId(); }