java對Clob大資料欄位型別的增刪改查
前言
前幾天臨時支援,幫pc端寫幾個介面,主要是對一個表的CRUD操作,雖然快兩年多沒寫後臺相關的東西了,但還不至於連一個表的基本的CRUD操作都忘了。但悲劇往往就來的這麼及時,表中有一個欄位是Clob型別的,以前沒怎麼處理過這種大欄位型別,網上查了下資料,感覺寫的五花八門,沒有一個完整的、適用的方法。通過參照別人的出來,加上自己的實踐,終於搞定。在此分享出來,希望給以後遇到同樣問題的人提供一些幫助。處理Clob型別的像hibernate、mybatis框架本身也提供了一些簡單的工具幫我們處理,先介紹使用最原始的的jdbc來處理。對於Blob型別的處理就不再介紹,同樣處理即可。
Clob型別的欄位最多可儲存2G的資料,不過超過5M的資料,我建議還是放到檔案裡面,資料庫放對應檔案的地址。至於兩種方式的利弊,不是本文重點,大家自行查之。
例項
環境
- oracle11g
- tomcat 7.0
- jdk 1.8
資料庫表結構
jdbc方式
首先一個基本的jdbc連線類,還是貼下吧:
public class ConnectionUntils {
private static Connection conn;
private ConnectionUntils(){
try {
throw new Exception("can't be instance");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getInstance(){
if(conn == null){
initConnection();
}
return conn;
}
private static void initConnection() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");// 載入Oracle驅動程式
String url = "jdbc:oracle:" + "thin:@127.0.0.1:1521:orcl" ;
String user = "lsh";
String password = "lsh";
conn = DriverManager.getConnection(url, user, password);// 獲取連線
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/*
* 測試連線成功
*/
/*public static void main(String[] args) {
PreparedStatement pst = null;
ResultSet rs = null;
String sql = "select count(a_id) from article";
Connection con = getInstance();
try {
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
if(rs.next()){
System.out.println(rs.getInt(1));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rs,pst,con);
}
}*/
public static void close(ResultSet rs, PreparedStatement pst, Connection connection) {
try {
if(rs!=null){
rs.close();
rs=null;
}
if(pst!=null){
pst.close();
pst=null;
}
if(connection!=null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
接下來是具體的增刪改查方法,先說增加,一般會插入一個空的clob到資料庫對應的欄位,然後鎖定該列,用Write將待插入字串寫入進去。重點:這兩步操作要放在同一個事務裡面。具體增加的方法如下:
public boolean save(Article article){
boolean result = true;
Connection conn = ConnectionUntils.getInstance();
String sql = "insert into article values(?,?,empty_clob())";
//鎖住該列,防止併發寫入時候該欄位同時被多次寫入造成錯誤
String sqlClob = "select a_content from article where a_id=? for update";
PreparedStatement pst =null;
ResultSet rs = null;
Writer writer = null;
try {
conn.setAutoCommit(false);//設定不自動提交,開啟事務
pst = conn.prepareStatement(sql);
pst.setInt(1,article.getId());
pst.setString(2,article.getName());
pst.executeUpdate();
pst= conn.prepareStatement(sqlClob);
pst.setInt(1, article.getId());
rs = pst.executeQuery();
CLOB clob = null;
if(rs.next()){
try {
clob = (CLOB) rs.getClob(1);
writer = clob.getCharacterOutputStream(); //拿到clob的字元輸入流
writer.write(article.getContent());
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
conn.commit();
} catch (SQLException e) {
result = false;
try {
conn.rollback();//當commit或者rollback後會自動釋放該列的鎖定
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
conn.setAutoCommit(true);//還原
ConnectionUntils.close(rs, pst, conn);
}
return result;
}
用Junit 測試:
@Test
public void testSave(){
dao = new CrudClob();
Article article = new Article();
article.setId(1);
article.setName("水滸傳");
StringBuilder str = new StringBuilder();
for(int i=0;i<6000000;i++){
str.append("我是正文,我是正文,我是正文,我是正文,我是正文");
}
article.setContent(str.toString());
boolean result = dao.save(article);
System.out.print(result);
}
將資料庫剛才插入的一條資料匯出到檔案:
article.sql裡面包括表結構和剛插入的一條資料,大小411MB,在我電腦上耗時36秒左右:
接下來看update操作,update時候主要利用PreparedStatement的setClob方法:
public boolean update(int id,String content){
int result = 0;
Connection conn = ConnectionUntils.getInstance();
String sql = "update article set a_content=? where a_id=?";
PreparedStatement pst =null;
try {
CLOB clob = oracle.sql.CLOB.createTemporary(conn, false,oracle.sql.CLOB.DURATION_SESSION);
clob.setString(1L, content);
pst = conn.prepareStatement(sql);
pst.setClob(1, clob);
pst.setInt(2,id);
result = pst.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
ConnectionUntils.close(null, pst, conn);
}
if(result==0)
return false;
return true;
}
查詢就主要是從結果集ResultSet中定位到對應的欄位後,往外讀:
public Article select(int id){
Article article = new Article();
Connection conn = ConnectionUntils.getInstance();
String sql = "select a_id,a_name,a_content from article where a_id = ?";
PreparedStatement pst =null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
pst.setInt(1,id);
rs = pst.executeQuery();
StringBuilder builder = new StringBuilder();
if(rs.next()){
Clob clob = rs.getClob("a_content");
Reader rd = clob.getCharacterStream();
char [] str = new char[12];
while(rd.read(str) != -1) {
builder.append(new String(str));
}
article.setContent(builder.toString());
article.setId(id);
article.setName(rs.getString("a_name"));
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
ConnectionUntils.close(rs, pst, conn);
}
return article;
}
刪除的方法和普通表一樣,就不在貼出。
hibernate方式
hibernate處理挺簡單的,hibernate4處理,clob型別在實體類裡面對應定一個一個Clob型別的欄位,對映:
<property name="content" type="clob">
<column name="a_content"/>
</property>
在插入對應欄位的地方建立一個clob即可。
Hibernate.getLobCreator(session).createBlob(str);
hibernate5就更簡單了,hibernate內部做了對應的處理,我們直接當string型別一樣處理即可。
@Entity
public class Article {
@Id
@Column(name="a_id")
private int id;
@Column(name="a_name")
private String name;
@Column(name="a_content")
private String content;
public int getId() {
return id;
}
}
存的時候直接設定大資料到content,直接呼叫session.save()即可。
mybatis方式
mybatis處理也非常簡單,沒必要貼程式碼,只需要配置mapper對映的時候配置一個處理器就會自動幫我們轉型別處理。和String型別一樣處理即可。
<result column="a_content" property="content" jdbcType="Clob" typeHandler="org.apache.ibatis.type.ClobTypeHandler"/>
所有的程式碼已經打包上傳,如果有任何疑問請郵件:[email protected]。
相關推薦
java對Clob大資料欄位型別的增刪改查
前言 前幾天臨時支援,幫pc端寫幾個介面,主要是對一個表的CRUD操作,雖然快兩年多沒寫後臺相關的東西了,但還不至於連一個表的基本的CRUD操作都忘了。但悲劇往往就來的這麼及時,表中有一個欄位是Clob型別的,以前沒怎麼處理過這種大欄位型別,網上查
mysql 初體驗 -----(資料和欄位的增刪改查)
上篇隨筆說到了如何去安裝和 DOS命令 一些最簡單的操作,以及如何去鍵一個數據庫和如何建表。 這次接著來談mysql 裡資料和欄位的增刪改查 有增刪改查就會有資料型別以及資料型別的屬性 mysql資料型別和資料屬性有很多,先接觸一些最基本和最實用的的。 mysql 資料
sqlite3中對錶欄位的增刪改查
[size=medium]android[/size]今天在做資料庫升級時,碰到要對原來資料庫中一張表的一個欄位名進行修改,但是用:alter table tablename rename column oldColumnName to newColumnName;始終不成功
【轉載】解決Java關鍵字作為json資料欄位名問題
轉自:https://blog.csdn.net/jjj11223344/article/details/79957559 在java命名規範中,我們不能採用Java關鍵字如 public、static等命名,但是在服務端資料命名時我們往往會採用某一欄位的英文來命名,這有時候就
Java JDBC中,MySQL欄位型別到JAVA型別的轉換
1. 概述 在使用Java JDBC時,你是否有過這樣的疑問:MySQL裡的資料型別到底該選擇哪種Java型別與之對應?本篇將為你揭開這個答案。 2. 型別對映 java.sql.Types定義了常用資料庫(MySQL、Oracle、DB2等)所用到的資料型別
c# 對oracle插入資料欄位過長超出限制的解決方案
通過建立儲存過程的方法解決問題,如下所示,儲存過程的名字為insertGEO,有4個輸入引數,Childrens,RingInParent直接通過sql語句插入時,欄位值過長會報錯,所以先在資料庫中建立儲存過程 create or replace procedure insertGEO (v_i
JPA之大資料欄位對映與欄位延遲載入
1、修改Person.java中的程式碼 package cn.sunft.bean; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; imp
解決Java關鍵字作為json資料欄位名問題
在java命名規範中,我們不能採用Java關鍵字如 public、static等命名,但是在服務端資料命名時我們往往會採用某一欄位的英文來命名,這有時候就不可避免的和java關鍵字有衝突。這裡介紹一個Java註解來解決這一問題,將json資料中的欄位進行轉換,如:@Seria
Spring mvc無法接受到大資料欄位處理
1 :Spring mvc 用@RequestBody 方式,接收方法如下: @RequestMapping(value = "testRecieve") @ResponseBod
由於Mybatis實體資料欄位不匹配而查不到的解決辦法
使用MyBatis進行查詢操作時無法查詢出相應的結果,但是純sql又能查出資料時,需要考慮下是不是欄位對應實體類的屬性出現問題,解決方法有如下兩點 1、通過在查詢的sql語句中定義欄位名的別名,讓欄位名的別名和實體類的屬性名一致,這樣就可以表的欄位名和實體類的屬性名一一
資料庫中的欄位無法增刪改
前沿 進行機房重構有一段時間了,進行機房資料庫是必不可少的,我們在執行機房的同時也要把相應的資料存入資料庫,同樣,我們也需要資料庫裡的資料進行增刪改,可是我遇到了一個關於資料庫的問題... &nb
arcengine 連線sde,並對sde內資料進行管理(增刪改)
1、連線sde,用的是連線檔案,怎麼建立連線檔案,arcgis 工具箱, 如果service引數使用的預設的埠號5151,則必須在建立連線檔案之前必須建立和開啟sde服務,而如果使用sde:sqlserver:ip地址或計算機名,則不需要建立和開啟服務。 locati
關於js對象中的,屬性的增刪改查問題
增刪改查 alt func 字面量 person per 技術分享 spa fine 刪除主要是delet方法; 1 function Person(){}; 2 var person = new Person();
java連接Oracle數據庫實現增刪改查並在Navicat中顯示
execute etag while args 自動 rest getc from lose 創建TEST表 eclipse中的java項目 代碼 數據庫方法類 DBUtil: package util; import java.sql.Connection;
listview展示網路資料+網路圖片+資料庫增刪改查+fragment
MainActivity package com.bwie.renzhili; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import andr
對xml檔案的sax解析(增刪改查)
crud(增刪改查): c:creat r:retrieve u:update d:delete 以下筆記來自於韓順平老師的講解。 現在是用java來操作。 第一步:新建java工程。file-new-Java Project,輸入工程的名字,點選finish. 第二步:放
C#在MVC模式下對單表專案執行總結的增刪改查
C#在MVC模式下對單表進行的增刪改查 1,首先建立一個新專案WebApplication1 2, 接著建立實體類product, 然後通過EF Code First建立資料庫初始資料。派生出DbContext的EF上下文。masterEntities對db檔案的實現 m
java+SQL做學生資訊管理系統(增刪改查)學生新作
java+SQL做學生資訊管理系統(增刪改查) 過程中需要用到的所有工具資料庫以及資料庫管理器等等 密碼:q80t 大學學習java後做的第一個小專案忍不住分享一下,也是我自己的面向物件程式設計的實踐作業啦,有點水,不是很優。廢話不多數,下面進入正題 介面的編
Java通過mongo-java-driver-3.0+操作mongodb資料庫(增刪改查)
本文以mongo-java-driver-3.5.0.jar為例 1 需要的jar包:https://pan.baidu.com/s/1jI3kB9W 密碼:79hv mongo-java-driver-3.5.0.jar junit-4.9.jar 2
java集合框架:List基本應用:增刪改查
package collection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; publi