`
j夫子
  • 浏览: 92427 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

sql格式化工具(从hibernate中弄出来的)

    博客分类:
  • java
 
阅读更多
package com.zjfhw.iteye.sqlformat;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.StringTokenizer;

public class SQLFormatter {

	private static final Set<String> BEGIN_CLAUSES = new HashSet<String>();
	private static final Set<String> END_CLAUSES = new HashSet<String>();
	private static final Set<String> LOGICAL = new HashSet<String>();
	private static final Set<String> QUANTIFIERS = new HashSet<String>();
	private static final Set<String> DML = new HashSet<String>();
	private static final Set<String> MISC = new HashSet<String>();
	public static final String WHITESPACE = " \n\r\f\t";
	static {
		BEGIN_CLAUSES.add( "left" );
		BEGIN_CLAUSES.add( "right" );
		BEGIN_CLAUSES.add( "inner" );
		BEGIN_CLAUSES.add( "outer" );
		BEGIN_CLAUSES.add( "group" );
		BEGIN_CLAUSES.add( "order" );

		END_CLAUSES.add( "where" );
		END_CLAUSES.add( "set" );
		END_CLAUSES.add( "having" );
		END_CLAUSES.add( "join" );
		END_CLAUSES.add( "from" );
		END_CLAUSES.add( "by" );
		END_CLAUSES.add( "join" );
		END_CLAUSES.add( "into" );
		END_CLAUSES.add( "union" );

		LOGICAL.add( "and" );
		LOGICAL.add( "or" );
		LOGICAL.add( "when" );
		LOGICAL.add( "else" );
		LOGICAL.add( "end" );

		QUANTIFIERS.add( "in" );
		QUANTIFIERS.add( "all" );
		QUANTIFIERS.add( "exists" );
		QUANTIFIERS.add( "some" );
		QUANTIFIERS.add( "any" );

		DML.add( "insert" );
		DML.add( "update" );
		DML.add( "delete" );

		MISC.add( "select" );
		MISC.add( "on" );
	}

	static final String indentString = "    ";
	static final String initial = "\n    ";

	public String format(String source) {
		return new FormatProcess( source ).perform();
	}

	private static class FormatProcess {
		boolean beginLine = true;
		boolean afterBeginBeforeEnd = false;
		boolean afterByOrSetOrFromOrSelect = false;
		boolean afterValues = false;
		boolean afterOn = false;
		boolean afterBetween = false;
		boolean afterInsert = false;
		int inFunction = 0;
		int parensSinceSelect = 0;
		private LinkedList<Integer> parenCounts = new LinkedList<Integer>();
		private LinkedList<Boolean> afterByOrFromOrSelects = new LinkedList<Boolean>();

		int indent = 1;

		StringBuilder result = new StringBuilder();
		StringTokenizer tokens;
		String lastToken;
		String token;
		String lcToken;

		public FormatProcess(String sql) {
			tokens = new StringTokenizer(
					sql,
					"()+*/-=<>'`\"[]," + WHITESPACE,
					true
			);
		}

		public String perform() {

			result.append( initial );

			while ( tokens.hasMoreTokens() ) {
				token = tokens.nextToken();
				lcToken = token.toLowerCase();

				if ( "'".equals( token ) ) {
					String t;
					do {
						t = tokens.nextToken();
						token += t;
					}
					while ( !"'".equals( t ) && tokens.hasMoreTokens() ); // cannot handle single quotes
				}
				else if ( "\"".equals( token ) ) {
					String t;
					do {
						t = tokens.nextToken();
						token += t;
					}
					while ( !"\"".equals( t ) );
				}

				if ( afterByOrSetOrFromOrSelect && ",".equals( token ) ) {
					commaAfterByOrFromOrSelect();
				}
				else if ( afterOn && ",".equals( token ) ) {
					commaAfterOn();
				}

				else if ( "(".equals( token ) ) {
					openParen();
				}
				else if ( ")".equals( token ) ) {
					closeParen();
				}

				else if ( BEGIN_CLAUSES.contains( lcToken ) ) {
					beginNewClause();
				}

				else if ( END_CLAUSES.contains( lcToken ) ) {
					endNewClause();
				}

				else if ( "select".equals( lcToken ) ) {
					select();
				}

				else if ( DML.contains( lcToken ) ) {
					updateOrInsertOrDelete();
				}

				else if ( "values".equals( lcToken ) ) {
					values();
				}

				else if ( "on".equals( lcToken ) ) {
					on();
				}

				else if ( afterBetween && lcToken.equals( "and" ) ) {
					misc();
					afterBetween = false;
				}

				else if ( LOGICAL.contains( lcToken ) ) {
					logical();
				}

				else if ( isWhitespace( token ) ) {
					white();
				}

				else {
					misc();
				}

				if ( !isWhitespace( token ) ) {
					lastToken = lcToken;
				}

			}
			return result.toString();
		}

		private void commaAfterOn() {
			out();
			indent--;
			newline();
			afterOn = false;
			afterByOrSetOrFromOrSelect = true;
		}

		private void commaAfterByOrFromOrSelect() {
			out();
			newline();
		}

		private void logical() {
			if ( "end".equals( lcToken ) ) {
				indent--;
			}
			newline();
			out();
			beginLine = false;
		}

		private void on() {
			indent++;
			afterOn = true;
			newline();
			out();
			beginLine = false;
		}

		private void misc() {
			out();
			if ( "between".equals( lcToken ) ) {
				afterBetween = true;
			}
			if ( afterInsert ) {
				newline();
				afterInsert = false;
			}
			else {
				beginLine = false;
				if ( "case".equals( lcToken ) ) {
					indent++;
				}
			}
		}

		private void white() {
			if ( !beginLine ) {
				result.append( " " );
			}
		}

		private void updateOrInsertOrDelete() {
			out();
			indent++;
			beginLine = false;
			if ( "update".equals( lcToken ) ) {
				newline();
			}
			if ( "insert".equals( lcToken ) ) {
				afterInsert = true;
			}
		}

		@SuppressWarnings( {"UnnecessaryBoxing"})
		private void select() {
			out();
			indent++;
			newline();
			parenCounts.addLast( Integer.valueOf( parensSinceSelect ) );
			afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) );
			parensSinceSelect = 0;
			afterByOrSetOrFromOrSelect = true;
		}

		private void out() {
			result.append( token );
		}

		private void endNewClause() {
			if ( !afterBeginBeforeEnd ) {
				indent--;
				if ( afterOn ) {
					indent--;
					afterOn = false;
				}
				newline();
			}
			out();
			if ( !"union".equals( lcToken ) ) {
				indent++;
			}
			newline();
			afterBeginBeforeEnd = false;
			afterByOrSetOrFromOrSelect = "by".equals( lcToken )
					|| "set".equals( lcToken )
					|| "from".equals( lcToken );
		}

		private void beginNewClause() {
			if ( !afterBeginBeforeEnd ) {
				if ( afterOn ) {
					indent--;
					afterOn = false;
				}
				indent--;
				newline();
			}
			out();
			beginLine = false;
			afterBeginBeforeEnd = true;
		}

		private void values() {
			indent--;
			newline();
			out();
			indent++;
			newline();
			afterValues = true;
		}

		@SuppressWarnings( {"UnnecessaryUnboxing"})
		private void closeParen() {
			parensSinceSelect--;
			if ( parensSinceSelect < 0 ) {
				indent--;
				parensSinceSelect = parenCounts.removeLast().intValue();
				afterByOrSetOrFromOrSelect = afterByOrFromOrSelects.removeLast().booleanValue();
			}
			if ( inFunction > 0 ) {
				inFunction--;
				out();
			}
			else {
				if ( !afterByOrSetOrFromOrSelect ) {
					indent--;
					newline();
				}
				out();
			}
			beginLine = false;
		}

		private void openParen() {
			if ( isFunctionName( lastToken ) || inFunction > 0 ) {
				inFunction++;
			}
			beginLine = false;
			if ( inFunction > 0 ) {
				out();
			}
			else {
				out();
				if ( !afterByOrSetOrFromOrSelect ) {
					indent++;
					newline();
					beginLine = true;
				}
			}
			parensSinceSelect++;
		}

		private static boolean isFunctionName(String tok) {
			final char begin = tok.charAt( 0 );
			final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"' == begin;
			return isIdentifier &&
					!LOGICAL.contains( tok ) &&
					!END_CLAUSES.contains( tok ) &&
					!QUANTIFIERS.contains( tok ) &&
					!DML.contains( tok ) &&
					!MISC.contains( tok );
		}

		private static boolean isWhitespace(String token) {
			return WHITESPACE.indexOf( token ) >= 0;
		}

		private void newline() {
			result.append( "\n" );
			for ( int i = 0; i < indent; i++ ) {
				result.append( indentString );
			}
			beginLine = true;
		}
	}

      public static void main(String[] args) {
		String sql = new SQLFormatter().format("select * from t_sss");
		System.out.println(sql);
	}


}

 

5
2
分享到:
评论

相关推荐

    SQL格式化功能(C#代码)

    5. **优化**:去除与原始Hibernate中的无用功能,意味着这个C#实现可能更轻量级,专为SQL格式化而优化,运行效率更高。 由于没有提供具体的源代码,我们无法深入探讨实现细节。但是,开发人员可以根据提供的`sql...

    java格式化sql组件 从hibernate中提取出来的

    java格式化sql组件 从hibernate中提取出来的

    SQL格式化功能(JAVA代码)

    在给定的标题“SQL格式化功能(JAVA代码)”中,我们聚焦于一个特定的Java实现,它从Hibernate库中抽取了用于SQL格式化的功能,并且不依赖任何第三方jar包。 `Hibernate`是一个流行的Java ORM(对象关系映射)框架...

    从Hibernate提取的SQL格式化功能(JAVA代码)

    从Hibernate中提取的SQL格式化功能,去除了没用的功能,没有第三方jar包

    Java打印漂亮的SQL语句(被格式化的SQL语句)

    另一个标签"SQL格式化"则明确了它的主要功能,即整理SQL语句的结构,使其更具可读性。"优美的SQL语句"则暗示了经过格式化后的SQL会更加整洁,便于理解和审查。 压缩包中的"PrettySQLFormatter.jar"是预编译的Java...

    hibernate显示不带?的完整sql

    这会使Hibernate输出格式化的SQL语句,并用实际参数值替换问号。在你的配置文件中添加或修改如下: ```xml &lt;property name="hibernate.format_sql"&gt;true ``` 此外,还需要引入一个日志框架,如Log4j或SLF4J,以...

    sql2000与sql2005的hibernate-configuration

    综上所述,这篇博客文章可能讲解了如何在Hibernate中配置SQL Server 2000和2005,包括设置正确的驱动类、JDBC URL,以及在`hibernate.cfg.xml`中的其他配置,同时可能还提供了实际的代码示例和最佳实践。通过理解...

    Hibernate调用配置文件中的sql语句

    其中,`hibernate.show_sql`和`hibernate.format_sql`分别控制是否打印SQL以及是否格式化输出。 2. **创建SQL查询**:在映射文件(.hbm.xml)中,我们可以为实体类定义一个或多个`&lt;sql-query&gt;`标签来存放自定义SQL...

    让hibernate输出sql语句参数配置.doc

    当设置为 true 时,Hibernate 将格式化 SQL 语句,提高可读性和调试效率。 4. hibernate.default_schema hibernate.default_schema 参数用于在生成的 SQL 中,给定的 schema/tablespace 附加于非全限定名的表名上...

    sql-formatter:格式化SQL语句

    SQL格式化程序 这是什么? 格式化SQL语句。格式化从标准输入接收SQL语句,并将其输出到标准输出。 使用例 echo " SELECT * FROM HOGE WHERE HOGE.FUGA = :fuga " | java -jar target/sql-formatter-1.0.1-jar-with...

    SQL Injection攻击检测工具

    - 参数化查询:使用预编译的SQL语句,将用户输入作为参数传递,而非直接拼接在SQL字符串中。 - 输入验证:对用户输入进行严格的格式检查和限制,拒绝非法字符或格式。 - 最小权限原则:数据库用户应只拥有完成其...

    hibernate 自动导入 sql 文件 import.sql 国际化编码的问题的解决方案

    ### Hibernate自动导入SQL文件import.sql国际化编码问题的解决方案 #### 背景介绍 在使用Hibernate框架时,经常需要在项目启动初期或者数据库更新时自动执行一些SQL脚本(如DDL脚本)来创建或更新数据库结构。这些...

    Hibernate关系映射XML生成工具

    Hibernate是一款强大的对象关系映射(ORM)框架,它允许开发者用Java对象来操作数据库,而无需直接编写SQL语句。关系映射XML生成工具,如"Middlegen-Hibernate-r5",则是为了简化这一过程而设计的。这些工具能够自动...

    Hibernate连接Sql Server所需的jar包

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者通过Java对象来操作数据库,而无需编写大量的SQL语句。当使用Hibernate连接Microsoft SQL Server数据库时,需要特定的JDBC驱动来建立...

    SQL转Java代码小工具

    1. 支持SQL语法高亮和格式化,使生成的Java字符串易于阅读。 2. 提供选项来处理SQL中的变量,例如用问号占位符替换,以便于配合`PreparedStatement`防止SQL注入。 3. 具有处理包含子查询、联接、聚合函数等复杂SQL的...

    hibernate中文文档 HTML格式

    1. 实体(Entity):在Hibernate中,实体是Java类,它们代表数据库中的表。通过在实体类上使用`@Entity`注解来标识。 2. 表映射(Mapping):实体与数据库表之间的关系由Hibernate的XML配置文件(或使用注解)定义,...

    hibernate工具类大全

    在Hibernate中,持久化类是Java类,它们的实例可以被映射到数据库表。配置文件(通常是`hibernate.cfg.xml`或`persistence.xml`)定义了这些类与数据库表之间的映射关系,包括字段对应列、主键生成策略等。例如,`@...

    使用p6spy完整显示hibernate的SQL语句

    3. **格式化输出**:它能够以易于阅读的格式输出SQL,包括颜色编码,使我们更容易理解复杂的SQL操作。 4. **自定义日志格式**:p6spy允许开发者通过修改配置文件(通常是`spy.properties`)来自定义日志格式和内容...

    java+hibernate+sql小型租房系统

    9. **集成开发环境(IDE)**:开发者可能使用Eclipse、IntelliJ IDEA等IDE来编写和调试代码,这些工具提供了丰富的功能,如代码提示、自动格式化、调试等,提高了开发效率。 10. **测试**:为了保证系统的稳定性和...

    采用p6spy完整显示hibernate的SQL语句

    在开发和调试基于Hibernate的Java应用时,有时我们需要获取到SQL语句的完整形式,而不仅仅是Hibernate默认输出的参数化形式。在这种情况下,P6Spy是一个非常有用的工具。P6Spy是一个开源的JDBC代理库,它允许我们...

Global site tag (gtag.js) - Google Analytics