• java代码将16进制字符串转换为图片,jdbc入库blob字段,解决ORA-01704,PLS-00172,ORA-06550,字符串文字太长等问题


    从Oracle导出SQL文件中的insert语句包含blob字段,语句HEXTORAW函数将16进制的字符串入库,由于字符串太长,insert失败

    下面的代码读取完整的insert语句,将HEXTORAW函数连同16进制的字符串替换为NULL,先将字段置空插入记录,然后使用PreparedStatement对图片文件读流更新入库

    import org.apache.commons.io.FileUtils;
    
    import javax.imageio.ImageIO;
    import javax.imageio.stream.FileImageOutputStream;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.math.BigInteger;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.List;
    
    public class ImageUtils {
    
        public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
            File file = new File("C:\Users\Nihaorz\Desktop\b_file_insert.sql");
            List<String> list = FileUtils.readLines(file, "UTF-8");
            for (String s : list) {
                String imageFilePath = null;
                String id = null;
                String[] array = s.split(",");
                StringBuilder sb = new StringBuilder();
                for (String s1 : array) {
                    if (s1.startsWith(" HEXTORAW(")) {
                        id = sb.toString();
                        id = id.substring("INSERT INTO "B_FILE" VALUES ('".length());
                        id = id.substring(0, id.indexOf("'"));
                        sb.append(" NULL");
                        String hexString = s1.trim();
                        hexString = hexString.substring("HEXTORAW('".length(), hexString.length() - 1);
                        imageFilePath = "C:\Users\Nihaorz\Desktop\b_file_images\" + id + ".jpg";
                        hexToImage(imageFilePath, hexString);
                    } else {
                        sb.append(s1);
                    }
                    sb.append(",");
                }
                sb.deleteCharAt(sb.length() - 1);
                sb.deleteCharAt(sb.length() - 1);
                insert2Kingbase(sb.toString(), imageFilePath, id);
            }
        }
    
        public static boolean insert2Oracle(String insertSql, String imgPath, String id) throws ClassNotFoundException, SQLException, FileNotFoundException {
            boolean flag = false;
            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@x.x.x.x:1521:orcl", "xxx", "xxx");
            conn.createStatement().execute(insertSql);
            // 打印除blob字段之外的insert语句
            System.out.println(insertSql);
            String sql = "update b_file set file_tx = ? where file_id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            InputStream is = new FileInputStream(imgPath);
            pstmt.setBlob(1, is);
            //还可以通过二进制流的方法存放图片pstmt.setBinaryStream(1,is);
            pstmt.setString(2, id);
            int i = pstmt.executeUpdate();
            if (i > 0) {
                flag = true;
                System.out.println("插入图片成功");
            } else {
                System.out.println("插入图片失败");
            }
            close(pstmt, conn, is);
            return flag;
        }
    
        public static boolean insert2Kingbase(String insertSql, String imgPath, String id) throws ClassNotFoundException, SQLException, FileNotFoundException {
            boolean flag = false;
            Class.forName("com.kingbase8.Driver");
            Connection conn = DriverManager.getConnection("jdbc:kingbase8://x.x.x.x:54321/xxx", "xxx", "xxx");
            conn.createStatement().execute(insertSql);
            // 打印除blob字段之外的insert语句
            System.out.println(insertSql);
            String sql = "update b_file set file_tx = ? where file_id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            InputStream is = new FileInputStream(imgPath);
            pstmt.setBlob(1, is);
            //还可以通过二进制流的方法存放图片pstmt.setBinaryStream(1,is);
            pstmt.setString(2, id);
            int i = pstmt.executeUpdate();
            if (i > 0) {
                flag = true;
                System.out.println("插入图片成功");
            } else {
                System.out.println("插入图片失败");
            }
            close(pstmt, conn, is);
            return flag;
        }
    
        private static void close(AutoCloseable... closeables) {
            for (AutoCloseable autoCloseable : closeables) {
                if (autoCloseable != null) {
                    try {
                        autoCloseable.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 将图片转换成十六进制字符串
         */
        static String imageToHex(String filePath) {
            File f = new File(filePath);
            String suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
            BufferedImage bi;
            try {
                bi = ImageIO.read(f);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.write(bi, suffix, baos);
                byte[] bytes = baos.toByteArray();
                return new BigInteger(1, bytes).toString(16);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 将十六进制字符串转化成图片
         */
        static void hexToImage(String filePath, String hexString) {
            byte[] bytes = stringToByte(hexString);
            try {
                FileImageOutputStream imageOutput = new FileImageOutputStream(new File(filePath));
                imageOutput.write(bytes, 0, bytes.length);
                imageOutput.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
        public static byte[] stringToByte(String s) {
            int length = s.length() / 2;
            byte[] bytes = new byte[length];
            for (int i = 0; i < length; i++) {
                bytes[i] = (byte) ((Character.digit(s.charAt(i * 2), 16) << 4) | Character.digit(s.charAt((i * 2) + 1), 16));
            }
            return bytes;
        }
    
    }

    b_file_insert.sql 示例,HEXTORAW('xxxxxx') 仅做示例,正常的是合法的16进制字符串

    INSERT INTO "B_FILE" VALUES ('f7fb0c74-8bdc-4edd-8bae-14e9b923c1c0', '长安.jpg', 'image/jpeg', '510368', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:43:54.780000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('ca6a7638-7ab5-437d-a486-f354fd210308', '麻涌.jpg', 'image/jpeg', '441326', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:46:23.792000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('df5be551-653e-4640-bfd6-7581cdce36fb', '洪梅.jpg', 'image/jpeg', '394404', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:48:19.201000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('abe056c6-d2a5-41b6-bc96-a05e6364b59b', '道滘.jpg', 'image/jpeg', '480304', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:48:58.139000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('7c99a74a-f8c4-4cdc-9e59-6735564bc126', '黄江.jpg', 'image/jpeg', '554472', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:50:23.518000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('409f586f-f086-48a8-a367-4d42fba26890', '谢岗.jpg', 'image/jpeg', '562335', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:51:08.539000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
    INSERT INTO "B_FILE" VALUES ('cf923739-6938-448f-af06-bc8d70678dac', '桥头.jpg', 'image/jpeg', '519045', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:51:49.255000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')

    b_file表结构

    -- Create table
    create table B_FILE
    (
      file_id         VARCHAR2(64) not null,
      file_name       VARCHAR2(64),
      file_type       VARCHAR2(100),
      file_size       VARCHAR2(16),
      file_small      BLOB,
      file_tx         BLOB,
      file_createtime TIMESTAMP(6),
      file_remark     VARCHAR2(512)
    )
    tablespace DATA
      pctfree 10
      initrans 1
      maxtrans 255
      storage
      (
        initial 64K
        next 1M
        minextents 1
        maxextents unlimited
      );
    -- Create/Recreate primary, unique and foreign key constraints 
    alter table B_FILE
      add primary key (FILE_ID)
      using index 
      tablespace DATA
      pctfree 10
      initrans 2
      maxtrans 255
      storage
      (
        initial 64K
        next 1M
        minextents 1
        maxextents unlimited
      );

    说明

    1、此示例中b_file表存在两个blob字段,且所有记录的file_small字段均为null,如果处理的表不止一个blob字段,需根据实际情况调整代码逻辑

    2、对于此代码造成的数据丢失本人概不负责

    参考链接:

    https://blog.csdn.net/rexueqingchun/article/details/78150877

    https://blog.csdn.net/qq_34514384/article/details/51134416

  • 相关阅读:
    痞子衡嵌入式:恩智浦MCU集成开发环境与开发工具教程
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.4)- 串行NOR Flash下载算法(Keil MDK工具篇)
    《痞子衡嵌入式半月刊》 第 17 期
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.3)- 串行NOR Flash下载算法(J-Link工具篇)
    《痞子衡嵌入式半月刊》 第 16 期
    痞子衡嵌入式:关于做技术的工作态度方面的几点建议
    痞子衡嵌入式:MCUXpresso IDE下添加C++源文件进SDK工程编译的方法
    痞子衡嵌入式:职场上有效地向师傅请教问题的几点建议
    痞子衡职场经验与见闻感悟分享
    痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link/DAPLink)
  • 原文地址:https://www.cnblogs.com/nihaorz/p/15464498.html
Copyright © 2020-2023  润新知