`
j夫子
  • 浏览: 91412 次
  • 性别: 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
分享到:
评论

相关推荐

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

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

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

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

    SQL格式化功能(JAVA代码)

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

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

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

    sql-formatter:格式化SQL语句

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

    hibernate3.2中文文档(chm格式)

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    Hibernate 中文 html 帮助文档

    5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用 XDoclet 标记 5.5.2. 使用 JDK 5.0 的注解(Annotation) 5.6. 数据库生成属性(Generated Properties) 5.7. 辅助数据库对象(Auxiliary Database ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  ...

    SQL tool 3.0

    很强大。拿来分享。... 提供Sql格式化功能以助于Sql语句的识别。 7. 提供Redo/Undo,Shift退格进格,大小写转化,StringBuilder化等常用文字编辑功能。 8. 能保存和记忆数据库信息,以便下次打开。

    精通hibernate:对象持久化技术孙卫琴第二版part2

    6.1.2 从序列(Sequence)中获取自动增长的标识符 124 6.2 Java语言按内存地址区分不同的对象 125 6.3 Hibernate用对象标识符(OID)来区分对象 126 6.4 Hibernate的内置标识符生成器的用法 128 6.4.1 increment...

    hibernateCriteria查询

    Criteria查询将数据查询条件封装成为一个对象,可以堪称是传统SQL的对象化表示。

    最新p6spy-3.6.0监控框架Hibernate和Mybatis执行数据库sql,调试监控项目程序运行状态

    内含p6spy-3.6.0.zip,p6spy最新Hibernate和Mybatis拦截并格式化sql配置.txt两个文件,用于调试监控项目运行状态,亲测可用,测试整理出来花了我很长时间的,好用不可多得!

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  ...

    精通Hibernate:对象持久化技术第二版part3

    6.1.2 从序列(Sequence)中获取自动增长的标识符 124 6.2 Java语言按内存地址区分不同的对象 125 6.3 Hibernate用对象标识符(OID)来区分对象 126 6.4 Hibernate的内置标识符生成器的用法 128 6.4.1 increment...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     6.1.2 从序列(Sequence)中获取自动增长的标识符 6.2 Java语言按内存地址区分不同的对象 6.3 Hibernate用对象标识符(OID)来区分对象 6.4 Hibernate的内置标识符生成器的用法  6.4.1 increment标识符生成器  ...

    hibernate配置

    数据库中表的主键名所对应的持久化对象中的属性名" column="对应数据库中表的主键名" type="java.lang.String(数据库中主键字段的数据类型)"&gt; &lt;generator class="assigned"&gt;&lt;/generator&gt; //数据库中的主键生成...

    Struts2+Hibernate3开发实现青鸟租房管理系统

    同时使用Oracle数据库技术,附带sql执行脚本,多条插入语句技术, 实现了上传并限制格式和大小的功能, 实现了datetimepicker选择日期的功能, 实现了用户注册功能, 实现了无刷新登录功能, 实现了国际化功能, 实现...

    java后台框架源码

    filter:Log4jFormatFilter(格式化log4j日志输出的),SessionCheckFilter(登陆拦截器) interceptor:权限拦截包 listener:目前只有session的监听器,用于监听session的 service:具体的业务处理包 util:项目工具包 ...

Global site tag (gtag.js) - Google Analytics