项目里需要扫代码的sql,主要是想找出所有用到的sql。 将相关的sql 提交给DBA 来分析,希望在最早的时间发现潜在的查询性能问题。
想想eclipse 里面用到的JDT 能分析java 源代码, 如果我们能分析项目里的源代码利用ASTParser 就可以找到相关的SQL 定义了。
其实已经有人想到这个 http://www.programcreek.com/2011/01/a-complete-standalone-example-of-astparser
,已经自己整理过所有会依赖的jar,机器重装本地的 repository给丢了。 所有就直接用这个链接里面给的一个zip 包, 但是在我现在用到的eclipse 还需要 一个 org.eclipse.text_3.5.0.jar 。
为了这个代码不要弄丢了,直接放一份 当然没有项目里面的信息
package com.bwang.jdt; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.FieldDeclaration; public class SqlExtractor { private BufferedWriter writer; private long counter = 0; private final String fileRoot; private final String logFileName; public static void main (String[] args) { if (args.length < 2) { System.out.println("Please provide the parameters:"); System.out.println("SqlExtractor codeOfRoot logFileName"); System.exit(-1); } SqlExtractor sqlExtractor = new SqlExtractor(args); sqlExtractor.extractSql(); } SqlExtractor(String[] args) { fileRoot = args[0]; logFileName = args[1]; try { writer = new BufferedWriter(new FileWriter(new File(logFileName))); } catch(IOException e) { } } private void analyzeOneFile(String sourceFile, Writer writer) { String source = getFileContent(sourceFile); ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setSource(source.toCharArray()); CompilationUnit unit = (CompilationUnit)parser.createAST(null); unit.recordModifications(); StringBuilder sb = new StringBuilder(); List<AbstractTypeDeclaration> types = unit.types(); for (AbstractTypeDeclaration type : types) { if (type.getNodeType() == ASTNode.TYPE_DECLARATION) { // Class def found List<BodyDeclaration> bodies = type.bodyDeclarations(); for (BodyDeclaration body : bodies) { if (body.getNodeType() == ASTNode.FIELD_DECLARATION /*&& ((FieldDeclaration)body).getType().equals(Type.S) */ ) { FieldDeclaration field = (FieldDeclaration)body; if(field.toString().toLowerCase().indexOf("select") >=0) { sb.append(field.toString()); counter++; } } } } } if (sb.length() > 0) { try { if (counter > 0) { writer.append("\n\n"); } sourceFile = sourceFile.replace(fileRoot, ""); sourceFile = sourceFile.replace("\\", "/"); writer.append(sourceFile + "\n"); String content = sb.toString(); content = content.replace("\" +", "\"\n\t\t+ "); content = content.replace("\"+", "\"\n\t\t+ "); writer.append(content); }catch(IOException ioe) { } } } private void extractSql() { File folder = new File(fileRoot); List<File> poms = new ArrayList<File>(); handleOneFolder(folder, poms); System.out.println("begin to analyze files of :" + poms.size()); try { int index = 1; for(File f : poms) { System.out.println("begin to analyze file : " + index + " " + f.getName()); analyzeOneFile(f.getPath(), writer); index++; } } finally { try { writer.flush(); writer.close(); } catch(IOException e) { } } System.out.println("successfully find sql count:" + counter); } private void handleOneFolder(File folder, List<File> poms) { if(!folder.isDirectory()) { return; } String[] files = folder.list(); for(String oneFile : files) { String fullFileName = folder.getPath() + "/" + oneFile; if (fullFileName.endsWith(".java") && fullFileName.indexOf("src\\test\\java\\") < 0) { poms.add(new File(fullFileName)); continue; } File f = new File(fullFileName); if (f.isDirectory()) { handleOneFolder(f, poms); } } } private String getFileContent(String fName) { try { File file = new File(fName); BufferedReader in = new BufferedReader(new FileReader(file)); StringBuffer buffer = new StringBuffer(); String line = null; while (null != (line = in.readLine())) { buffer.append("\t" + line); buffer.append("\n"); } return buffer.toString(); } catch (IOException e) { throw new RuntimeException(e); } } }
思路也简单就是遍历 codeOfRoot 下面的所有java 文件, 找到 所有的field 定义的值里面包含 select 关键字的 field, 然后将所有这些满足条件的都写到一个log 文件。
到时候将log 文件发给DBA 就行了。 当然还可以更进一步来个CI, 可以定期去扫项目的代码, 然后比较产生的log 文件的变化。 然后DBA 定期看 变化的SQL 就好了, 是不是很酷。
相关推荐
本资料“基于Eclipse-JDT生成Java源代码的AST并可视化.zip”着重介绍了如何利用Eclipse JDT来生成Java源代码的抽象语法树(Abstract Syntax Tree, AST)并进行可视化展示。 首先,让我们深入了解什么是AST。AST是一...
3. **编写代码分析器**:创建一个新的Java类,如`CodeAnalyzer`,并使用JDT API来解析和检查Java源代码。例如,我们可以检查类中是否存在未使用的变量或方法。 4. **运行插件**:通过Eclipse的插件开发环境(PDE)...
而AST则是Eclipse JDT中一个非常重要的概念,它是Java源代码的一种内部表示形式,可以被用来分析和修改程序结构。 ##### 2.1 AST基本概念 - **AST**:抽象语法树是一种树形的数据结构,它表示程序的语法结构。在...
对于调试MS的Java源代码,通常会使用Visual Studio Code (VS Code) 或者Eclipse等集成开发环境(IDE),它们都提供了强大的调试工具。确保你的IDE已经安装了Java和相关插件,如Java Debugger (for VS Code) 或者JDT ...
在Eclipse JDT中,AST(Abstract Syntax Tree,抽象语法树)是解析Java源代码的关键工具,它将源代码转换为一种层次化的数据结构,便于进行各种代码分析和处理。 AST的节点定位是其核心操作之一。每个ASTNode代表源...
1. **源代码编辑器**:Eclipse JDT提供了集成的Java源代码编辑器,支持语法高亮、自动代码完成、错误检测和快速修复,以及重构工具。这些功能极大地提高了开发效率和代码质量。 2. **构建工具**:JDT包含了一个基于...
3. **构建工具**:JDT包含了构建工具,如Java Builder,它自动编译项目中的源代码,并在发现错误时提供反馈。此外,还有支持Ant和Maven的插件,使开发者能够轻松管理不同类型的构建过程。 4. **调试器**:Eclipse ...
1. 编译器:JDT Core中的Java编译器是基于ANTLR(ANother Tool for Language Recognition)的,能够解析和理解Java源代码,生成字节码,进行类型检查和错误报告。它还支持Javadoc的生成以及遵循Java语言规范的新特性...
`ant编译用jdt_jars`指的是使用Ant进行项目构建时,利用JDT的相关库来执行编译任务。 Ant是一个开源的Java构建工具,它的主要功能包括编译源代码、打包、测试、部署等。与传统的Makefile相比,Ant使用XML来描述构建...
通过上述代码,可以获取到对应的Java元素,并利用JDT API进行进一步的操作,如遍历、查询模型中的信息等。此外,这些Java元素也支持对底层非Java资源的查询操作。 #### Java元素的显示与浏览 某些Java元素可以在...
3. **调试工具**:Eclipse.jdt集成了强大的调试器,允许开发者在源代码级别进行断点设置、单步执行、查看变量值、调用堆栈等操作,方便问题定位和修复。 4. **项目管理**:它支持Java工程的创建、导入和导出,以及...
在学习过程中,你可以逐个研究源代码,理解它们如何利用Java 6的新特性,同时参考附录中的解释和指导,这将有助于你全面掌握这个版本的Java编程。记得在实践中不断调试和测试,以便更好地理解和运用这些知识。
源代码包含了从第9章到第23章的全部示例项目,旨在帮助读者通过实际操作来学习和巩固理论知识。 在Eclipse的学习中,了解和掌握以下几个关键知识点至关重要: 1. **工作空间(Workspace)管理**:Eclipse的工作...
6. **Java模型和API**:介绍JDT提供的Java模型,用于访问和操作项目中的Java元素,以及如何利用JDT API进行插件开发。 7. **版本控制集成**:说明如何将Eclipse与版本控制系统(如SVN、Git等)集成,进行代码版本...
`jdt-compiler.jar`是这个工具集中的关键组件,包含了Java源代码的编译逻辑。 描述中提到的"进度条"和"动画加载的计算"可能是在讨论一个用户界面(UI)设计,其中进度条用于展示动画加载的状态。在软件开发中,特别是...
它包含了用于解析、操作和生成Java源代码的类,包括构建AST的工具。通过JDT,你可以实现诸如提取类信息、查找特定方法、分析类型关系等功能。 Javassist则是另一个流行的Java字节码操作库,它不仅可以用来动态生成...
【JDT基础知识】\n\nJava Development Tools (JDT) 是Eclipse IDE中的核心组件,专注于Java语言...同时,掌握如何利用这些工具来创建自定义的代码分析和改进工具,将极大地提升开发者在Java开发环境中的效率和专业性。
5. **项目管理(Project Management)**:JDT允许开发者创建、管理和组织Java项目,包括源代码目录结构、构建路径、依赖关系等。 6. **重构(Refactoring)**:JDT提供了丰富的重构工具,如提取方法、重命名、移动...