- 浏览: 285970 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
86614009:
如何在service层,如何获取绑定到当前线程的entitna ...
使用spring的OpenEntityManagerInView -
yajunyajun2011:
好帖子 怎么没人顶呢
Java 正则表达式最大,最小匹配问题 -
xtuali:
能说明一下,你的nutch是哪个版本的吗?谢谢!
搜索引擎Nutch源代码研究之一 网页抓取(1) -
dongmusic:
需要学习这么多的东西,吐血中...
如何提高Java开发能力 -
jiminsc:
cool
LDAP 验证、添加、修改、删除(转)
文章分类:Java编程
Clob和blob的操作主要分为3种:插入,更新和读取显示。
对于插入,可以分为两类。一类是可以直接按照正常的字段处理,一类为必须先插入空clob/blob再更新为真正的内容。
插入:
对于大部分的数据库,在插入lob时都可以通过PreparedStatement.setAsciiStream或PreparedStatement.setBinaryStream直接写入,查到的资料包括:
H2数据库:http://code.google.com/p/h2database/issues/detail?id=100#c3
Mysql数据库:http://lavasoft.blog.51cto.com/62575/64963
DB2:http://lavasoft.blog.51cto.com/62575/64683
而对于Oracle数据库则必须先插入空lob,重新查询再进行更新(查询时需要加for update)。方法如下:
Oracle数据库:http://www.iteye.com/topic/254
插入空Lob的方式很多,如可以插入长度为1的byte[1到blob中]或1个字符的字符串到clob中。也可以在创建表时通过default empty_clob()由数据库自动创建。
对于上面帖子的补充:robbin同志介绍说需要加for update行锁,是为了防止被其他连接并发更新,这种提法并不完整。oracle数据库要求进行lob更新时,必须加for update,否则报错,这是数据库一个强制要求。就算你知道不会有并发修改,也必须加。
对于Lob更新,方法都比较类似,查询到Lob字段然后直接更新(H2不支持Lob字段的更新)。需要注意的是,获取到Lob的Stream(如:Blob.setBinaryStream())写入完毕后,必须调用flush(),否则可能会出现数据丢失(在Oracle10g + odbc14.jar下测试发现)。
对于Lob读取:可以使用传统的java.sql.Clob/java.sql.Blob的api,某些驱动也可以使用rs.getString()或rs.getBytes()(没有测试过,据说大部分都行)当成普通的varchar和字节字段处理,很是方便。
对于Clob/Blob的使用,大部分都纠结在Oracle上,Oracle有各种各样的限制,如经典的长度限制,最新的odbc14.jar驱动据说已经解决了所有问题,也就是增加一个连接参数SetBigStringTryClob的事情。相关的资料如下:
Oracle官方文档:
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/clob10g/handlingclobsinoraclejdbc10g.html
也可以看看一大堆跟贴的讨论:
http://www.iteye.com/topic/254
我没有测试过rs.getString()的方法,我测试过Oracle和H2的Clob api。通过clob api的方法,可以正常的写入和读取100万字符的大字符串。最理想,最节省内存,也最通用的应该还是JDBC为Lob设计的api。
NAME varchar(24) DEFAULT NULL,
TXT text,
IMG blob
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
import java.sql.*;
import java.io.*;
/**
* JDBC 读取MySQL lob字段测试
* File: TestLob4MySQL.java
* User: leizhimin
* Date: 2008-3-3 14:44:30
*/
public class TestLob4MySQL {
public static final String url = "jdbc:mysql://localhost/testdb";
public static final String username = "root";
public static final String password = "leizhimin";
public static final String driverClassName = "com.mysql.jdbc.Driver";
/**
* 数据库连接获取器
*
* @return 数据库连接
*/
public static Connection makeConnection() {
Connection conn = null;
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 测试数据库连接
*/
public static void testConnection() {
Connection conn = makeConnection();
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM mysql.user");
while (rs.next()) {
String s1 = rs.getString(1);
System.out.println(s1);
}
rs.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 插入Lob字段
*/
public static void testInsertlob() {
Connection conn = makeConnection();
try {
conn.setAutoCommit(false);
File txtFile = new File("C:\\txt.txt");
File imgFile = new File("C:\\img.png");
int txt_len = (int) txtFile.length();
int img_len = (int) imgFile.length();
try {
InputStream fis1 = new FileInputStream(txtFile);
InputStream fis2 = new FileInputStream(imgFile);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO T_LOB(NAME,TXT,IMG) VALUES('G',?,?)");
pstmt.setAsciiStream(1, fis1, txt_len);
pstmt.setBinaryStream(2, fis2, img_len);
pstmt.executeUpdate();
conn.commit();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 读取lob字段
*/
public static void testQueryLob() {
Connection conn = makeConnection();
try {
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT TXT,IMG FROM T_LOB");
int i = 1;
while (rs.next()) {
Clob clob = rs.getClob("TXT");
Blob blob = rs.getBlob("IMG");
InputStream txtIs = rs.getAsciiStream("TXT");
InputStream imgIs = rs.getBinaryStream("IMG");
InputStreamReader txtIsr = new InputStreamReader(txtIs);
InputStreamReader imgIsr = new InputStreamReader(imgIs);
BufferedReader buff_txtIsr = new BufferedReader(txtIsr);
BufferedReader buff_imgIsr = new BufferedReader(imgIsr);
String line = null;
while (null != (line = buff_txtIsr.readLine())) {
System.out.println(line); //将其输出至屏幕,实际你可以按照需要处理
}
File fileOutput = new File("c:\\img_x" + i + ".png");
FileOutputStream fo = new FileOutputStream(fileOutput);
int c;
while ((c = imgIs.read()) != -1)
fo.write(c);
fo.close();
System.out.println("img " + i + " retrieved!");
i++;
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 读取lob字段
*/
public static void testQueryLob1() {
Connection conn = makeConnection();
try {
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT TXT,IMG FROM T_LOB");
while (rs.next()) {
Clob clob = rs.getClob("TXT");
Blob blob = rs.getBlob("IMG");
InputStream txtIs = clob.getAsciiStream();
InputStream imgIs = blob.getBinaryStream();
InputStreamReader txtIsr = new InputStreamReader(txtIs);
InputStreamReader imgIsr = new InputStreamReader(imgIs);
BufferedReader buff_txtIsr = new BufferedReader(txtIsr);
BufferedReader buff_imgIsr = new BufferedReader(imgIsr);
String line = null;
while (null != (line = buff_txtIsr.readLine())) {
System.out.println(line); //将其输出至屏幕,实际你可以按照需要处理
}
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 删除lob字段
*/
public static void testDeleteLob() {
Connection conn = makeConnection();
try {
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
int row = stmt.executeUpdate("DELETE FROM T_LOB");
conn.commit();
System.out.println("删除 " + row + " 行数据!");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 读取lob字段
*/
public static void testUpdateLob() {
Connection conn = makeConnection();
try {
String in_str="HAHAHAHAHAHA!!!";
File in_file=new File("c:\\img_haha.png");
InputStream txt_is = string2InputStream(in_str);
InputStream img_is =new FileInputStream(in_file);
conn.setAutoCommit(false);
PreparedStatement pstmt = conn.prepareStatement("UPDATE T_LOB SET TXT=?, IMG=? WHERE NAME='G'");
pstmt.setAsciiStream(1,txt_is,in_str.getBytes().length);
pstmt.setBinaryStream(2,img_is,(int)in_file.length());
int row = pstmt.executeUpdate();
conn.commit();
txt_is.close();
img_is.close();
// System.out.println("更新 " + row + " 行数据!");
} catch (SQLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
// testInsertlob();
// testQueryLob();
// testQueryLob1();
// testDeleteLob();
testUpdateLob();
}
public static InputStream string2InputStream(String str) {
if (str == null) return null;
return new ByteArrayInputStream(str.getBytes());
}
public static String inputStream2String(InputStream is) {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine;
try {
while ((inputLine = br.readLine()) != null) {
sb.append(inputLine).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
发表评论
-
文件存储到 Oracle 的存储过程用的外部BLOB的方式
2012-04-25 17:24 888一个存储图片文件的过程,任何开发工具都可以通过调用过程把图片文 ... -
Linux 安装 Mysql
2012-03-06 16:37 749一、引言 想使用Linux已经很长时间了,由于没有硬性任 ... -
sql查看oracle tablespace剩余空间
2012-01-01 10:46 1646select a.TABLESPACE_NAME, a.BYT ... -
oracle报错ID(一)
2011-12-06 08:55 1893ORA-00001: 违反唯一约束 ... -
ORACLE错误一览表
2011-06-03 16:52 684ORA-00001: 违反唯一约束 ... -
Oracle 使用总结(收藏于论坛)
2011-05-08 20:20 710一.Oracle数据库中常用的 ... -
oracle中scott/tiger、sys、SYSDBA、system都是什么用
2011-03-07 21:33 1217scott 是个演示用户,是让你学习ORACLE用的 SYS ... -
Oracle 一次插入多条记录的方法
2011-03-04 13:01 1131原来一次插入多条记录是用这个方法,需要用到dual 表, ... -
为Oracle字段建索引
2011-03-04 09:55 1198一、查看表中所有的索引,注意表名必须要大写SQL> se ... -
查看及删除oracle序列的方法
2011-03-04 09:37 1014一、查看所有序列 select * from u ... -
Oracle 9i主键自增长
2011-03-02 20:50 811<!--StartFragment --> ... -
Oracle连接池
2011-03-01 18:00 1132Oracle连接池 public class Conn ... -
jdbc连接数据库操作
2011-02-28 13:27 830好久没有操作数据库,今天上午连接Oracle的,竟然不知道怎么 ... -
常用的Oracle命令
2011-01-14 16:33 1015ORACLE数据库维护 01. ORACLE数 ... -
oracle的blob,clob的读写
2010-10-26 19:32 1074JDBC驱动程序的类型: JDBC-ODBC桥;部分本地API ... -
将文档以BLOB类型存入Oracle数据库中
2010-10-26 16:06 1210头痛了两天的问题终于得到解决了,特此写下(原创): c ... -
向oracle中插入BLOB对象
2010-10-25 20:19 1486package oracle.otnsamples.jdbc. ... -
How To Handle CLOBs Easily in JDBC?
2010-10-24 11:07 805How To Handle CLOBs Easily in ... -
Blob、InputStream、byte 互转
2010-10-24 10:55 1294来自 sukyle的专栏 在我们的程序开发当中,经常会用到j ... -
将clob 转换成 String
2010-10-24 10:53 1118将clob 转换成 String 文章分类:Java编程 ...
相关推荐
Oracle支持4种LOB:BLOB、CLOB、NCLOB、BFILE其中,BLOB、CLOB、NCLOB是内部LOB,真正存储在数据库中;BFILE是唯一的外部LOB,它是以外部文件的方式存储在文件中。 本文以BLOB为例进行说明,它以二进制方式存储数据...
本文将深入探讨如何使用Java Database Connectivity (JDBC) API来操作Oracle数据库中的BLOB字段,包括创建表、插入和读取BLOB数据的方法。 #### 创建包含BLOB字段的表 在Oracle数据库中创建一个包含BLOB字段的表...
JDBC提供了一套API来处理这些数据类型,包括`setObject()`、`setBinaryStream()`和`setCharacterStream()`等方法。 - **示例代码**: ```java Blob blob = conn.createBlob(); blob.setBytes(1, bytesArray); ...
- **特殊数据类型**:LOB、ROWID等特殊数据类型的特性及应用场景。 #### 第十一章 Oracle 体系结构(DBA) - **Oracle体系结构概述**:深入理解Oracle数据库的内部结构。 - **内存结构**:SGA、PGA等内存区域的作用...
Oracle 数据类型可以分为数值类型、字符类型、日期类型、LOB 类型等。了解 Oracle 数据类型是掌握 Oracle 基础知识的重要一步。 5. 数据定义语言(DDL) 数据定义语言(DDL)是一种用于定义数据库结构的语言。常见...
- **基本数据类型**:NUMBER、VARCHAR2、DATE等。 - **复合数据类型**:PL/SQL RECORD、TABLE等。 - **LOB类型**:BLOB、CLOB、NCLOB、BFILE等。 #### 十二、Oracle体系结构(DBA) - **物理结构**:数据文件、日志...
H2数据库支持多种类型的数据类型,包括数值类型、日期和时间类型、字符类型等。此外,还提供了一系列的数据操作函数和表达式,如字符串、数学、日期时间等函数,这些都是在SQL查询中频繁使用的。 H2数据库的操作也...
- **LOB数据类型**:用于存储大对象,如BLOB(二进制大对象)、CLOB(字符大对象)等。 - **属性类型**: - `%type`:定义一个变量,其数据类型与另一个已定义的数据类型相同。 - `%rowtype`:返回一个记录类型,...
`ojdbc8.jar`驱动程序属于类型4的纯Java驱动,这意味着它无需依赖本地数据库客户端,可以跨平台运行。 该驱动程序的主要功能包括: 1. **连接建立**:`DriverManager.getConnection()`方法使用提供的URL、用户名和...
PL/SQL提供了多种内置函数来支持数据类型的转换,例如TO_CHAR、TO_NUMBER等。 **2.9 运算符和表达式** PL/SQL支持多种运算符,包括关系运算符、一般运算符和逻辑运算符。表达式则是由变量、常量和运算符组成的组合...
1. **5CD2-02-Foundation-2006-01.pdf**:这可能是一份关于SQL标准基础的文档,可能包含了SQL语言的核心概念,如数据类型、运算符、表达式、查询语句(SELECT)、数据定义(CREATE)、数据操纵(INSERT、UPDATE、...
攻击者通过构造特殊的SQL查询来操纵目标应用程序中的SQL语句,以此来获取敏感数据、修改数据或执行任意代码等。在本篇文章中,我们将详细介绍一种利用Oracle SQL注入来实现远程命令执行的方法。 #### 二、关键知识...
SQLServer的主要数据类型包括CHAR、VARCHAR、NVARCHAR、TEXT等,货币类型为MONEY,还有二进制类型如BINARY和VARBINARY。 在数据库操作上,修改表结构的语法有所不同。例如,更改列的数据类型,SQLServer使用"ALTER ...
9. **org.jbpm.pvm.internal.hibernate**: 与Hibernate ORM的交互类,处理类型转换、命名策略和主要的数据库会话`DbSessionImpl`,负责所有与数据库相关的操作。 10. **org.jbpm.pvm.internal.history**: 提供历史...
在Oracle数据库中,支持多种数据类型,包括字符(CHAR、VARCHAR2等)、数值(NUMBER、INTEGER等)、日期时间(DATE、TIMESTAMP等)、RAW(二进制数据)以及大型对象(LOB,如BLOB、CLOB等)。此外,还有一些特殊列,...