Java操作BLOB和CLOB

BLOB
BLOB全称为二进制大型对象(Binary Large Object)。它用于存储数据库中的大型二进制对象。可存储的最大大小为4G字节,通常像图片、文件、音乐等信息就用BLOB字段来存储。

CLOB
CLOB全称为字符大型对象(Character Large Object)。它与LONG数据类型类似,只不过CLOB用于存储数据库中的大型单字节字符数据块,不支持宽度不等的字符集。可存储的最大大小为4G字节,文章或者是较长的文字,就用CLOB存储,这样对以后的查询更新存储等操作都提供很大的方便。

Java操作BLOB和CLOB

insert语句不支持blob字段的超长16进制字符串,执行sql会提示过长(较短可以)。

一、mysql数据库

写字段

存--手动执行sql语句,借助load_file()函数

# /absPath 为文件所在路径
insert into image_source(id, column_blob) values ('123', load_file("/absPath"));

存--使用preparedStatement

public static void insertBlobValue(File file){
    PreparedStatement ps = connection.prepareStatement("insert into image_source (id, column_blob) values (?, ?)");
    ps.setInt(1, 123);
    //输入流
    ps.setBlob(2, file.getInputStream(), file.getSize());
    ps.execute();
}

存--使用jdbcTemplate

//借助LobHandler
final LobHandler lobHandler = new DefaultLobHandler();
        jdbcTemplate.execute(modelSql, new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
            @Override
            protected void setValues(PreparedStatement preparedStatement, LobCreator lobCreator) throws SQLException, DataAccessException {
                lobCreator.setClobAsString(preparedStatement, 3, "yourClobContent");
            }
        });

LobCreator提供了多个接口来简化大字段的写入:对于BLOB,内容来源可以是InputStream、byte[];对于CLOB,内容来源可以是InputStream(自行确保都是ascii字符)、Reader、String。

读字段
同下Oracle方法。

二、oracle数据库

同mysql,blob无法直接insert,需要借助存储过程,CallableStatement,PreparedStatement,或JdbcTemplate。

写字段

一、使用存储过程, 脚本内容如下,hex串过长省略。

DECLARE
    v_blob BLOB;
BEGIN
    v_blob :=HEXTORAW('7B227265736F75.....');
INSERT INTO "AML_PLATFORM"."ACT_GE_BYTEARRAY"("ID_", "REV_", "NAME_", "DEPLOYMENT_ID_", "BYTES_", "GENERATED_")
    values ('900101', '1', 'risk', '', v_blob, '1');
end;

可以直接执行该脚本入库数据。

二、使用CallableStatement获取脚本内容执行

//该方式较麻烦,愿意使用的可以网上搜下

三、java代码执行脚本

InputStream inputStream = file.getInputStream();
            ScriptRunner runner = new ScriptRunner(jdbcTemplate.getDataSource().getConnection());
            runner.setAutoCommit(true);
            runner.setStopOnError(true);
            runner.setEscapeProcessing(false);
            runner.setSendFullScript(true);
            runner.runScript(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

四、PreparedStatement同mysql

五、JdbcTemplate

LobHandler lobHandler = new DefaultLobHandler();  // reusable object

 jdbcTemplate.execute(
     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
     new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
       protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
         ps.setString(1, name);
         lobCreator.setBlobAsBinaryStream(ps, 2, contentStream, contentLength);
         //lobCreator.setClobAsString(ps, 3, description);
       }
     }
 );
读字段

mybatis等框架也封装了特殊字段的处理方法,但是使用起来比较麻烦,这里仅写jdbcTemplate示例

//我的方法
String modelSql = "SELECT * FROM ACT_GE_BYTEARRAY WHERE ID_ in (SELECT EDITOR_SOURCE_VALUE_ID_ FROM ACT_RE_MODEL where ID_= ?)";
        List<Map<String, String>> query = jdbcTemplate.query(modelSql, new Object[]{flowId}, (resultSet, i) -> {
            final LobHandler lobHandler = new DefaultLobHandler();
            InputStream binaryStream = lobHandler.getBlobAsBinaryStream(resultSet, 5);
            IOUtils.toByteArray(binaryStream);
            byte[] blobAsBytes = lobHandler.getBlobAsBytes(resultSet, 5);
            String bytes = new String(blobAsBytes);
            HashMap<String, String> map = new HashMap<>(6);
            map.put("ID_", resultSet.getString(1));
            map.put("REV_", resultSet.getString(2));
            map.put("NAME_", resultSet.getString(3));
            map.put("DEPLOYMENT_ID_", resultSet.getString(4));
            map.put("BYTES_", bytes);
            map.put("GENERATED_", resultSet.getString(6));
            return map;
        });
//取出后为16进制字符串




//网上方法
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 final LobHandler lobHandler = new DefaultLobHandler();  // reusable object

 jdbcTemplate.query(
                 "SELECT content FROM imagedb WHERE image_name=?", new Object[] {name},
                 new AbstractLobStreamingResultSetExtractor() {
                         public void streamData(ResultSet rs) throws SQLException, IOException {
                    //业务处理
                         }
                 }
 );

两种仅区别于query的实现,实际上都是借助于spring封装的Lobhandler。

CLOB

clob不区分库

读, 使用ResultSet或LobHandler
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 final LobHandler lobHandler = new DefaultLobHandler();  // reusable object

 jdbcTemplate.query(
                 "SELECT content FROM imagedb WHERE image_name=?", new Object[] {name},
                 new AbstractLobStreamingResultSetExtractor() {
                         public void streamData(ResultSet rs) throws SQLException, IOException {
                             resultSet.getAsciiStream("columnIndex"/"clolumnName");
            resultSet.getCharacterStream("columnIndex"/"clolumnName");
            lobHandler.getClobAsAsciiStream("columnIndex"/"clolumnName");
            lobHandler.getClobAsCharacterStream("columnIndex"/"clolumnName");
            lobHandler.getClobAsString("columnIndex"/"clolumnName");
                    //业务处理
                         }
                 }
 );
写,使用PreparedStatement
 PreparedStatement ps = connection.prepareStatement("insert into image_source (id, column_blob, column_clob) values (?, ?, ?)");
        ps.setInt(1, 123);
        ps.setBlob(2, file.getInputStream(), file.getSize());
        ps.setClob(3, new InputStreamReader(file.getInputStream()) , file.getSize());
        ps.execute();

使用jdbcTemplate

jdbcTemplate.execute(modelSql, new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
            @Override
            protected void setValues(PreparedStatement preparedStatement, LobCreator lobCreator) throws SQLException, DataAccessException {
                lobCreator.setClobAsString(preparedStatement, 3, "yourClobContent");
                lobCreator.setClobAsAsciiStream(参数);
                lobCreator.setClobAsCharacterStream(参数);
            }
        });
原文地址:https://www.cnblogs.com/mzc1997/p/14348476.html