效果,首先打开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
相关推荐
程序员清风1 小时前
RocketMQ发送消息默认是什么策略,主同步成功了就算成功了?异步写?还是要大部分从都同步了?starstarzz1 小时前
解决idea无法正常加载lombok包oioihoii1 小时前
C++11 Thread-Local Storage:从入门到精通YuTaoShao1 小时前
Java八股文——消息队列「场景篇」YuTaoShao1 小时前
Java八股文——Redis「淘汰删除篇」FlyWIHTSKY2 小时前
idea中push拒绝,merge,rebase的区别Code季风2 小时前
深入实战 —— Protobuf 的序列化与反序列化详解(Go + Java 示例)Leslie_Lei2 小时前
【pdf】Java代码生成PDF想用offer打牌3 小时前
关于Seata的一个小issue...😯飞翔的佩奇3 小时前
基于Spring+MyBatis+MySQL实现的监考安排与查询系统设计与实现(附源码+数据库)推荐!