获取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;
    }
}
相关推荐
_herbert6 分钟前
MAVEN构建分离依赖JAR
java
野犬寒鸦20 分钟前
Pipeline功能实现Redis批处理(项目批量查询点赞情况的应用)
java·服务器·数据库·redis·后端·缓存
꧁༺摩༒西༻꧂26 分钟前
Spring Boot Actuator 监控功能的简介及禁用
java·数据库·spring boot
Java中文社群1 小时前
快看!百度提前批的面试难度,你能拿下吗?
java·后端·面试
丨千纸鹤丨1 小时前
Tomcat
java·tomcat
发发发发8881 小时前
leetcode 674.最长连续递增序列
java·数据结构·算法·leetcode·动态规划·最长连续递增序列
回忆是昨天里的海1 小时前
3.3.2_1栈在表达式求值中的应用(上)
java··后缀表达式·前缀表达式
雨绸缪2 小时前
为什么 Java 在 2025 年仍然值得学习:开发人员的 25 年历程
java·后端·掘金·金石计划
花花无缺3 小时前
泛型类和泛型方法
java·后端
泉城老铁3 小时前
Spring Boot 中实现 COM 口数据监听并解析十六进制数据,结合多线程处理
java·后端·物联网