posts - 66,  comments - 11,  trackbacks - 0
Blob、Clob字段的映射
     Blob和Clob字段的区别在于,Blob字段采用单字节存储,适合保存二进制数据,如图片文件。Clob字段采用多字节存储,适合保存大型文本数据。
     在Oracle中Blob/Clob字段独特的访问方式,Oracle Blob/Clob字段本身拥有一个游标,JDBC必须必须通过游标对Blob/Clob字段进行操作,在Blob/Clob字段被创建之前,我们无法获取其游标句柄,这也意味着,我们必须首先创建一个空Blob/Clob字段,再从这个空Blob/Clob字段获取游标,写入我们所期望保存的数据。

    实体粒度设计:
    在Hibernate世界里,我们经常听到"fine-grained object model"直接翻译就是适当的细粒度对象模型。
    适当的比较模糊,细粒度就是将原本业务模型中的对象加以细分,从而得到更加精细的对象模型。就是划分出更多的对象。分为:面向设计的细粒度划分和面向性能的细粒度划分。
    对于单表的对象细分,在Hibernate中可借助Component节点的定义来完成。何谓Component?从名字上来看,既然称之为组件,则其必然是从属于某个整体的一个组成部分。在Hibernate语义中,我们将某个实体对象中的一个逻辑组成成为Component.Component与实体对象的根本差别,就在于Component没有标示,它作为一个逻辑组成,完全从属于实体对象。通过Component定义,我们将T_User表实际映射到了3个类,TUser,Contact和Name,这样我们就可以在传统关系型库表上,实现了面向对象的领域划分。
    面向性能的细粒度划分:
    当我们通过Hibernate加载TUser对象时,Hibernate会从库表中读取所有的字段数据,并构造TUser实例返回。这里就产生了一个性能方面的问题,作为blob/clob等重量级字段类型,数据库读取操作代价较高。对于需要处理resume和image的应用逻辑而言,这样的代价无法避免,而对于那些无需resume和image信息的操作而言,如此性能无谓的损耗实在可惜。
    如何避免这个问题,Hibernate3提供了属性的延迟加载功能,通过这个功能,我们可以在调用TUser.getResume/getImage时才真正从数据库中读取数据。对于hibernate2来说我们通过继承关系,我们将一个对象进行纵向细分来解决这个问题。我们通过在子类的映射文件中class节点指定polymorphism="explicit"声明了一个显示多态关系。声明为显示多态的类,只有在明确指定类名的时候才会返回此类实例。

  
package com.wyq.hibernateLoad;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;

import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.wyq.hibernate.TUser2;

public class TUserOperator {
    Session session 
= null;
    
//复合主键加载数据
    public void loadData(){
        TUser2 user 
= new TUser2();
        user.setFirstname(
"Kevin");
        user.setLastname(
"Shark");
        user 
= (TUser2)session.load(TUser2.class, user);
        System.out.println(
"User age is=>"+user.getAge());
    }
    
//SQL保存图片
    public void saveImage(){
        TUser2 user 
= new TUser2();
        user.setAge(
new Integer(20));
        
        
try {
            FileInputStream imgis 
= new FileInputStream("C:\\inimage.jpg");
            
            Blob img 
= Hibernate.createBlob(imgis);
            user.setImage(img);
            
            Clob resume 
= Hibernate.createClob("This is Clob");
            user.setResume(resume);
            
            Transaction tx 
= session.beginTransaction();
            
            session.save(user);
            tx.commit();
            
        } 
catch (FileNotFoundException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
catch (IOException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
//SQL读取图片
    public void getImageObj(){
        TUser2 user 
= (TUser2)session.load(TUser2.class,new Integer(3));
        Clob resume 
= user.getResume();
        Blob img 
= user.getImage();
        
        
try {
            InputStream is 
= img.getBinaryStream();
            
            FileOutputStream fos 
= new FileOutputStream("c:\\outimage.jpg");
            
byte[] buf = new byte[102400];
            
int len;
            
while((len=is.read(buf))!=-1){
                fos.write(buf,
0,len);
            } 
            fos.close();
            is.close();
            
        } 
catch (SQLException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
catch (FileNotFoundException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
catch (IOException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
//Oracle保存图片
    public void saveForOracleImage(){
        TUser2 user 
= new TUser2();
        user.setAge(
new Integer(20));
        user.setImage(Hibernate.createBlob(
new byte[1]));
        user.setResume(Hibernate.createClob(
" "));//注意这里的参数是一个空格
        
        Transaction tx 
= session.beginTransaction();
        
        session.save(user);
        
//调用flush方法,强制Hibernate立即执行insert sql
        session.flush();
        
//通过refresh方法,强制Hibernate执行select for update
        session.refresh(user, LockMode.UPGRADE);
        
        
//向Blob写入实际内容
        oracle.sql.BLOB blob = (oracle.sql.BLOB)user.getImage();
        
try {
            OutputStream out 
= blob.getBinaryOutputStream();
            
            FileInputStream imgis 
= new FileInputStream("c:\\inimage.jpg");
            
byte[] buf = new byte[10240];//10k缓存
            int len;
            
while((len=imgis.read(buf))>0){
                out.write(buf,
0,len);
            }
            imgis.close();
            out.close();
            
            
//向CLOB写入实际内容
            oracle.sql.CLOB clob = (oracle.sql.CLOB)user.getResume();
            java.io.Writer writer 
= clob.getCharacterOutputStream();
            writer.write(
"this is my resume");
            writer.close();
            session.save(user);
            tx.commit();
        } 
catch (SQLException e) {
            e.printStackTrace();
        }
catch (FileNotFoundException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
catch (IOException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
}


    实体层次设计:继承关系是关系型数据与面向对象数据结构之间的主要差异之一。
    Hibernate中支持3种类型的继承形式:
    1、表与子类之间的独立一对一关系。
    2、每个子类对应一张子表,并与主类共享主表
    3、表与类的一对多关系



  
posted on 2009-10-27 22:32 王永庆 阅读(219) 评论(0)  编辑  收藏 所属分类: HIBERNATE

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 
<2009年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿(1)

随笔分类

随笔档案

关注blogs

搜索

  •  

最新评论

阅读排行榜

评论排行榜