关于java:jdbc查询数据库流式查询和普通查询Blob数据读成压缩包生成byte数组

依据查问后果数据条数大小进行调整:

1、流式查问
长处:大数据量时不会有OOM问题。
毛病:占用数据库工夫更长,导致网络拥塞的可能性较大。

//连贯数据库(简略)
Class.forName("驱动");
Connection connection = DriverManager.getConnection(url,user,password)
List<Map<String, Object>> result = new ArrayList<>();
//ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY  开启流式查问
PreparedStatement ps = connection.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
        long l1 = System.currentTimeMillis();
        //设计每次查问的大小
        ps.setFetchSize(1000);
        long l2 = System.currentTimeMillis();
        LOG.info("查问工夫1000大小:"+(l2-l1));
        ResultSet rs = ps.executeQuery();//返回一个后果集对象
        // 利用sql查问获取后果集
        // 利用反射创立实体类的对象
        // 获取后果街的别名Stud_id 获取JDBC的元数据
        // 获取后果集每一列的值,联合上一步失去一个Map键值对
        // 键:列的别名 值:列的值
        // 在利用反射对实体类对象的属性赋值
        // 属性为Map的键 值为Map的值
        // 获取元数据
        ResultSetMetaData rsmd = rs.getMetaData();
        Map<String, Object> mapMetaData = new HashMap<>();
       // 打印一列的列名
                while (rs.next()) {
                    //获取数据表中满足要求的一行数据,并放入Map中
                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
                        String columnLabel = rsmd.getColumnLabel(i + 1);
                        Object columnValue = rs.getObject(columnLabel);
                        //获取数据库类型为Blob时
                        //Blob columnValue = rs.getBlob(columnLabel);
                        //InputStream ins = columnValue.getBinaryStream();
                        mapMetaData.put(columnLabel, columnValue);
                    }
                    //将Map中的数据通过反射初始化T类型对象
                    Map<String, Object> map = new HashMap<>();
                    if (mapMetaData.size() > 0) {
                        for (Map.Entry<String, Object> entry : mapMetaData.entrySet()) {
                            String fieldkey = entry.getKey();//字段名
                            Object fieldvalue = entry.getValue();//对应的值
                            // 判断附件属性
                            // map "fileData": "fileData"
                            if (CollectionUtil.isNotEmpty(fileDataMap) && StringUtil.isNotEmpty(blobFile) && fieldkey.equals(fileDataMap.get(EfmConfigConstant.FILE_DATA)) && null != fieldvalue) {
                                File file1 = new File(blobFile);
                                if (!file1.getParentFile().exists()) {
                                    boolean mkdirs = file1.mkdirs();
                                    if (!mkdirs) {
                                        LOG.error("建设文件失败");
                                    }
                                }
                                // 建设输入流
                                Blob blob = rs.getBlob(fieldkey);
                                try (InputStream in = blob.getBinaryStream(); FileOutputStream file = new FileOutputStream(file1.getPath() + File.separator + mapMetaData.get(EfmConfigConstant.FILE_NAME))) {
                                    int len = (int) blob.length();
                                    byte[] buffer = new byte[len]; // 建设缓冲区
                                    while ((len = in.read(buffer)) != -1) {
                                        file.write(buffer, 0, len);
                                    }
                                }
                            }
                            map.put(fieldkey, fieldvalue);
                        }
                    }

                    result.add(map);

2、一般查问
长处:利用代码简略,数据量较小时操作速度快。
毛病:数据量大时会呈现OOM问题。

//连贯数据库(简略)
Class.forName("驱动");
Connection connection = DriverManager.getConnection(url,user,password)
List<Map<String, Object>> result = new ArrayList<>();
PreparedStatement ps = connection.prepareStatement(sql);
        long l1 = System.currentTimeMillis();
        //设计客户端期待超时工夫(s)
        ps.setQueryTimeout(360);
        long l2 = System.currentTimeMillis();
        LOG.info("查问工夫1000大小:"+(l2-l1));
        ResultSet rs = ps.executeQuery();//返回一个后果集对象
        // 利用sql查问获取后果集
        // 利用反射创立实体类的对象
        // 获取后果街的别名Stud_id 获取JDBC的元数据
        // 获取后果集每一列的值,联合上一步失去一个Map键值对
        // 键:列的别名 值:列的值
        // 在利用反射对实体类对象的属性赋值
        // 属性为Map的键 值为Map的值
        // 获取元数据
        ResultSetMetaData rsmd = rs.getMetaData();
        Map<String, Object> mapMetaData = new HashMap<>();
       // 打印一列的列名
                while (rs.next()) {
                    //获取数据表中满足要求的一行数据,并放入Map中
                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
                        String columnLabel = rsmd.getColumnLabel(i + 1);
                        Object columnValue = rs.getObject(columnLabel);
                        //获取数据库类型为Blob时
                        //Blob columnValue = rs.getBlob(columnLabel);
                        //InputStream ins = columnValue.getBinaryStream();
                        mapMetaData.put(columnLabel, columnValue);
                    }
                    //将Map中的数据通过反射初始化T类型对象
                    Map<String, Object> map = new HashMap<>();
                    if (mapMetaData.size() > 0) {
                        for (Map.Entry<String, Object> entry : mapMetaData.entrySet()) {
                            String fieldkey = entry.getKey();//字段名
                            Object fieldvalue = entry.getValue();//对应的值
                            // 判断附件属性
                            // map "fileData": "fileData"
                            if (CollectionUtil.isNotEmpty(fileDataMap) && StringUtil.isNotEmpty(blobFile) && fieldkey.equals(fileDataMap.get(EfmConfigConstant.FILE_DATA)) && null != fieldvalue) {
                                File file1 = new File(blobFile);
                                if (!file1.getParentFile().exists()) {
                                    boolean mkdirs = file1.mkdirs();
                                    if (!mkdirs) {
                                        LOG.error("建设文件失败");
                                    }
                                }
                                // 建设输入流
                                Blob blob = rs.getBlob(fieldkey);
                                try (InputStream in = blob.getBinaryStream(); FileOutputStream file = new FileOutputStream(file1.getPath() + File.separator + mapMetaData.get(EfmConfigConstant.FILE_NAME))) {
                                    int len = (int) blob.length();
                                    byte[] buffer = new byte[len]; // 建设缓冲区
                                    while ((len = in.read(buffer)) != -1) {
                                        file.write(buffer, 0, len);
                                    }
                                }
                            }
                            map.put(fieldkey, fieldvalue);
                        }
                    }

                    result.add(map);

读取Blob类型的数据为压缩包格局解决成文件读成byte数组:

                //errorFile为自定义文件生成门路
                //jdbc查问获取Blob,生成压缩包文件
                String columnLabel = rsmd.getColumnLabel(1);
                Blob columnValue = rs.getBlob(columnLabel);
                InputStream ins = columnValue.getBinaryStream();
                File file = new File(errorFile, "cs.zip");
                FileUtils.copyInputStreamToFile(ins, file);
                ZipFile zipFile = new ZipFile(file, Charset.defaultCharset());
                Stream<? extends ZipEntry>  signStream = zipFile.stream();
                Stream<? extends ZipEntry> zipStream = zipFile.stream();
                //断言
                Predicate<ZipEntry> signTxt = ze -> ze.getName().contains("sign,txt");
                Predicate<ZipEntry> zipTxt = ze -> ze.getName().endsWith(".zip");
                //过滤
                Optional<ZipEntry> signInfo = (Optional<ZipEntry>) signStream.filter(signTxt).findFirst();
                Optional<ZipEntry> zipInfo = (Optional<ZipEntry>) zipStream.filter(zipTxt).findFirst();
                ins.close();
                zipFile.close();
                //获取文件名称
                String fileName = rsmd.getColumnLabel(2);
                Object fileNames = rs.getObject(fileName);
                //解压zip文件
                String name = ZipUtils.unzip(file.getPath(), errorFile+File.separator);
                //删除文件
                file.delete();
                //读成byte数组
                byte[] bytes = FileUtil.readFile2Bytes(new File(errorFile + File.separator + name), true);

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理