上次就比较简单的讲了使用,这块也比较简单,因为封装得不是很复杂,首先我们从 select 作为入口来看看,这个具体的实现,1 2 3 4 5 String selectSql = new SQL () {{ SELECT("id" , "name" ); FROM("student" ); WHERE("id = #{id}" ); }}.toString();
SELECT
方法的实现,1 2 3 4 5 public T SELECT (String... columns) { sql().statementType = SQLStatement.StatementType.SELECT; sql().select.addAll(Arrays.asList(columns)); return getSelf(); }
statementType是个枚举1 2 3 public enum StatementType { DELETE, INSERT, SELECT, UPDATE }
那这个就是个 select 语句,然后会把参数转成 list 添加到 select
变量里, 然后是 from 语句,这个大概也能猜到就是设置下表名,1 2 3 4 public T FROM (String table) { sql().tables.add(table); return getSelf(); }
往 tables 里添加了 table,这个 tables 是什么呢 这里也可以看下所有的变量,1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 StatementType statementType; List<String> sets = new ArrayList <>(); List<String> select = new ArrayList <>(); List<String> tables = new ArrayList <>(); List<String> join = new ArrayList <>(); List<String> innerJoin = new ArrayList <>(); List<String> outerJoin = new ArrayList <>(); List<String> leftOuterJoin = new ArrayList <>(); List<String> rightOuterJoin = new ArrayList <>(); List<String> where = new ArrayList <>(); List<String> having = new ArrayList <>(); List<String> groupBy = new ArrayList <>(); List<String> orderBy = new ArrayList <>(); List<String> lastList = new ArrayList <>(); List<String> columns = new ArrayList <>(); List<List<String>> valuesList = new ArrayList <>();
可以看到是一堆 List 先暂存这些sql 片段,然后再拼装成 sql 语句, 因为它重写了 toString 方法1 2 3 4 5 6 @Override public String toString () { StringBuilder sb = new StringBuilder (); sql().sql(sb); return sb.toString(); }
调用的 sql 方法是1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public String sql (Appendable a) { SafeAppendable builder = new SafeAppendable (a); if (statementType == null ) { return null ; } String answer; switch (statementType) { case DELETE: answer = deleteSQL(builder); break ; case INSERT: answer = insertSQL(builder); break ; case SELECT: answer = selectSQL(builder); break ; case UPDATE: answer = updateSQL(builder); break ; default : answer = null ; } return answer; }
根据上面的 statementType判断是个什么 sql,我们这个是 selectSQL 就走的 SELECT 这个分支1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private String selectSQL (SafeAppendable builder) { if (distinct) { sqlClause(builder, "SELECT DISTINCT" , select, "" , "" , ", " ); } else { sqlClause(builder, "SELECT" , select, "" , "" , ", " ); } sqlClause(builder, "FROM" , tables, "" , "" , ", " ); joins(builder); sqlClause(builder, "WHERE" , where, "(" , ")" , " AND " ); sqlClause(builder, "GROUP BY" , groupBy, "" , "" , ", " ); sqlClause(builder, "HAVING" , having, "(" , ")" , " AND " ); sqlClause(builder, "ORDER BY" , orderBy, "" , "" , ", " ); limitingRowsStrategy.appendClause(builder, offset, limit); return builder.toString(); }
上面的可以看出来就是按我们常规的 sql 理解顺序来处理 就是select ... from ... where ...
这样子 再看下 sqlClause 的代码1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 private void sqlClause (SafeAppendable builder, String keyword, List<String> parts, String open, String close, String conjunction) { if (!parts.isEmpty()) { if (!builder.isEmpty()) { builder.append("\n" ); } builder.append(keyword); builder.append(" " ); builder.append(open); String last = "________" ; for (int i = 0 , n = parts.size(); i < n; i++) { String part = parts.get(i); if (i > 0 && !part.equals(AND) && !part.equals(OR) && !last.equals(AND) && !last.equals(OR)) { builder.append(conjunction); } builder.append(part); last = part; } builder.append(close); } }
这里的拼接方式还需要判断 AND 和 OR 的判断逻辑,其他就没什么特别的了,只是where 语句中的 lastList 不知道是干嘛的,好像只有添加跟赋值的操作,有知道的大神也可以评论指导下