项目里需要扫代码的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,并通过可视化工具进行展示。 首先,你需要安装Eclipse IDE,并且确保已经安装了JDT插件。如果你使用的是默认的Eclipse IDE安装,那么JDT通常已经包含在内。...
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代表源...
3. **构建工具**:JDT包含了构建工具,如Java Builder,它自动编译项目中的源代码,并在发现错误时提供反馈。此外,还有支持Ant和Maven的插件,使开发者能够轻松管理不同类型的构建过程。 4. **调试器**:Eclipse ...
1. **源代码编辑器**:Eclipse JDT提供了集成的Java源代码编辑器,支持语法高亮、自动代码完成、错误检测和快速修复,以及重构工具。这些功能极大地提高了开发效率和代码质量。 2. **构建工具**:JDT包含了一个基于...
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工程的创建、导入和导出,以及...
- **描述**:介绍了如何使用API来编译Java源代码。 - **关键步骤**:设置编译环境、编译代码、处理编译错误。 #### 5.3 使用Java搜索引擎 - **描述**:讲解了如何使用搜索引擎在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提供了丰富的重构工具,如提取方法、重命名、移动...