`
Vity
  • 浏览: 3498 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

SQL 语句组装类 (JAVA 实现)

阅读更多
自己某事写了个SQL组装工具类

支持普通条件、日期条件(Oracle和Mysql)。

支持比较运算,like查询,in查询,not in 查询。

支持分组,排序。

代码如下:
package cn.create.cbl.core.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;

import cn.create.cbl.core.exception.AppException;
import cn.create.cbl.core.global.Constants;
import cn.create.cbl.core.global.ResultCode;

public class SQLQueryUtil extends BaseUtil {

	private static final long serialVersionUID = -4008847394285279230L;

	private static String USE_JDBC_DRIVER = Constants.getConfig("jdbc.driverClassName");

	/**
	 * main()
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		SQLQueryUtil util = new SQLQueryUtil();
		util.addTable("base_user");
		util.addTable("base_group");
		util.addColumn("user_name");
		util.addColumn("user_age");
		util.addAndCondition("id", RelationalOperators.EQ, "xxxx", ValueType.STRING);
		util.addAndInCondition("user_age", "'x','x','x','x','x'");
		util.addOrLikeCondition("xxx", "yyyy");
		util.addGroupBy("user_name");
		util.addAscOrderBy("create_time");
		util.addDescOrderBy("id");
		System.out.println(util.toSQL());
	}

	/**
	 * 日期格式化字符串 如:2013-06-20
	 */
	public static final String FMT_DATE = "yyyy-MM-dd";

	/**
	 * 时间格式化字符串 如:13:01:01
	 */
	public static final String FMT_TIME = "HH:mm:ss";

	/**
	 * 日期时间格式化字符串 如:2013-06-20 13:01:01
	 */
	public static final String FMT_DATETIME = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 逻辑运算
	 * 
	 * @author Vity
	 * 
	 */
	public enum LogicalOperators {
		AND("AND"), OR("OR");
		private String value;

		private LogicalOperators(String value) {
			this.value = value;
		}

		public String toString() {
			return new String(this.value);
		}
	}

	/**
	 * 关系运算
	 * 
	 * <p>
	 * EQ("="), NE("<>"), GT(">"), GE(">="), LT("<"), LE("<=")
	 * </p>
	 * 
	 * @author Vity
	 * 
	 */
	public enum RelationalOperators {
		EQ("="), NE("<>"), GT(">"), GE(">="), LT("<"), LE("<=");
		private String value;

		private RelationalOperators(String value) {
			this.value = value;
		}

		public String toString() {
			return this.value;
		}
	}

	/**
	 * 排序方式
	 * 
	 * @author Vity
	 * 
	 */
	public enum SortMethod {
		ASC("ASC"), DESC("DESC");
		private String value;

		private SortMethod(String value) {
			this.value = value;
		}

		public String toString() {
			return this.value;
		}
	}

	/**
	 * 值类型
	 * 
	 * @author Vity
	 * 
	 */
	public enum ValueType {
		NUMBER, DATE, STRING, TIME, DATETIME
	}

	/**
	 * 内置表别名前缀
	 */
	private final String TABLE_ALIAS_NAME = "TEMP_TABLE_ALIAS_";

	/**
	 * 内置表别名索引
	 */
	private int TABLE_ALIAS_INDEX = 0;

	/**
	 * 是否调试模式 非调试模式则不打印SQL语句
	 */
	private boolean isDebug = true;

	/**
	 * 是否去重
	 */
	private boolean isDistinct = false;

	/**
	 * 表名及别名集合 key : table & view name | value : alias name
	 * <p>
	 * <b>注意:</b>目前不支持重复表查询
	 * </p>
	 */
	private Map<String, String> tableMap = new HashMap<String, String>();

	/**
	 * 待查列名集合 key : column name value : | alias name
	 */
	private Map<String, String> columnMap = new HashMap<String, String>();

	/**
	 * 查询条件集合 key : and & or | value 条件值
	 */
	private Map<String, String> conditionMap = new IdentityHashMap<String, String>();

	/**
	 * 排序条件集合
	 */
	private Map<String, String> orderMap = new HashMap<String, String>();

	/**
	 * 分组集合
	 */
	private List<String> groupList = new ArrayList<String>();

	/**
	 * sql生成结果
	 */
	private StringBuilder sqlResult = new StringBuilder();

	/**
	 * 追加字符串,在后面添加一个空格
	 * 
	 * @param string
	 * @return
	 */
	private SQLQueryUtil append(String string) {
		sqlResult.append(string).append(" ");
		return this;
	}

	/**
	 * 删除最后两位字符串
	 * 
	 * @return
	 */
	private SQLQueryUtil clearEndChar() {
		sqlResult.delete(sqlResult.length() - 2, sqlResult.length());
		return this;
	}

	/**
	 * 生成SQL语句
	 * 
	 * @return
	 */
	public String toSQL() {
		if (tableMap.isEmpty()) {
			throw new AppException(ResultCode.Failure, "未发现表或视图");
		}

		this.append("SELECT");

		if (isDistinct) {
			this.append("DISTINCT");
		}

		if (columnMap.isEmpty()) {
			this.append("*");
		} else {
			for (String key : columnMap.keySet()) {
				this.append(key);
				if (!StringUtils.isBlank(columnMap.get(key))) {
					this.append("AS").append(columnMap.get(key));
				}
				this.append(",");
			}
			this.clearEndChar();
		}

		this.append("FROM");

		for (String key : tableMap.keySet()) {
			this.append(key);
			if (!StringUtils.isBlank(tableMap.get(key))) {
				this.append("AS").append(tableMap.get(key));
			}
			this.append(",");
		}
		this.clearEndChar().append(" ");

		if (!groupList.isEmpty()) {
			this.append("GROUP BY");
			for (String field : groupList) {
				this.append(field).append(",");
			}
			this.clearEndChar();
		}

		if (!conditionMap.isEmpty()) {
			if (!groupList.isEmpty()) {
				this.append("HAVING");
			} else {
				this.append("WHERE");
			}
			this.append("1 = 1");
			for (Entry<String, String> entry : conditionMap.entrySet()) {
				this.append(entry.getKey()).append(entry.getValue());
			}
		}

		if (!orderMap.isEmpty()) {
			this.append("ORDER BY");
			for (String key : orderMap.keySet()) {
				this.append(key).append(orderMap.get(key)).append(",");
			}
			this.clearEndChar();
		}

		if (isDebug) {
			logger.trace(sqlResult.toString().replace(" ,", ",").replace("  ", " ").replace(" 1 = 1 AND", "").replace(" 1 = 1 OR", ""));
		}
		return sqlResult.toString().replace(" ,", ",").replace("  ", " ").replace(" 1 = 1 AND", "").replace(" 1 = 1 OR", "");
	}

	/**
	 * 设置 是否Distinct查询
	 * 
	 * @param isDistinct
	 */
	public void setDistinct(boolean isDistinct) {
		this.isDistinct = isDistinct;
	}

	/**
	 * 添加待查询的表或视图名称
	 * 
	 * @param tableName
	 * @return
	 */
	public SQLQueryUtil addTable(String tableName) {
		tableMap.put(tableName, TABLE_ALIAS_NAME + TABLE_ALIAS_INDEX++);
		return this;
	}

	/**
	 * 添加待查询的表或视图名称,并指定别名
	 * 
	 * @param tableName
	 * @param aliasName
	 * @return
	 */
	public SQLQueryUtil addTable(String tableName, String aliasName) {
		if (aliasName.contains(TABLE_ALIAS_NAME)) {
			throw new AppException(ResultCode.Failure, "不能使用这个别名前缀:" + TABLE_ALIAS_NAME);
		}
		tableMap.put(tableName, aliasName);
		return this;
	}

	/**
	 * 添加待查列
	 * 
	 * @param columnName
	 * @return
	 */
	public SQLQueryUtil addColumn(String columnName) {
		return this.addColumn(columnName, "");
	}

	/**
	 * 添加待查列,并指定别名
	 * 
	 * @param columnName
	 * @param aliasName
	 * @return
	 */
	public SQLQueryUtil addColumn(String columnName, String aliasName) {
		columnMap.put(columnName, aliasName);
		return this;
	}

	/**
	 * 添加查询条件
	 * 
	 * <p>
	 * <span>针对日期类型查询的说明</span> <div>
	 * 日期查询必须将查询值按照本类提供的格式化字符串进行格式化,并指定相应的ValueType </div>
	 * </p>
	 * 
	 * @param logicalOperators
	 * @param cKey
	 * @param relationalOperators
	 * @param cValue
	 * @param valueType
	 * @return
	 */
	private SQLQueryUtil addCondition(LogicalOperators logicalOperators, String cKey, RelationalOperators relationalOperators, String cValue,
			ValueType valueType) {
		switch (valueType) {
		case STRING:
			conditionMap.put(logicalOperators.toString(),
					cKey.concat(" ").concat(relationalOperators.toString()).concat(" '").concat(cValue).concat("'"));
			break;
		case NUMBER:
			conditionMap.put(logicalOperators.toString(), cKey.concat(" ").concat(relationalOperators.toString()).concat(" ").concat(cValue));
			break;
		default:
			conditionMap.put(logicalOperators.toString(), this.getDateTimeQuery(cKey, relationalOperators, cValue, valueType));
			break;

		}
		return this;
	}

	/**
	 * 目前仅支持 Oracle, MySQL ; 日期查询生成 其他数据库方式请根据需要自行扩展
	 */
	private String getDateTimeQuery(String cKey, RelationalOperators ro, String cValue, ValueType vt) {
		if (USE_JDBC_DRIVER.toLowerCase().contains("oracle")) {
			switch (vt) {
			case DATE:
				return "to_char(".concat(cKey).concat(",'yyyy-mm-dd')").concat(ro.toString()).concat("'").concat(cValue).concat("'");
			case TIME:
				return "to_char(".concat(cKey).concat(",'hh24:mi:ss')").concat(ro.toString()).concat("'").concat(cValue).concat("'");
			case DATETIME:
				return "to_char(".concat(cKey).concat(",'yyyy-mm-dd hh24:mi:ss')").concat(ro.toString()).concat("'").concat(cValue).concat("'");
			default:
				break;
			}
		} else if (USE_JDBC_DRIVER.toLowerCase().contains("mysql")) {
			switch (vt) {
			case DATE:
				return cKey.concat(ro.toString()).concat("UNIX_TIMESTAMP('").concat(cValue).concat(" 00:00:00')");
			case TIME:
				throw new AppException(ResultCode.Failure, "暂不支持MySQL某段时间内查询,请确认日期后使用 ValueType.DATETIME 查询");
			case DATETIME:
				return cKey.concat(ro.toString()).concat("UNIX_TIMESTAMP('").concat(cValue).concat("')");
			default:
				break;
			}
		}
		return cKey.concat(" ").concat(ro.toString()).concat(" \"").concat(cValue).concat("\"");
	}

	private SQLQueryUtil addLikeCondition(LogicalOperators logicalOperators, String cKey, String cValue) {
		if (cValue.contains("%")) {
			conditionMap.put(logicalOperators.toString(), cKey.concat(" LIKE \"").concat(cValue).concat("\""));
		} else {
			conditionMap.put(logicalOperators.toString(), cKey.concat(" LIKE \"%").concat(cValue).concat("%\""));
		}
		return this;
	}

	private SQLQueryUtil addInCondition(LogicalOperators logicalOperators, String cKey, String cValue) {
		conditionMap.put(logicalOperators.toString(), cKey.concat(" IN ( ").concat(cValue).concat(" )"));
		return this;
	}

	private SQLQueryUtil addNotInCondition(LogicalOperators logicalOperators, String cKey, String cValue) {
		conditionMap.put(logicalOperators.toString(), cKey.concat(" NOT IN ( ").concat(cValue).concat(" )"));
		return this;
	}

	private SQLQueryUtil addOrderBy(String orderField, SortMethod sortMethod) {
		orderMap.put(orderField, sortMethod.toString());
		return this;
	}

	/**
	 * 添加分组字段
	 * 
	 * @param groupField
	 * @return
	 */
	public SQLQueryUtil addGroupBy(String groupField) {
		groupList.add(groupField);
		return this;
	}

	/**
	 * 添加 AND查询条件
	 * 
	 * @param cKey
	 * @param relationalOperators
	 * @param cValue
	 * @param valueType
	 * @return
	 */
	public SQLQueryUtil addAndCondition(String cKey, RelationalOperators relationalOperators, String cValue, ValueType valueType) {
		return this.addCondition(LogicalOperators.AND, cKey, relationalOperators, cValue, valueType);
	}

	/**
	 * 添加 OR查询条件
	 * 
	 * @param cKey
	 * @param relationalOperators
	 * @param cValue
	 * @param valueType
	 * @return
	 */
	public SQLQueryUtil addOrCondition(String cKey, RelationalOperators relationalOperators, String cValue, ValueType valueType) {
		return this.addCondition(LogicalOperators.OR, cKey, relationalOperators, cValue, valueType);
	}

	/**
	 * 添加 AND LIKE 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addAndLikeCondition(String cKey, String cValue) {
		return this.addLikeCondition(LogicalOperators.AND, cKey, cValue);
	}

	/**
	 * 添加 OR LIKE 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addOrLikeCondition(String cKey, String cValue) {
		return this.addLikeCondition(LogicalOperators.OR, cKey, cValue);
	}

	/**
	 * 添加 AND IN 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addAndInCondition(String cKey, String cValue) {
		return this.addInCondition(LogicalOperators.AND, cKey, cValue);
	}

	/**
	 * 添加 OR IN 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addOrInCondition(String cKey, String cValue) {
		return this.addInCondition(LogicalOperators.OR, cKey, cValue);
	}

	/**
	 * 添加 AND NOT IN 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addAndNotInCondition(String cKey, String cValue) {
		return this.addNotInCondition(LogicalOperators.AND, cKey, cValue);
	}

	/**
	 * 添加 OR NOT IN 查询条件
	 * 
	 * @param cKey
	 * @param cValue
	 * @return
	 */
	public SQLQueryUtil addOrNotInCondition(String cKey, String cValue) {
		return this.addNotInCondition(LogicalOperators.OR, cKey, cValue);
	}

	/**
	 * 添加正向排序字段
	 * 
	 * @param orderField
	 * @return
	 */
	public SQLQueryUtil addAscOrderBy(String orderField) {
		return this.addOrderBy(orderField, SortMethod.ASC);
	}

	/*
	 * 添加逆向排序字段
	 */
	public SQLQueryUtil addDescOrderBy(String orderField) {
		return this.addOrderBy(orderField, SortMethod.DESC);
	}

	/**
	 * 清除待查表和视图
	 * 
	 * @return
	 */
	public SQLQueryUtil clearTable() {
		tableMap.clear();
		return this;
	}

	/**
	 * 清除待查列
	 * 
	 * @return
	 */
	public SQLQueryUtil clearColumn() {
		columnMap.clear();
		return this;
	}

	/**
	 * 清除查询条件
	 * 
	 * @return
	 */
	public SQLQueryUtil clearCondition() {
		conditionMap.clear();
		return this;
	}

	/**
	 * 清除排序条件
	 * 
	 * @return
	 */
	public SQLQueryUtil clearOrder() {
		orderMap.clear();
		return this;
	}

	/**
	 * 清除分组列
	 * 
	 * @return
	 */
	public SQLQueryUtil clearGroup() {
		groupList.clear();
		return this;
	}
}

0
5
分享到:
评论
2 楼 Vity 2013-06-21  
xiaokang1582830 写道
有什么实质性的意义?


使用spring jdbc 的时候组装sql
1 楼 xiaokang1582830 2013-06-21  
有什么实质性的意义?

相关推荐

    动态拼接sql语句工具类,拼接where后面语句

    动态拼接sql语句工具类,拼接where后面语句 配合原生jdbc仿动态sql注入 if (ObjectUtil.isNotEmpty(maxLat)&&ObjectUtil.isNotEmpty(minLat)){ sqlParamList.add(new SqlParam("lat",minLat, SqlOpEnum.GE)); ...

    OCCI接口和SQL语句的组装.pdf

    ### OCCI接口与SQL语句组装...通过上述介绍,我们可以看到OCCI接口和SQL语句组装在Java应用程序与Oracle数据库交互中的重要作用。合理地设计和实现这些功能不仅可以提高应用程序的性能,还能确保数据的安全性和一致性。

    在ibatis日志信息中打印SQL语句的方法(个人总结)

    总之,打印iBatis中的SQL语句是通过配置日志实现和调整日志级别来实现的,这为我们提供了宝贵的调试信息。根据项目需求选择合适的日志库,并进行相应的配置,就可以轻松地在日志中看到SQL执行的全过程了。

    SQL语句拼装工具

    写java程序时用来拼装sql语句时使用的小工具,在.net 4.0环境下运行。例如将 select a, b, c from abc where a like('3') 转换为: sql.append("select "); sql.append(" a, "); sql.append(" b, "); sql.append...

    SpringBoot+JPA+Freemarker 生成动态SQL

    它是ORM(对象关系映射)的一种实现,允许开发者使用Java对象来操作数据库,而不是直接编写SQL。JPA通过注解或XML配置来定义数据模型,提供了透明的持久化机制。 Freemarker是一个模板引擎,常用于生成HTML、XML或...

    lambda2sql:将Java lambdas转换为SQL语句。 构建类型安全且可读的查询

    将Java 8 lambda转换为SQL语句。 例如,以下谓词: person -&gt; person.getAge() &lt; 100&gt; 200 转换为字符串: age &lt; 100&gt; 200 允许您以类型安全的方式编写可读的查询。 有关更多示例,请参见或 。 用法 int age = ...

    sql-builder:Java语言的动态SQL构建器

    Java语言的动态SQL构建器。 例子 一些用法示例:选择 QueryBuilder query = new QueryBuilder () . select() .column( " s.name " ) .column( " count(s.impediments) AS total_impediments " ) .from() .table...

    zTree后台组装树结构java代码

    - 在Java后端,我们需要使用Java SQL API(JDBC)来连接MySQL数据库,执行SQL语句,获取数据。 - JDBC提供了连接数据库、发送SQL、处理结果集等功能,是Java开发数据库应用的基础。 3. **MySQL数据库建表**: - ...

    idea插件-mybatis-打印sql

    在开发过程中,为了调试SQL语句,通常需要查看执行的SQL日志。"MyBatis Log Plugin"就是为了满足这一需求而设计的,它能直接在IDEA中显示MyBatis执行的SQL,免去了手动开启日志或者查看控制台的繁琐步骤。 接下来,...

    MyBatis框架-动态SQL

    经常需要根据不同的条件拼接SQL语句,拼接SQL语句时还要确保不能遗漏必要的空格、标点符号等,这种编程方式给开发人员带来了非常大的不便,而MyBatis提供的SQL语句动态组装功能,恰能很好地解决这一问题。...

    java 动态生成SQL的实例讲解

    在本文中,我们将学习如何使用 Java 语言动态生成 SQL 语句的实例讲解。在这个实例中,我们将使用 Java 语言编写一个方法,该方法可以根据传入的参数动态生成 UPDATE 语句和相应的参数列表。 知识点一:Java 反射...

    基于java的企业级应用开发:动态SQL.ppt

    这样的逻辑可以通过`&lt;choose&gt;`元素来实现,确保SQL语句的正确性。 ```xml select * from t_customer where 1=1 !=null and username !=''"&gt; and username like concat('%',#{username}, '%') !=null and ...

    java多线程查询数据库

    Java中的线程池是通过`java.util.concurrent.ExecutorService`接口和其实现类(如`ThreadPoolExecutor`)来创建的。线程池可以有效地管理线程资源,避免频繁创建和销毁线程带来的开销。通过设置线程池的参数(核心...

    Java开发基于rmi的数据库中间件设计源码.zip

    Java开发基于rmi的数据库中间件设计源码。分布式对象技术课程实践:基于rmi的数据库中间件...根据表名自动获取数据类型,从而在拼装SQL语句时决定数值是否加单引号; 提供事务确认和回滚处理。 接口设计如下表所示:

    java常见错误集合以及描述

    **描述**:当执行SQL语句时出现错误时会抛出此异常。 **解决方案**: 1. **异常处理**:使用try-catch语句处理SQLException。 2. **参数验证**:对输入参数进行有效性验证。 3. **使用PreparedStatement**:使用...

    ibatis开发和学习总结借鉴.pdf

    **SQL Map的概念**:Ibatis的核心是SQL Map,它是一种映射框架,旨在将SQL查询与Java代码解耦,通过XML或注解方式配置SQL语句,实现了SQL与业务逻辑的分离,提高了代码的可维护性。 **SQL Map如何工作**:Ibatis...

    Java面试题目汇总英文Java面试题(核心知识).doc

    11. JDBC:Java访问数据库的标准接口,包括加载驱动、建立连接、执行SQL语句、处理结果集等步骤。 12. 解析XML:DOM、SAX、StaX等方式,DOM一次性加载整个文档,SAX逐行解析,StaX基于事件的流式解析。 13. 权限...

    基于Java的会议室管理系统源码 .zip

    可能涉及到SQL语句的执行、事务管理等。 5. **前端展示**:可能采用JavaServer Pages (JSP) 或者Spring MVC框架,结合HTML、CSS和JavaScript构建用户界面,实现数据的动态显示和交互。 6. **安全性**:使用Spring ...

    mybatis学习笔记LBY.pdf

    - **SQL 与 Java 代码分离**:Mybatis 支持将 SQL 语句写在 XML 文件中,与 Java 代码分离,降低了耦合度,使得维护和修改 SQL 变得更加容易。 ##### 1.3 优点 - **简化 JDBC 代码**:通过 Mybatis 的封装,可以...

Global site tag (gtag.js) - Google Analytics