工具

工具记载

Zip操作

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileZipUtils {

    private static final String POINT = ".";

    private static final String SUFFIX = POINT + "zip";

    /**
     * 创建压缩文件
     *
     * @param filePath 文件路径
     */
    public static void zip(String filePath) {
        zip(new File(filePath));
    }

    /**
     * 创建压缩文件
     *
     * @param file 文件
     */
    public static void zip(File file) {
        String filePath = file.getAbsolutePath();
        String zipFilePath;
        if (file.isDirectory()) {
            zipFilePath = filePath + SUFFIX;
        } else {
            zipFilePath = filePath.substring(0, filePath.lastIndexOf(POINT)) + SUFFIX;
        }
        log.debug("zipFilePath:{}", zipFilePath);
        zip(file, zipFilePath);
    }

    /**
     * 创建压缩文件
     *
     * @param filePath    文件路径
     * @param zipFilePath 压缩文件路径
     */
    public static void zip(String filePath, String zipFilePath) {
        File file = new File(filePath);
        zip(file, zipFilePath);
    }

    /**
     * 创建压缩文件
     *
     * @param file        文件
     * @param zipFilePath 压缩文件路径
     */
    public static void zip(File file, String zipFilePath) {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath)))) {
            // 添加文件到压缩包
            if (file.isDirectory()) {
                compressFolder(file, zipOutputStream);
            } else {
                addToZipFile(file, zipOutputStream);
            }
        } catch (IOException e) {
            log.error("创建压缩文件 error", e);
        }
    }

    /**
     * 创建压缩文件
     *
     * @param files       文件集合
     * @param zipFilePath 压缩文件路径
     */
    public static void zip(File[] files, String zipFilePath) {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFilePath)))) {
            // 添加文件到压缩包
            for (File file : files) {
                if (file.isDirectory()) {
                    compressFolder(file, zipOutputStream);
                } else {
                    addToZipFile(file, zipOutputStream);
                }
            }
        } catch (IOException e) {
            log.error("创建压缩文件 error", e);
        }
    }

    /**
     * 解压缩文件
     *
     * @param zipFilePath zip文件路径
     */
    public static void unzip(String zipFilePath) {
        File zipFile = new File(zipFilePath);
        unzip(zipFilePath, zipFile.getParentFile().getAbsolutePath());
    }

    /**
     * 解压缩文件
     *
     * @param zipFile zip文件
     */
    public static void unzip(File zipFile) {
        String zipFilePath = zipFile.getAbsolutePath();
        unzip(zipFilePath, zipFile.getParentFile().getAbsolutePath());
    }

    /**
     * 解压缩文件
     *
     * @param zipFilePath zip文件路径
     * @param filePath    文件路径
     */
    public static void unzip(String zipFilePath, String filePath) {
        try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)))) {
            // 解压缩文件
            unzipFiles(zipInputStream, filePath);
        } catch (IOException e) {
            log.error("解压缩文件 error", e);
        }
    }

    /**
     * 解压缩文件
     *
     * @param zipInputStream zip文件
     * @param filePath       文件
     * @throws IOException IOException
     */
    private static void unzipFiles(ZipInputStream zipInputStream, String filePath) throws IOException {
        byte[] buffer = new byte[1024];
        ZipEntry entry;
        while ((entry = zipInputStream.getNextEntry()) != null) {
            String fileName = entry.getName();
            File outputFile = new File(getPath(filePath, fileName));
            // 创建文件夹
            // entry.isDirectory() 的 判断逻辑为 name.endsWith("/"),受到系统限制,故不使用
            if (fileName.endsWith(File.separator)) {
                outputFile.mkdirs();
            } else {
                // 创建文件并写入内容
                new File(outputFile.getParent()).mkdirs();
                try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile)) {
                    int bytesRead;
                    while ((bytesRead = zipInputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, bytesRead);
                    }
                }
            }
            zipInputStream.closeEntry();
        }
    }

    /**
     * 添加文件夹到zip文件
     *
     * @param folder          文件夹
     * @param zipOutputStream zip文件
     * @throws IOException IOException
     */
    private static void compressFolder(File folder, ZipOutputStream zipOutputStream) throws IOException {
        compressFolder(folder, folder.getName(), zipOutputStream);
    }

    /**
     * 添加文件夹到zip文件
     *
     * @param folder          文件夹
     * @param zipEntryName    zip压缩文件名称
     * @param zipOutputStream zip文件
     * @throws IOException IOException
     */
    private static void compressFolder(File folder, String zipEntryName, ZipOutputStream zipOutputStream) throws IOException {
        File[] folderFiles = folder.listFiles();
        if (folderFiles != null && folderFiles.length > 0) {
            for (File folderFile : folderFiles) {
                String name = folderFile.getName();
                String folderFileEntryName = getPath(zipEntryName, name);
                if (folderFile.isDirectory()) {
                    // 压缩子文件夹
                    compressFolder(folderFile, folderFileEntryName, zipOutputStream);
                } else {
                    // 压缩文件
                    addToZipFile(folderFile, folderFileEntryName, zipOutputStream);
                }
            }
        } else {
            // 空文件夹处理
            emptyFolder(zipEntryName, zipOutputStream);
        }
    }

    /**
     * 空文件夹处理
     *
     * @param zipEntryName    zip压缩文件名称
     * @param zipOutputStream zip文件
     * @throws IOException IOException
     */
    private static void emptyFolder(String zipEntryName, ZipOutputStream zipOutputStream) throws IOException {
        // // 空文件夹的处理
        ZipEntry entry = new ZipEntry(getSepPath(zipEntryName));
        zipOutputStream.putNextEntry(entry);
        // 没有文件,不需要文件的copy
        zipOutputStream.closeEntry();
    }

    /**
     * 添加文件到zip文件
     *
     * @param file            文件
     * @param zipOutputStream zip文件
     * @throws IOException IOException
     */
    private static void addToZipFile(File file, ZipOutputStream zipOutputStream) throws IOException {
        addToZipFile(file, file.getName(), zipOutputStream);
    }

    /**
     * 添加文件到zip文件
     *
     * @param file            文件
     * @param zipEntryName    zip压缩文件名称
     * @param zipOutputStream zip文件
     * @throws IOException IOException
     */
    private static void addToZipFile(File file, String zipEntryName, ZipOutputStream zipOutputStream) throws IOException {
        // 创建ZipEntry对象并设置文件名
        ZipEntry entry = new ZipEntry(zipEntryName);
        zipOutputStream.putNextEntry(entry);
        // 读取文件内容并写入Zip文件
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, bytesRead);
            }
        }
        // 完成当前文件的压缩
        zipOutputStream.closeEntry();
    }

    /**
     * 获取 separator结尾 路径
     *
     * @param path 获取 separator结尾 路径
     * @return separator结尾 路径
     */
    private static String getSepPath(String... path) {
        return getPath(path) + File.separator;
    }

    /**
     * 获取路径
     *
     * @param path 获取路径
     * @return 路径
     */
    private static String getPath(String... path) {
        return String.join(File.separator, path);
    }

    /**
     * 创建文件
     *
     * @param file 文件
     */
    private static void createNewFile(File file) {
        String path = file.getAbsolutePath();
        if (!file.exists()) {
            try {
                boolean create = file.createNewFile();
                log.info("createNewFile:{} -> path:{}", create, path);
            } catch (IOException e) {
                log.error("createNewFile -> path:{}, error", path);
            }
        }
    }
}

GZIP操作

可用于压缩超大的json串 等

import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * GZIPUtils
 *
 * @author JunJian
 * @since 2024/7/8 14:52
 */
@Slf4j
public class GZIPUtils {
    public static final String GZIP_ENCODE_UTF_8 = "UTF-8";

    /**
     * 字符串压缩为GZIP字节数组
     *
     * @param str 字符串
     * @return GZIP压缩后的字节数组(base64编码)
     */
    public static String compressToString(String str) {
        byte[] bytes = compress(str, GZIP_ENCODE_UTF_8);
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(bytes);
    }

    /**
     * 字符串压缩为GZIP字节数组
     *
     * @param str 字符串
     * @return GZIP压缩后的字节数组
     */
    public static byte[] compress(String str) {
        return compress(str, GZIP_ENCODE_UTF_8);
    }

    /**
     * 字符串压缩为GZIP字节数组
     *
     * @param str      字符串
     * @param encoding 编码方式
     * @return GZIP压缩后的字节数组
     */
    public static byte[] compress(String str, String encoding) {
        if (str == null || str.isEmpty()) {
            return null;
        }
        byte[] bytes = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(out)) {
            gzip.write(str.getBytes(encoding));
            gzip.finish();
            bytes = out.toByteArray();
        } catch (IOException e) {
            log.error("压缩失败!", e);
        }
        return bytes;
    }

    /**
     * GZIP解压缩
     *
     * @param bytes GZIP压缩后的字节数组
     * @return 原字符串字节数组
     */
    public static byte[] unCompress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        byte[] origBytes = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(bytes);
             GZIPInputStream unGzip = new GZIPInputStream(in)) {
            byte[] buffer = new byte[256];
            int n;
            while ((n = unGzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            origBytes = out.toByteArray();
        } catch (IOException e) {
            log.error("解压失败!", e);
        }
        return origBytes;
    }

    /**
     * 解压并返回String
     *
     * @param str GZIP压缩后的字节数组(base64编码)
     * @return 原字符串字节数组(转String)
     */
    public static String unCompressString(String str) {
        if (str == null || str.isEmpty()) {
            return null;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] bytes = null;
        try {
            bytes = decoder.decodeBuffer(str);
        } catch (IOException e) {
            log.error("BASE64Decoder 异常", e);
        }
        return unCompressToString(bytes, GZIP_ENCODE_UTF_8);
    }

    /**
     * 解压并返回String
     *
     * @param bytes GZIP压缩后的字节数组
     * @return 原字符串字节数组(转String)
     */
    public static String unCompressToString(byte[] bytes) {
        return unCompressToString(bytes, GZIP_ENCODE_UTF_8);
    }

    /**
     * GZIP解压缩
     *
     * @param bytes GZIP压缩后的字节数组
     * @return 原字符串字节数组
     */
    public static byte[] unCompressToByteArray(byte[] bytes) {
        return unCompressToByteArray(bytes, GZIP_ENCODE_UTF_8);
    }

    /**
     * 解压成字符串
     *
     * @param bytes    压缩后的字节数组
     * @param encoding 编码方式
     * @return 解压后的字符串
     */
    public static String unCompressToString(byte[] bytes, String encoding) {
        byte[] origBytes = unCompressToByteArray(bytes, encoding);
        if (origBytes == null || origBytes.length == 0) {
            return null;
        }
        return new String(origBytes);
    }

    /**
     * 解压成字节数组
     *
     * @param bytes    压缩后的字节数组
     * @param encoding 编码方式
     * @return 解压后的字符串
     */
    public static byte[] unCompressToByteArray(byte[] bytes, String encoding) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        byte[] byteArray = null;
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(bytes);
             GZIPInputStream unGzip = new GZIPInputStream(in)) {
            byte[] buffer = new byte[256];
            int n;
            while ((n = unGzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            byteArray = out.toByteArray();
        } catch (IOException e) {
            log.error("解压缩失败!", e);
            throw new RuntimeException(e);
        }
        return byteArray;
    }

    /**
     * 将字节流转换成文件
     *
     * @param file 文件
     * @param data 字节流
     */
    public static void saveFile(File file, byte[] data) {
        if (data != null) {
            if (file.exists()) {
                boolean delete = file.delete();
                log.debug("{} - {}", file.getPath(), delete);
            }
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(data, 0, data.length);
                fos.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

临时文件

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * TempFileUtils
 *
 * @author JunJian
 * @since 2024/7/8 14:52
 */
@Slf4j
public class TmpFileUtils {

    /**
     * 创建服务临时文件
     *
     * @param fileName 文件名称
     * @return 服务临时文件
     */
    public static File createTmpFile(String fileName) {
        return createTmpFile(fileName, createTmpDir());
    }

    /**
     * 创建服务临时文件
     *
     * @param fileName 文件名称
     * @param dir      目录
     * @return 服务临时文件
     */
    public static File createTmpFile(String fileName, File dir) {
        File file = new File(dir, fileName);
        if (!file.exists()) {
            boolean create = false;
            try {
                create = file.createNewFile();
            } catch (IOException e) {
                log.error("临时文件 - 创建 - 异常: path:{}", file.getPath(), e);
            }
            log.debug("临时文件 - 创建: path:{} - create:{}", file.getPath(), create);
        }
        return file;
    }


    /**
     * 创建服务临时文件夹目录
     *
     * @return 服务临时文件夹目录
     */
    public static File createTmpDir() {
        String path = UUID.randomUUID().toString().replace("-", "");
        return createTmpDir(path);
    }

    /**
     * 创建服务临时文件夹目录
     *
     * @param dirName 路径名称
     * @return 服务临时文件夹目录
     */
    public static File createTmpDir(String dirName) {
        File file = new File(getTmp(), dirName);
        if (!file.exists()) {
            boolean create = file.mkdirs();
            log.debug("临时文件夹 - 创建: path:{} - create:{}", file.getPath(), create);
        }
        return file;
    }

    /**
     * 获取系统临时文件夹目录
     *
     * @return 系统临时文件夹目录
     */
    public static String getTmp() {
        return System.getProperty("java.io.tmpdir");
    }

    /**
     * 删除文件
     *
     * @param folder 文件
     */
    public static void deleteFolder(File folder) {
        String path = folder.getPath();
        boolean delete = delete(folder);
        log.debug("临时文件 - 删除: path:{} - delete:{}", path, delete);
    }

    /**
     * 删除文件
     *
     * @param folder 文件
     * @return 是否删除
     */
    private static boolean delete(File folder) {
        if (folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    delete(file);
                }
            }
        }
        return folder.delete();
    }
}

Mybatis

Mybatis日志替换?并打印耗时

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Matcher;

/**
 * MyBatis拦截器打印不带问号的完整sql语句
 */
@Slf4j
@Component
// 只在开发环境下执行
// @ConditionalOnProperty(value = "spring.profiles.active", havingValue = "dev")
// @ConditionalOnProperty(value = "com.mybatis.showSql", havingValue = "1")
@Intercepts({
        // update 包括了最常用的 insert/update/delete 三种操作
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
                Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class,
                Object.class, RowBounds.class, ResultHandler.class})})
public class MybatisSQLResolverInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取xml中的一个select/update/insert/delete节点,是一条SQL语句
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = null;
        // 获取参数,if语句成立,表示sql语句有参数,参数格式是map形式
        if (invocation.getArgs().length > 1) {
            parameter = invocation.getArgs()[1];
        }
        // 获取到节点的id,即sql语句的id
        String id = mappedStatement.getId();
        // BoundSql就是封装myBatis最终产生的sql类
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        // 获取节点的配置
        Configuration configuration = mappedStatement.getConfiguration();
        // 判断是否是查询
        boolean isSelect = SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType());
        // 获取到最终的sql语句
        try {
            String sql = showSql(configuration, boundSql);
            log.info("{} : ==> Preparing: {}", id, sql);
        } catch (Exception e) {
            log.error("{} : ==> showSql error: {}", id, e.getMessage());
        }
        long start = System.currentTimeMillis();
        // 执行完上面的任务后,不改变原有的sql执行过程
        Object result = invocation.proceed();
        long time = System.currentTimeMillis() - start;
        // 获取到最终的结果数
        try {
            String total = shownTotal(result);
            if (isSelect) {
                log.info("{} : <== Total: {} , time: {}ms", id, total, time);
            } else {
                log.info("{} : <== Updates: {} , time: {}ms", id, total, time);
            }
        } catch (Exception e) {
            log.error("{} : <== shownTotal error: {}", id, e.getMessage());
        }
        return result;
    }

    /**
     * 进行?的替换
     */
    public static String showSql(Configuration configuration, BoundSql boundSql) {
        // 获取参数
        Object parameterObject = boundSql.getParameterObject();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        // sql语句中多个空格都用一个空格代替
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        if (CollectionUtils.isNotEmpty(parameterMappings) && parameterObject != null) {
            // 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            // 如果根据parameterObject.getClass()可以找到对应的类型,则替换
            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                sql = sql.replaceFirst("\\?",
                        Matcher.quoteReplacement(getParameterValue(parameterObject)));
            } else {
                // MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作
                MetaObject metaObject = configuration.newMetaObject(parameterObject);
                for (ParameterMapping parameterMapping : parameterMappings) {
                    String propertyName = parameterMapping.getProperty();
                    if (metaObject.hasGetter(propertyName)) {
                        Object obj = metaObject.getValue(propertyName);
                        sql = sql.replaceFirst("\\?",
                                Matcher.quoteReplacement(getParameterValue(obj)));
                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
                        // 该分支是动态sql
                        Object obj = boundSql.getAdditionalParameter(propertyName);
                        sql = sql.replaceFirst("\\?",
                                Matcher.quoteReplacement(getParameterValue(obj)));
                    } else {
                        // 未知参数,替换?防止错位
                        sql = sql.replaceFirst("\\?", "unknown");
                    }
                }
            }
        }
        return sql;
    }

    /**
     * 获取结果数
     */
    private String shownTotal(Object result) {
        if (Objects.nonNull(result)) {
            if (result instanceof Collection<?>) {
                int size = ((Collection<?>) result).size();
                return String.valueOf(size);
            }
            if (result instanceof Number) {
                return String.valueOf(result);
            }
            if (result instanceof Page<?>) {
                int size = ((Page<?>) result).getRecords().size();
                return String.valueOf(size);
            }
        }
        return "0";
    }

    /**
     * 如果参数是String,则添加单引号
     * 如果参数是日期,则转换为时间格式器并加单引号; 对参数是null和不是null的情况作了处理
     */
    private static String getParameterValue(Object obj) {
        String value;
        if (obj instanceof String) {
            value = "'" + obj.toString() + "'";
        } else if (obj instanceof Date) {
            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
                    DateFormat.DEFAULT, Locale.CHINA);
            value = "'" + formatter.format(obj) + "'";
        } else {
            if (obj != null) {
                value = obj.toString();
            } else {
                value = "null";
            }
        }
        return value;
    }
}
posted @ 2024-07-02 16:48  Zzzy君不见  阅读(6)  评论(0编辑  收藏  举报