GitHub项目:jkrasnay/sqlbuilder的使用
http://www.jianshu.com/p/7f099b8cf5f0
技术选型:
在报表查询时,通常需要做可以动态添加的条件
在老项目中使用的是一种Tcondition的对象分装sql
import java.util.HashMap;
public class TCondition {
private String sql;
private Object[] paraValues;
private String orderBy;
private String groupBy;
private String having;
/**
* key为表名,value为 left join on后的内容(如何关联的)
*/
private HashMap<String,String> leftJoinMap;
/**
* count方法计数时可指定 count哪个字段,默认为count(1)
*/
private String mainId;
public TCondition() {
}
public TCondition(String sql, Object... paraValues) {
this.setSql(sql);
this.setParaValues(paraValues);
}
public static TCondition of() {
return new TCondition();
}
public static TCondition of(String sql, Object... paraValues) {
return new TCondition(sql, paraValues);
}
public String getSql() {
return sql;
}
public TCondition setSql(String sql) {
this.sql = sql;
return this;
}
public Object[] getParaValues() {
return paraValues;
}
public TCondition setParaValues(Object[] paraValues) {
this.paraValues = paraValues;
return this;
}
public String getOrderBy() {
return orderBy;
}
public TCondition setOrderBy(String orderBy) {
this.orderBy = orderBy;
return this;
}
public String getGroupBy() {
return groupBy;
}
public TCondition setGroupBy(String groupBy) {
this.groupBy = groupBy;
return this;
}
public String getHaving() {
return having;
}
public TCondition setHaving(String having) {
this.having = having;
return this;
}
public String getMainId() {
return mainId;
}
public TCondition setMainId(String mainId) {
this.mainId = mainId;
return this;
}
@Override
public String toString() {
StringBuffer result = new StringBuffer(this.getSql() + ":");
for (int i = 0; i < paraValues.length; i++) {
result.append(paraValues[i]).append(",");
}
result.append(" || ");
return result.toString();
}
public HashMap<String, String> getLeftJoinMap() {
return leftJoinMap;
}
public TCondition setLeftJoinMap(HashMap<String, String> leftJoinMap) {
this.leftJoinMap = leftJoinMap;
return this;
}
但是由于与老代码的数据库访问层紧紧的耦合在一起,无法在另外的项目中进行复用,因此,在GitHub中找到了一款类似的封装SQL查询的对象
封装的内容:
package ca.krasnay.sqlbuilder;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Tool for programmatically constructing SQL select statements. This class aims
* to simplify the task of juggling commas and SQL keywords when building SQL
* statements from scratch, but doesn't attempt to do much beyond that. Here are
* some relatively complex examples:
*
* <pre>
* String sql = new SelectBuilder()
* .column("e.id")
* .column("e.name as empname")
* .column("d.name as deptname")
* .column("e.salary")
* .from(("Employee e")
* .join("Department d on e.dept_id = d.id")
* .where("e.salary > 100000")
* .orderBy("e.salary desc")
* .toString();
* </pre>
*
* <pre>
* String sql = new SelectBuilder()
* .column("d.id")
* .column("d.name")
* .column("sum(e.salary) as total")
* .from("Department d")
* .join("Employee e on e.dept_id = d.id")
* .groupBy("d.id")
* .groupBy("d.name")
* .having("total > 1000000").toString();
* </pre>
*
* Note that the methods can be called in any order. This is handy when a base
* class wants to create a simple query but allow subclasses to augment it.
*
* It's similar to the Squiggle SQL library
* (http://code.google.com/p/squiggle-sql/), but makes fewer assumptions about
* the internal structure of the SQL statement, which I think makes for simpler,
* cleaner code. For example, in Squiggle you would write...
*
* <pre>
* select.addCriteria(new MatchCriteria(orders, "status", MatchCriteria.EQUALS, "processed"));
* </pre>
*
* With SelectBuilder, we assume you know how to write SQL expressions, so
* instead you would write...
*
* <pre>
* select.where("status = 'processed'");
* </pre>
*
* To include parameters, it's highly recommended to use the
* {@link ParameterizedPreparedStatementCreatorTest}, like this:
*
* <pre>
* String sql = new SelectBuilder("Employee e")
* .where("name like :name")
* .toString();
*
* PreparedStatement ps = new ParameterizedPreparedStatementCreator(sql)
* .setParameter("name", "Bob%")
* .createPreparedStatement(conn);
* </pre>
*
*
* @author John Krasnay <john@krasnay.ca>
*/
public class SelectBuilder extends AbstractSqlBuilder implements Cloneable, Serializable {
private static final long serialVersionUID = 1;
private boolean distinct;
private List<Object> columns = new ArrayList<Object>();
private List<String> tables = new ArrayList<String>();
private List<String> joins = new ArrayList<String>();
private List<String> leftJoins = new ArrayList<String>();
private List<String> wheres = new ArrayList<String>();
private List<String> groupBys = new ArrayList<String>();
private List<String> havings = new ArrayList<String>();
private List<SelectBuilder> unions = new ArrayList<SelectBuilder>();
private List<String> orderBys = new ArrayList<String>();
private boolean forUpdate;
private boolean noWait;
public SelectBuilder() {
}
public SelectBuilder(String table) {
tables.add(table);
}
/**
* Copy constructor. Used by {@link #clone()}.
*
* @param other
* SelectBuilder being cloned.
*/
protected SelectBuilder(SelectBuilder other) {
this.distinct = other.distinct;
this.forUpdate = other.forUpdate;
this.noWait = other.noWait;
for (Object column : other.columns) {
if (column instanceof SubSelectBuilder) {
this.columns.add(((SubSelectBuilder) column).clone());
} else {
this.columns.add(column);
}
}
this.tables.addAll(other.tables);
this.joins.addAll(other.joins);
this.leftJoins.addAll(other.leftJoins);
this.wheres.addAll(other.wheres);
this.groupBys.addAll(other.groupBys);
this.havings.addAll(other.havings);
for (SelectBuilder sb : other.unions) {
this.unions.add(sb.clone());
}
this.orderBys.addAll(other.orderBys);
}
/**
* Alias for {@link #where(String)}.
*/
public SelectBuilder and(String expr) {
return where(expr);
}
public SelectBuilder column(String name) {
columns.add(name);
return this;
}
public SelectBuilder column(SubSelectBuilder subSelect) {
columns.add(subSelect);
return this;
}
public SelectBuilder column(String name, boolean groupBy) {
columns.add(name);
if (groupBy) {
groupBys.add(name);
}
return this;
}
@Override
public SelectBuilder clone() {
return new SelectBuilder(this);
}
public SelectBuilder distinct() {
this.distinct = true;
return this;
}
public SelectBuilder forUpdate() {
forUpdate = true;
return this;
}
public SelectBuilder from(String table) {
tables.add(table);
return this;
}
public List<SelectBuilder> getUnions() {
return unions;
}
public SelectBuilder groupBy(String expr) {
groupBys.add(expr);
return this;
}
public SelectBuilder having(String expr) {
havings.add(expr);
return this;
}
public SelectBuilder join(String join) {
joins.add(join);
return this;
}
public SelectBuilder leftJoin(String join) {
leftJoins.add(join);
return this;
}
public SelectBuilder noWait() {
if (!forUpdate) {
throw new RuntimeException("noWait without forUpdate cannot be called");
}
noWait = true;
return this;
}
public SelectBuilder orderBy(String name) {
orderBys.add(name);
return this;
}
/**
* Adds an ORDER BY item with a direction indicator.
*
* @param name
* Name of the column by which to sort.
* @param ascending
* If true, specifies the direction "asc", otherwise, specifies
* the direction "desc".
*/
public SelectBuilder orderBy(String name, boolean ascending) {
if (ascending) {
orderBys.add(name + " asc");
} else {
orderBys.add(name + " desc");
}
return this;
}
@Override
public String toString() {
StringBuilder sql = new StringBuilder("select ");
if (distinct) {
sql.append("distinct ");
}
if (columns.size() == 0) {
sql.append("*");
} else {
appendList(sql, columns, "", ", ");
}
appendList(sql, tables, " from ", ", ");
appendList(sql, joins, " join ", " join ");
appendList(sql, leftJoins, " left join ", " left join ");
appendList(sql, wheres, " where ", " and ");
appendList(sql, groupBys, " group by ", ", ");
appendList(sql, havings, " having ", " and ");
appendList(sql, unions, " union ", " union ");
appendList(sql, orderBys, " order by ", ", ");
if (forUpdate) {
sql.append(" for update");
if (noWait) {
sql.append(" nowait");
}
}
return sql.toString();
}
/**
* Adds a "union" select builder. The generated SQL will union this query
* with the result of the main query. The provided builder must have the
* same columns as the parent select builder and must not use "order by" or
* "for update".
*/
public SelectBuilder union(SelectBuilder unionBuilder) {
unions.add(unionBuilder);
return this;
}
public SelectBuilder where(String expr) {
wheres.add(expr);
return this;
}
}
在后续的文章中我将介绍如何使用该组件,在报表项目中进行使 ^_^
github地址:
https://github.com/jkrasnay/sqlbuilder
博客:
http://john.krasnay.ca/2010/02/15/building-sql-in-java.html
GitHub项目:jkrasnay/sqlbuilder的使用的更多相关文章
- 利用Travis CI 让你的github项目持续构建
Travis CI 是目前新兴的开源持续集成构建项目,它与jenkins,GO的很明显的特别在于采用yaml格式,简洁清新独树一帜.目前大多数的github项目都已经移入到Travis CI的构建队列 ...
- 优秀大数据GitHub项目一览
http://blog.csdn.net/yaoxtao/article/details/50540485 优秀大数据GitHub项目一览 VMware CEO Pat Gelsinger曾说: 数据 ...
- 用tortoiseGit管理GitHub项目代码(完整教程)
一.为什么要写这篇博客呢,因为在一开始用tortoiseGit来管理项目的时候,在百度上找了很多教程,但是感觉说的都不是很全,有些东西以及操作没写清楚,所以想写一片比较完整用tortoiseGit管理 ...
- Github项目推荐-图神经网络(GNN)相关资源大列表
文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 转自 | AI研习社 作者|Zonghan Wu 这是一个与图神经网络相关的资源集合.相关资源浏览下方 ...
- Eclipse安装git插件以及关联导入GitHub项目
一.Eclipse配置git 1.查看自己eclipse的版本 打开eclipse 导航: help->AboutEclipse 如图: 2.检查Eclipse中是否已安装Git插件 菜单栏He ...
- Keras RetinaNet github项目
https://github.com/fizyr/keras-retinanet 根据此网站的方法,利用Pascal VOC 2007数据集开始训练,出现error: D:\JupyterWorkSp ...
- Keras RetinaNet github项目安装
在存储库目录/keras-retinanet/中,执行pip install . --user 后,出现错误: D:\>cd D:\JupyterWorkSpace\keras-retinane ...
- github项目
一.github项目地址: https://github.com/fairy1231/gitLearning/tree/master 二.github的重要性: Git 是一个快速.可扩展的分布式版本 ...
- 【全网最全的博客美化系列教程】01.添加Github项目链接
全网最全的博客美化系列教程相关文章目录 [全网最全的博客美化系列教程]01.添加Github项目链接 [全网最全的博客美化系列教程]02.添加QQ交谈链接 [全网最全的博客美化系列教程]03.给博客添 ...
随机推荐
- Codeforces 348B:Apple Tree(DFS+LCM+思维)
http://codeforces.com/contest/348/problem/B 题意:给一棵树,每个叶子结点有w[i]个苹果,每个子树的苹果数量为该子树所有叶子结点苹果数量之和,要使得每个结点 ...
- django基础知识之POST属性:
POST属性 QueryDict类型的对象 包含post请求方式的所有参数 与form表单中的控件对应 问:表单中哪些控件会被提交? 答:控件要有name属性,则name属性的值为键,value属性的 ...
- 2050编程赛 冰水挑战 HDU 6495
题目地址:https://vjudge.net/problem/HDU-6495 思路:我们需要维护的是挑战了n个之后剩余体力值,剩余体力值越大越好dp[N(i)][N(j)],第一个维度,记录当前是 ...
- C++学习书籍推荐《C++ Primer 第五版 (英文)》下载
百度云及其他网盘下载地址:点我 编辑推荐 <C++ Primer(英文版)(第5版)>是全球最畅销的C++图书.这本久负盛名的C++经典教程,时隔八年之久,终迎来的重大升级.除令全球无数程 ...
- 扫描线——POJ1151
平面上有若干个矩形,求矩形相互覆盖的面积.为方便起见,矩形的边均平行于坐标轴. 我们根据容斥原理,矩形相互覆盖的面积即为所有矩形的面积和减去所有矩形所覆盖的面积即可. 而现在问题是如何求得所有矩形所覆 ...
- Linux 系统的基本操作及工具的使用
基本操作命令如:useradd.userdel.passwd.su 添加用户.删除用户.修改密码.切换用户 ls.ll.cd.cp.mv.chmod ps.kil.man mkdir.touch.ta ...
- LeetCode第2题
// 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.//// 如果,我们将这两个数相加起来,则会返回一个新的链表 ...
- 【css系列】六种实现元素水平居中方法
一.前言 居中效果在CSS中很是普通的效果,平时大家所看到的居中效果主要分为三大类:水平居中.垂直居中和水平垂直居中.而其中水平居中相对于后两者来说要简单得多.使用了css3的flexbox的属性轻松 ...
- C#编程之自动实现的属性
在 C# 3.0 及更高版本,当属性访问器中不需要任何其他逻辑时,自动实现的属性会使属性声明更加简洁.它们还允许客户端代码创建对象.当你声明以下示例中所示的属性时,编译器将创建仅可以通过该属性的 ge ...
- 从国际象棋与象棋的走法差异,再趣说IT人提升能力和增收方式
之前我写过篇博文,用象棋的思维趣说IT人的职业发展和钱途,发现象棋中的一些思维能应用到我们程序员平时的职业发展中. 当从大学毕业的程序员干个五六年以后,也达到了高级开发的水平,工作环境应该能摆脱动荡, ...