<%@ page contentType="text/html; charset=gb2312"%> 学习Oracle中Blob和Clob一点点心得
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
学习Oracle中Blob和Clob一点点心得
     发布者: 发布时间:2007-03-26

Blob是指二进制大对象也就是英文Binary Large Object的所写,而Clob是指大字符对象也就是英文Character Large Object的所写。由此可见这辆个类型都是用来存储大量数据而设计的,其中BLOB是用来存储大量二进制数据的;CLOB用来存储大量文本数据。
那么有人肯定要问既然已经有VARCHAR和VARBINARY两中类型,为什么还要再使用另外的两种类型呢?其实问题很简单,VARCHAR和VARBINARY两种类型是有自己的局限性的。首先说这两种类型的长度还是有限的不可以超过一定的限额,以VARCHAR再ORA中为例长度不可以超过4000;那么有人又要问了,LONGVARCHAR类型作为数据库中的一种存储字符的类型可以满足要求,存储很长的字符,那为什么非要出现CLOB类型呢?其实如果你用过LONGVARCHAR类型就不难发现,该类型的一个重要缺陷就是不可以使用LIKE这样的条件检索。(稍候将介绍在CLOB中如何实现类似LIKE的模糊查找)另外除了上述的问题外,还又一个问题,就是在数据库中VARCHAR和VARBINARY的存取是将全部内容从全部读取或写入,对于100K或者说更大数据来说这样的读写方式,远不如用流进行读写来得更现实一些。
在JDBC中有两个接口对应数据库中的BLOB和CLOB类型,java.sql.Blob和java.sql.Clob。和你平常使用数据库一样你可以直接通过ResultSet.getBlob()方法来获取该接口的对象。与平时的查找唯一不同的是得到Blob或Clob的对象后,我们并没有得到任何数据,但是我们可以这两个接口中的方法得到数据
例如:
Blob b=resultSet.getBlob(1);
InputStream bin=b.getBinaryStryeam();
Clob c=resultSet.getClob(2);
Reader cReader=c.getCharacterStream():
关于Clob类型的读取可以使用更直接的方法,就是直接通过ResultSet.getCharacterStream();方法获得字符流,但该方法并不安全,所以建议还是使用上面例子的方法获取Reader。
另外还有一种获取方法,不使用数据流,而是使用数据块。
例如
Blob b=resultSet.getBlob(1);
byte data=b.getByte(0,b.length());
Clob c=resultSet.getClob(2);
String str=c.getSubString(0,c.length()):
在这里我要说明一下,这个方法其实并不安全,如果你很细心的话,那很容易就能发现getByte()和getSubString()两个方法中的第二个参数都是int类型的,而BLOB和CLOB是用来存储大量数据的。而且Bolb.length()和Clob.length()的返回值都是long类型的,所以很不安全。这里不建议使用。但为什么要在这里提到这个方法呢?稍候告诉你答案,这里你需要记住使用数据块是一种方法。

在存储的时候也同样的在PreparedStatement和CallableStatememt中,以参数的形式使用setBlob()和setClob方法把Blob和Clob对象作为参数传递给SQL。这听起来似乎很简单对吧,但是并非我们想象的这样,很不幸由于这两个类型的特殊,JDBC并没有提供独立于数据库驱动的Blob和Clob建立对象。因此需要自己编写与驱动有关的代码,但这样又牵掣到移植性。怎样才是解决办法呢?这就要用到前面说过的思想了使用数据块进行写操作。同样用PreparedStatement和CallableStatememt类,但参数的设置可以换为setAsciiStream、setBinaryStream、setCharacterStream、setObject(当然前3个同样存在长度的问题)
下面给大家个例子以方便大家理解
public void insertFile(File f) throws Exception{
FileInputStream fis=new FileInputStream(f,Connection conn);
byte[] buffer=new byte[1024];
data=null;
int sept=0;int len=0;

while((sept=fis.read(buffer))!=-1){
if(data==null){
len=sept;
data=buffer;
}else{
byte[] temp;
int tempLength;

tempLength=len+sept;
temp=new byte[tempLength];
System.arraycopy(data,0,temp,0,len);
System.arraycopy(buffer,0,temp,len,sept);
data=temp;
len=tempLength;
}
if(len!=data.length()){
byte temp=new byte[len];
System.arraycopy(data,0,temp,0,len);
data=temp;
}
}
String sql="insert into fileData (filename,blobData) value(?,?)";
PreparedStatement ps=conn.prepareStatement(sql);
ps.setString(1,f.getName());
ps.setObject(2,data);
ps.executeUpdate();

}

最后由于刚刚说过Clob类型读取字符的长度问题,这里再给大家一段代码,希望对你有帮助
public static String getClobString(ResultSet rs, int col) {
try {
Clob c=resultSet.getClob(2);
Reader reader=c.getCharacterStream():
if (reader == null) {
return null;
}
StringBuffer sb = new StringBuffer();
char[] charbuf = new char[4096];
for (int i = reader.read(charbuf); i > 0; i = reader.read(charbuf)) {
sb.append(charbuf, 0, i);
}
return sb.toString();
} catch (Exception e) {
return "";
}
}

另外似乎前面还提到过LIKE检索的问题。LONGVARCHAR类型中不可以用LIKE查找(至少ORA中不可以使用,其他的数据库我没有试过),在ORA中我们可以使用这样一个函数dbms_lob.instr来代替LIKE来个例子吧

select docid,dat0 from text where dbms_lob.instr(dat0,'魏',1,1)>0

在text表中有两个字段docid用来放文档编号dat0为clob类型存放文章内容;这句话的意思就是检索第一条dat0中出现第一次"魏"字的数据。听起来这个检索的数据有点象google的“手气不错”

以上只是对数据库中比较特殊的两个类型做了简单的说明,希望能对你有所帮助,如果有什么不对的地方也请各位指出,可以通过邮件联系我zuyingwei@hotmail.com

(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
Java的类装载器和命名空间
JAVA中浅复制与深复制概念详细解析
基于JAVA的电子政务系统整体解决方案
线性报表解释
IIS6.0与Resin_3.0.8的整合
Java连接各种数据库的实例
 
最近评论:
        
你曾悄悄的来过!
wow gold,wow gold,wow gold,ffxi gil max(8183)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(7332)
        
飞舞的传奇!
传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(8969)
        
高薪诚聘IT讲师
软件测试工程师(教学督导) 软件测试工程师(教学督导) 电子邮箱: youjie.yao@jb-aptech.com.cn 工作地点: 北京市 招聘人数: 4 工作年限: 一年以上 薪水范围: 面议 学 历: 本科 职位描述: 职位描述: 部门:软件测试事业部 公司内部职位名称:教学督导 1、协助培训中心建立讲师团队 2、保证培训中心学术团队按照标准化进行运作 3、保证培训中心教学质量和学员就业质量 4、演示关键事件的执行方式(如授课等) 备注:需要较强的沟通能力,能出差,之前做过售前和技术支持者优先 1、本科要求1年以上的软件开发经验或2年以上软件测试经验(在校期间项目开发经验或项目测试经验可以计算在内) 2、硕士可以应届毕业生 3、年龄大于24周岁 4、有培训经验或学生工作经验者优先考虑 技术要求: 具备如下技能当中之一即可。 A类技能: 熟练掌握C、C++、Java、C#中任意一种编程语言 了解软件体系结构 了解J2EE或.net架构; 掌握计算机原理及软硬件知识 掌握网络基础知识及TCP/IP协议 熟练配置Windows或Linux操作系统及常用服务配置 熟悉SQLserver数据库产品的管理和配置 B类技能: 掌握C、C++、Java、C#中任意一种编程语言 熟悉软件测试流程 掌握常用测试技术,能够熟练设计软件测试用例 熟练编写测试计划 掌握功能或性能测试工具 基本素质: 1、表达能力强、口齿清晰 2、较强的沟通意识、思路清晰 3、细心、耐心、有团队精神 有意者请将简历发送至邮箱 备注:请应聘者标注招聘信息来源。 软件测试培训师 电子邮箱: youjie.yao@jb-aptech.com.cn 工作地点: 北京市 招聘人数: 10 工作年限: 一年以上 薪水范围: 面议 学 历: 本科 职位名称 讲师 所属部门 学术质量部 直接主管 学术质量部经理 职位目标 在学术质量部经理的领导下,执行授课流程和事件,并参与中心相关学术活动,达到提高学员的满意度、合格率、就业率、就业质量的目标 工作职责 范围 内容 1、授课 1、 备课(撰写教案) 2、 协助搭建教学环境 3、 讲授知识点 4、 解答学员问题(理论课、实践课、讨论课) 5、 批改作业及记录作业批改情况 6、 阅卷、并做试卷分析、总结 7、 组织实施项目实训 8、 整理反馈教学经验(包括教案、典型案例) 2、开发课件 1、 开发BTEST沙龙的课件 2、 开发试题,组内部测试、结业考试样卷 3、参与市场活动 1、 招生演讲 招聘要求 基本条件 1、本科(含)以上学历,身体健康 2、认同北大青鸟企业文化和BTEST产品,自觉维护企业形象和产品 经验要求 1、1年以上的软件开发经验或2年以上软件测试经验(在校期间项目开发经验或项目测试经验可以计算在内) 2、研究生毕业可不需要工作经验 技能要求 以下两类专业技能,至少具备一类: a、测试类技能:熟悉软件测试流程、测试用例设计、测试计划、常用测试技术、有使用测试工具经验者优先; b、开发类技能:熟悉C、C++、Java、C#中任意一种编程语言; 搭建环境类技能:了解计算机原理及PC机软硬件知识,了解网络基础知识及TCP/IP协议,了解Windows或Unix/Linux操作系统管理; 素质要求 1、 较强的沟通能力和表达能力 2、 责任心强、职业意识强 3、 形象佳、有亲和力、口齿清晰
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号