`
leh627
  • 浏览: 23811 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

tomcat连接池中解决clob字段的问题

阅读更多
1. 关于CLOB(Character Large Object)
CLOB可用于存放大文本数据,最多可存储4GB数据,在应用开发中比较常见.java提供的sql.Clob类与之对应.它提供两个方法来读取Clob的数据:
getCharacterStream() 方法返回按unicode编码的输入流(java.io.Reader对象)
getAsciiStream() 方法返回按ASCII编码的输入流(java.io.InputStream对象)
所以如果你的数据库中有可能存储中文字符的话,就要使用前一个方法.
现在举一个实际的例子,让我一步步学习如何使用CLOB.
首先,创建一个含CLOB字段的表:
create table test (id INTEGER, content clob);

接下来, 我们通过JSP往这张表里插入一条记录,然后再获取显示它.
插入操作:
<%
Connection con = DriverManager.getConnection(...); //该行从略
String content = request.getParameter("content"); //大文本数据
con.setAutoCommit(false); //*
String sql = "insert into test values(1, empty_clob())";
Statement stmt = con.createStatement();
stmt.executeUpdate(sql);

con.commit(); //*
sql = "select content from test where id=1 for update";
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()) {
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob(1);
//如果用的是tomcat连接池此处使用  
//oracle.sql.CLOB clob = (CLOB) ((org.apache.commons.dbcp.DelegatingResultSet)rs).getClob("CONTENT");
clob.putString(1, content);
sql = "update test set content=? where id=" + seq;
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setClob(1, clob);
pstmt.executeUpdate();
}
%>


以上需要注意的几点是:
1)clob类型的数据不能直接insert,要先通过empty_clob()方法给它分配一个locator(同理,blob的用empty_blob()函数分配locator).然后把它select出来(此时它当然没有数据,但结果集不是空的),得到一个Clob的对象,修改该对象的内容让它满足我们的需要,再通过update方法更新该行记录.

2) 通过select修改含lob类型的记录时一定要锁定该行(通过for update关键字实现),否则oracle会报错.

3) 刚插入的记录就select for update, 会出现"违反读取顺序"错误,解决办法是将自动提交功能置为false,即不允许自动提交,然后commit它,再select,就可以了. 这就是上面那段代码里//*两行的作用.

4)补充点:如果用的 tomcat连接池,应该照上面插入数据时的写,否则样报错java.lang.ClassCastException ,在oracle9i以上好像没这个问题

下面,我们将刚插入的记录从数据库中读取出来并显示之:

<%
String sql = "select content from test where doc_id=1";
ResultSet rs = stmt.executeQuery(sql);
String content = "";
if (rs.next()) {
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("content");
if (clob != null){
Reader is = clob.getCharacterStream();
BufferedReader br = new BufferedReader(is);
String s = br.readLine();
while (s != null) {
content += s + "<br>";
s = br.readLine();
}
}
out.println(content);
%>
分享到:
评论

相关推荐

    hibernate教程

    - **自定义连接池**:如果应用已经使用了其他连接池(如 C3P0、DBCP),可以配置 Hibernate 使用这些连接池。 ##### 3.4 Hibernate 提供的 JDBC 连接 - **内置连接池**:Hibernate 自带了一个简单的连接池,适用于...

    Java数据库编程宝典2

    4.6 连接池 4.7 分布式事务处理 4.7.1 分布式事务管理 4.7.2 Connection对象 4.8 SQL语句 4.8.1 Statement对象 4.8.2 PreparedStatement语句 4.8.3 CallableStatement 4.9 事务 4.9.1 事务独立性等级 ...

    Java数据库编程宝典4

    4.6 连接池 4.7 分布式事务处理 4.7.1 分布式事务管理 4.7.2 Connection对象 4.8 SQL语句 4.8.1 Statement对象 4.8.2 PreparedStatement语句 4.8.3 CallableStatement 4.9 事务 4.9.1 事务独立性等级 ...

    Java数据库编程宝典1

    4.6 连接池 4.7 分布式事务处理 4.7.1 分布式事务管理 4.7.2 Connection对象 4.8 SQL语句 4.8.1 Statement对象 4.8.2 PreparedStatement语句 4.8.3 CallableStatement 4.9 事务 4.9.1 事务独立性等级 ...

    Java数据库编程宝典3

    4.6 连接池 4.7 分布式事务处理 4.7.1 分布式事务管理 4.7.2 Connection对象 4.8 SQL语句 4.8.1 Statement对象 4.8.2 PreparedStatement语句 4.8.3 CallableStatement 4.9 事务 4.9.1 事务独立性等级 ...

    JAVA程序开发技术

    **4.11.2 数据库连接池** - **定义**:管理数据库连接的池。 - **优点**:复用连接,减少资源开销。 #### 第五章:JSP/Servlet技术 **5.1 JSP/Servlet概述** **5.1.1 HTML入门** - **定义**:超文本标记语言。 - ...

Global site tag (gtag.js) - Google Analytics