利用JDBC操作Oracle CLOB和BLOB类型数据
对LOB数据(包括CLOB BLOB NCLOB BFILE类型)操作的插入操作步骤:插入空值-->获取空值列及更新锁-->更新LOB字段。
通过查询操作得到的LOB类型数据处理要点:首先利用LOB字段数据获取InputStream或OutputStream对象,然后根据需要对其进行操作,若需提取数据则获取InputStream对象,若需更新LOB字段数据,则获取OutputStream对象。
程序分为两层,1)JdbcUtil提供基本数据库访问及事务管理,2)DAO层调用JdbcUtil来提供DAO服务。
包含CLOB数据的content_text表:
Sql代码
1. /*==============================================================*/
2. /* Table: content_text */
3. /*==============================================================*/
4. CREATE TABLE content_text (
5. pk_content_text INTEGER NOT null,
6. text_type VARCHAR2(25) NOT null,
7. text_content CLOB NOT null,
8. CONSTRAINT PK_CONTENT_TEXT PRIMARY KEY (pk_content_text)
9. )
包含BLOB数据的content_bin表:
Sql代码
1. /*==============================================================*/
2. /* Table: content_bin */
3. /*==============================================================*/
4. CREATE TABLE content_bin (
5. pk_content_bin INTEGER NOT null,
6. bin_type VARCHAR2(25) NOT null,
7. bin_content CLOB NOT null,
8. CONSTRAINT PK_CONTENT_BIN PRIMARY KEY (pk_content_bin)
9. );
=========================JdbcUtil================
-------向content_text表中插入数据:
Java代码
1. public int insertText(ContentText text) {
2. int insertkey = -1;
3. try {
4. // 利用序列sequence向数据库索取content_text表的自增长主键
5. ResultSet rs = executeQuery("select seq_content_text.nextval as pk_content_text from dual");
6. rs.first();
7. insertkey = rs.getInt(1);
8. rs.close();
9.
10. // 插入空CLOB
11. String insertEmpty = "insert into content_text values(" + insertkey
12. + ",'" + text.getTextType() + "',empty_clob())";
13. boolean insertResult = executeUpdate(insertEmpty);
14. if (insertResult == false) {
15. throw new SQLException();
16. }
17.
18. // 获取CLOB类型列text_content,并获取更新锁,锁定当前行直至更新结束
19. String getForUpdate = "select text_content from content_text where pk_content_text = "
20. + insertkey + " for update";
21. rs = executeQuery(getForUpdate);
22. rs.first();
23. CLOB content = (CLOB) rs.getClob("text_content");
24. rs.close();
25. content.setString(1L, text.getContent());
26.
27. // 更新text_content列
28. String updateSQL = "update content_text set text_content = ? where pk_content_text = ?";
29. PreparedStatement pst = conn.prepareStatement(updateSQL);
30. pst.setClob(1, content);
31. pst.setInt(2, insertkey);
32. pst.execute();
33. pst.close();
34. } catch (SQLException e) {
35. try {
36. conn.rollback();
37. conn.close();
38. } catch (SQLException e1) {
39. e1.printStackTrace();
40. }
41. e.printStackTrace();
42. System.out.println("Insert text failed!");
43. }
44. return insertkey;
45. }
------------向content_bin表中插入数据:
Java代码
1. public int insertBin(ContentBin bin) {
2. int insertkey = -1;
3. try {
4. // 利用序列sequence向数据库索取content_bin表的自增长主键
5. ResultSet rs = executeQuery("select seq_content_bin.nextval from dual");
6. boolean good = rs.first();
7. System.out.println(good);
8. insertkey = rs.getInt(1);
9. rs.close();
10.
11. // 插入空BLOB
12. String insertEmpty = "insert into content_bin values(" + insertkey
13. + ",'" + bin.getBinType() + "','" + bin.getBinFilename()
14. + "',empty_blob())";
15. boolean result = executeUpdate(insertEmpty);
16. System.out.println("插入空值:" + result);
17.
18. // 获取空BLOB字段,并获取更新锁
19. String getEmpty = "select bin_content from content_bin where pk_content_bin="
20. + insertkey + " for update";
21. ResultSet forupdateRs = executeQuery(getEmpty);
22. forupdateRs.first();
23. BLOB blob = (BLOB) forupdateRs.getBlob(1);
24.
25. //由文件系统获取文件输入流
26. File file = bin.getContent();
27. System.out.println(file.getAbsolutePath());
28. FileInputStream fin = new FileInputStream(file);
29. System.out.println(fin.toString());
30.
31. // 获取BLOB的输出流,并从文件输入流获取数据,写入BLOB的输出流,完成数据库外的BLOB更新
32. OutputStream out = blob.setBinaryStream(0);
33. byte[] data = new byte[blob.getBufferSize()];
34. System.out.println(data.length);
35. int count = -1, total = 0;
36. while ((count = fin.read(data)) != -1) {
37. total += count;
38. out.write(data, 0, count);
39. }
40. fin.close();
41. out.close();
42.
43. // 利用新的BLOB更新数据库
44. String updateBin = "update content_bin set bin_content=? where pk_content_bin=?";
45. PreparedStatement pstmt = conn.prepareStatement(updateBin);
46. pstmt.setBlob(1, blob);
47. pstmt.setInt(2, insertkey);
48. pstmt.execute();
49. pstmt.close();
50.
51. } catch (SQLException e) {
52. try {
53. conn.rollback();
54. conn.close();
55. } catch (SQLException e1) {
56. e1.printStackTrace();
57. }
58. e.printStackTrace();
59. } catch (IOException e) {
60. e.printStackTrace();
61. }
62. return insertkey;
63. }
=============================DAO层====================
---------查询content_text表
Java代码
1. public ContentText getById(int id) {
2. jdbc.openConn();
3. ContentText text = new ContentText();
4. String sql = "select pk_content_text,text_type,text_content from content_text where pk_content_text = "
5. + id;
6. ResultSet rs = jdbc.executeQuery(sql);
7. try {
8. rs.first();
9. text.setContentId(rs.getInt("pk_content_text"));
10. text.setTextType(rs.getString("text_type"));
11. CLOB clob = (CLOB) rs.getClob(3);
12. char[] chars = new char[(int) clob.getLength()];//(int)clob.length();
13. clob.getCharacterStream().read(chars);
14. String content = new String(chars);
15. text.setContent(content);
16. } catch (SQLException e) {
17. e.printStackTrace();
18. } catch (IOException e) {
19. // TODO Auto-generated catch block
20. e.printStackTrace();
21. }
22. jdbc.commitAndCloseConn();
23. return text;
24. }
--------------查询content_bin表
Java代码
1. public ContentBin getById(int id) {
2. ContentBin bin = new ContentBin();
3. jdbc.openConn();
4. String sql = "select pk_content_bin,bin_type,bin_filename,bin_content from content_bin where pk_content_bin="+ id;
5. ResultSet rs = jdbc.executeQuery(sql);
6. try {
7. rs.first();
8. bin.setContentId(rs.getInt(1));
9. bin.setBinType(rs.getString(2));
10. String filename = rs.getString(3);
11. bin.setBinFilename(filename);
12. //利用字段bin_filename值构造文件
13. File file = new File(filename);
14. FileOutputStream sout = new FileOutputStream(file);
15. BLOB blob = (BLOB) rs.getBlob(4);
16. InputStream in = blob.getBinaryStream();//获取BLOB数据的输入数据流
17. //经BLOB输入数据流读取数据,并将其写入文件
18. byte[] b = new byte[256];
19. int off = 0;
20. int len = b.length;
21. for (int i = in.read(b); i != -1;) {
22. sout.write(b);
23. System.out.println(i);
24. i = in.read(b);
25. }
26. in.close();
27. sout.close();
28. bin.setContent(file);
29. } catch (SQLException e) {
30. e.printStackTrace();
31. } catch (FileNotFoundException e) {
32. e.printStackTrace();
33. } catch (IOException e) {
34. e.printStackTrace();
35. }
36. jdbc.commitAndCloseConn();
37. return bin;
38. }
第二种插入操作
public Connection getConn(String flag){
Connection con=null;
try
{
if(flag.equals("1"))
{
Class.forName(“oracle.jdbc.driver.OracleDriver”);
con = DriverManager.getConnection(“jdbc:oracle:thin:@IP:1521:数据库名字”,"name","password");
}
if(flag.equals("2"))
{
Class.forName("org.gjt.mm.mysql.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/数据库名?user=用户名&password=密码&useUnicode=true&characterEncoding=GBK");
}
}
catch(Exception e)
{
e.printStackTrace();
}
return con;
}
执行插入操作
public void setData() {
conn = new Conn();
try {
String sqlfrom = "select p.id,p.content from table p order by p.id ";
String sqlinsert = "insert into table values(?,?)";
con = conn.getConn("2");
stmt = con.createStatement(); //从mysql取出大字段
rs = stmt.executeQuery(sqlfrom);
con = conn.getConn("1");
PreparedStatement pstmt = con.prepareStatement(sqlinsert); //向oracle中插入大字段
int i = 0;
while (rs.next()) {
pstmt.setInt(1, rs.getInt(1));
pstmt.setClob(2, oracle.sql.CLOB.empty_lob());
pstmt.executeUpdate(); //插入时将大字段设为空
this.updateOne(con,rs.getInt(1),rs.getString(2)); // 这里调用然后更新这个大字段
}
rs.close(); //关闭相关连接
pstmt.close();
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
try
{
con.rollback();
} catch (Exception e1) {
System.out.println("回滚出现异常!");
e1.printStackTrace();
}
}
}