获取oracle的HQL日志,采取参数日志,拼装SQL语句

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