工具记载
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 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);
}
}
}
}
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.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.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.util.ArrayList;
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();
// 获取到最终的sql语句
try {
String sql = showSql(configuration, boundSql);
log.info("{} ==> : Preparing: {}", id, sql);
} catch (Exception e) {
log.error("{} ==> : Preparing error: {}", id, e.getMessage());
}
long start = System.currentTimeMillis();
// 执行完上面的任务后,不改变原有的sql执行过程
Object result = invocation.proceed();
long time = System.currentTimeMillis() - start;
// 获取到最终的结果数
try {
String total = shownTotal(result);
log.info("{} <== : Total: {} , time: {}ms", id, total, time);
} catch (Exception e) {
log.error("{} <== : Total 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(new Date()) + "'";
} else {
if (obj != null) {
value = obj.toString();
} else {
value = "";
}
}
return value;
}
}
标签:zipOutputStream,String,zip,param,file,import,工具
From: https://www.cnblogs.com/Zzzyyw/p/18280154