效果,首先打开HQL的参数日志,
这种也要看hibernate版本,5.1及其一下用这个,以上的可以用新的方式,也可以自己搜索打开HQL的参数日志的方法有几种方式
<logger category="org.hibernate.type.descriptor.sql.BasicBinder" use-parent-handlers="false">
<level name="TRACE"/>
<handlers>
<handler name="HIBERNATEFILE"/>
</handlers>
</logger>
或者使用SPY插件,我这个是jboss自带,
package util;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class MesLogHandel {
public static void main(String[] args) {
String select=" select * ";
HashSet<String> sqls=new HashSet<>();
String filePath ="F:\\SoftWare\\wildfly-10.1.0.Final-V6\\standalone\\log\\server.log";
String sqldemo=null;
//记录所有sql信息
List<String> allSqls=new ArrayList<>();
List<String> subSqls=new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "GB2312"))) {
String line;
String sqltext=null;
//线程map
Map<String,String> threadMaps=new HashMap<>();
//线程sqlMap
Map<String,String> sqlMaps=new HashMap<>();
//线程参数集合map
Map<String,List<Object>> listMaps=new HashMap<>();
//线程参数计数
Map<String,Integer> countMaps=new HashMap<>();
String thread=null;
String paramstring=null;
String lastSql=null;
while ((line = reader.readLine()) != null) {
// 逐行读取并处理
if (line.contains("prepareStatement(")){
//获取sql语句处理
sqltext=line.split("prepareStatement\\(")[1];
sqltext=sqltext.substring(0,sqltext.length()-1);
int count= countPlaceholders(sqltext);
if (count>0){
thread=line.split(" java:")[0].split("jdbc.spy] ")[1];
threadMaps.put(thread,thread);
countMaps.put(thread,countPlaceholders(sqltext));
sqlMaps.put(thread,sqltext);
List<Object> parmes=new ArrayList<>();
listMaps.put(thread,parmes);
}else{
allSqls.add(sqltext);
subSqls.add(sqltext);
//handleSql(sqltext,sqls);
}
}else if (line.contains("[PreparedStatement] set")){
//获取参数处理
thread=line.split(" java:")[0].split("jdbc.spy] ")[1];
if(threadMaps.containsKey(thread)){
paramstring=line.split("PreparedStatement")[1];
if (handleValue(paramstring,thread,listMaps,countMaps,sqlMaps)){
//参数获取完毕,清空线程所有信息
try {
lastSql=HqlSqlGenerator.generateSql(sqlMaps.get(thread),listMaps.get(thread));
//异常此sql作废,后续不做处理
allSqls.add(lastSql);
if (lastSql.contains("select * from (")&&lastSql.contains(") where rownum")){
int i=lastSql.indexOf(") where rownum");
lastSql=lastSql.substring(16,i);
//sqltext=sqlBuilder.toString().replaceAll("select * from \\(","").replaceAll("\\) where rownum <= ?","");
}
//handleSql(lastSql,sqls);
if(lastSql.indexOf(" from ")>0){
int pos=lastSql.indexOf(" from ");
lastSql=select+lastSql.substring(pos,lastSql.length());
}
subSqls.add(lastSql);
}catch (Exception e){
System.out.println("作废sql:"+lastSql);
System.out.println(e);
}
listMaps.remove(thread);
countMaps.remove(thread);
sqlMaps.remove(thread);
threadMaps.remove(thread);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("报错"+sqldemo);
System.out.println("Error reading file: " + filePath);
}
//存储原始sql
String cfilePath = "E:\\mesLogSql.txt";
//存储简化后的sql,去掉外层分页和select 所有选项改为select * ,多表查询时,可能会一起去掉了,但是字段都查太长了
String cfilePath1 = "E:\\mesLogSql1.txt";
try (BufferedWriter writer = new BufferedWriter(new FileWriter(cfilePath))) {
for (String sql:allSqls){
//System.out.println(sql);
if (handleFilter(false,sql)){
writer.write(sql+";");
writer.newLine();
}
}
} catch (IOException e) {
System.err.println("创建文件或写入文件时出错: " + e.getMessage());
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(cfilePath1))) {
for (String sql:subSqls){
//System.out.println(sql);
if (handleFilter(false,sql)){
writer.write(sql+";");
writer.newLine();
}
}
} catch (IOException e) {
System.err.println("创建文件或写入文件时出错: " + e.getMessage());
}
}
public static boolean handleFilter(boolean isfiter,String line){
boolean istrue=true;
if (isfiter){
if (line.contains("COM_TASK_HIS")||line.contains("COM_TASK_TIMESTAPM")||line.contains("COM_TASK")){
istrue=false;
}
}
return istrue;
}
/**
* 处理参数信息
* @param value
* @param thread
* @param listMaps
* @param countMaps
* @param sqlMaps
* @return
*/
public static boolean handleValue(String value,String thread,Map<String,List<Object>> listMaps, Map<String,Integer> countMaps,Map<String,String> sqlMaps){
boolean isOver=false;
try {
List<Object> params= listMaps.get(thread);
int i=value.indexOf("(");
int j=value.indexOf(",");
String colVaues=value.substring(j+1,value.length()-1).trim();
int count=Integer.valueOf(value.substring(i+1,j));
if (count==countMaps.get(thread)){
isOver=true;
}
if (value.contains("setString")){
params.add(colVaues);
}else if (value.contains("setLong")){
params.add(Long.valueOf(colVaues));
}else if (value.contains("setInt")){
params.add(Integer.valueOf(colVaues));
}else if (value.contains("setBigDecimal")){
params.add(new BigDecimal(colVaues));
}else if (value.contains("setTimestamp")){
params.add(colVaues);
}else if (value.contains("setBytes")){
params.add(colVaues);
}else if (value.contains("setNull")){
params.add(colVaues);
}else {
System.out.println("特殊类型"+value);
params.add(null);
}
listMaps.put(thread,params);
}catch (Exception e){
System.out.println("参数获取报错:"+value);
System.out.println(e);
}
return isOver;
}
/**
* 统计占位符号?的数量
* @param hql
* @return
*/
public static int countPlaceholders(String hql) {
if (hql == null) {
return 0;
}
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(hql);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
}
获取oracle的HQL日志,采取参数日志,拼装SQL语句
麻花20132025-05-28 23:17
相关推荐
_herbert6 分钟前
MAVEN构建分离依赖JAR野犬寒鸦20 分钟前
Pipeline功能实现Redis批处理(项目批量查询点赞情况的应用)꧁༺摩༒西༻꧂26 分钟前
Spring Boot Actuator 监控功能的简介及禁用Java中文社群1 小时前
快看!百度提前批的面试难度,你能拿下吗?丨千纸鹤丨1 小时前
Tomcat发发发发8881 小时前
leetcode 674.最长连续递增序列回忆是昨天里的海1 小时前
3.3.2_1栈在表达式求值中的应用(上)雨绸缪2 小时前
为什么 Java 在 2025 年仍然值得学习:开发人员的 25 年历程花花无缺3 小时前
泛型类和泛型方法泉城老铁3 小时前
Spring Boot 中实现 COM 口数据监听并解析十六进制数据,结合多线程处理