http://www.jianshu.com/p/7f099b8cf5f0html
在報表查詢時,一般須要作能夠動態添加的條件java
在老項目中使用的是一種Tcondition的對象分裝sqlgit
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查詢的對象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; } } 在後續的文章中我將介紹如何使用該組件,在報表項目中進行使 ^_^
https://github.com/jkrasnay/sqlbuilder數據庫
http://john.krasnay.ca/2010/02/15/building-sql-in-java.htmlexpress