Mybatis源码阅读之SqlBuilder



 

package org.apache.ibatis.jdbc;

import java.util.ArrayList;

import java.util.List;

public class SqlBuilder {

  private static final String AND = ") \nAND (";

  private static final String OR = ") \nOR (";

  private static final ThreadLocal<SQL> localSQL = new ThreadLocal<SQL>();

  public static void BEGIN() {

    RESET();

  }

  public static void RESET() {

    localSQL.set(new SQL());

  }

  public static void UPDATE(String table) {

    sql().statementType = SQL.StatementType.UPDATE;

    sql().tables.add(table);

  }

  public static void SET(String sets) {

    sql().sets.add(sets);

  }

  public static String SQL() {

    try {

      return sql().sql();

    } finally {

        RESET();

    }

  }

  public static void INSERT_INTO(String tableName) {

    sql().statementType = SQL.StatementType.INSERT;

    sql().tables.add(tableName);

  }

  public static void VALUES(String columns, String values) {

    sql().columns.add(columns);

    sql().values.add(values);

  }

  public static void SELECT(String columns) {

    sql().statementType = SQL.StatementType.SELECT;

    sql().select.add(columns);

  }

  public static void SELECT_DISTINCT(String columns) {

    sql().distinct = true;

    SELECT(columns);

  }

  public static void DELETE_FROM(String table) {

    sql().statementType = SQL.StatementType.DELETE;

    sql().tables.add(table);

  }

  public static void FROM(String table) {

    sql().tables.add(table);

  }

  public static void JOIN(String join) {

    sql().join.add(join);

  }

  public static void INNER_JOIN(String join) {

    sql().innerJoin.add(join);

  }

  public static void LEFT_OUTER_JOIN(String join) {

    sql().leftOuterJoin.add(join);

  }

  public static void RIGHT_OUTER_JOIN(String join) {

    sql().rightOuterJoin.add(join);

  }

  public static void OUTER_JOIN(String join) {

    sql().outerJoin.add(join);

  }

  public static void WHERE(String conditions) {

    sql().where.add(conditions);

    sql().lastList = sql().where;

  }

  public static void OR() {

    sql().lastList.add(OR);

  }

  public static void AND() {

    sql().lastList.add(AND);

  }

  public static void GROUP_BY(String columns) {

    sql().groupBy.add(columns);

  }

  public static void HAVING(String conditions) {

    sql().having.add(conditions);

    sql().lastList = sql().having;

  }

  public static void ORDER_BY(String columns) {

    sql().orderBy.add(columns);

  }

  private static SQL sql() {

    SQL sql = localSQL.get();

    if (sql == null) {

      RESET();

      sql = localSQL.get();

    }

    return sql;

  }

  private static class SQL {

    public enum StatementType {

        DELETE,

        INSERT,

        SELECT,

        UPDATE

    }

    

    StatementType statementType;

    List<String> sets = new ArrayList<String>();

    List<String> select = new ArrayList<String>();

    List<String> tables = new ArrayList<String>();

    List<String> join = new ArrayList<String>();

    List<String> innerJoin = new ArrayList<String>();

    List<String> outerJoin = new ArrayList<String>();

    List<String> leftOuterJoin = new ArrayList<String>();

    List<String> rightOuterJoin = new ArrayList<String>();

    List<String> where = new ArrayList<String>();

    List<String> having = new ArrayList<String>();

    List<String> groupBy = new ArrayList<String>();

    List<String> orderBy = new ArrayList<String>();

    List<String> lastList = new ArrayList<String>();

    List<String> columns = new ArrayList<String>();

    List<String> values = new ArrayList<String>();

    boolean distinct;

    private void sqlClause(StringBuilder builder, String keyword, List<String> parts, String open, String close, String conjunction) {

      if (!parts.isEmpty()) {

        if (builder.length() > 0) 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);

      }

    }

    private String selectSQL() {

      StringBuilder builder = new StringBuilder();

      if (distinct) {

        sqlClause(builder, "SELECT DISTINCT", select, "", "", ", ");

      } else {

        sqlClause(builder, "SELECT", select, "", "", ", ");

      }

      sqlClause(builder, "FROM", tables, "", "", ", ");

      sqlClause(builder, "JOIN", join, "", "", "JOIN");

      sqlClause(builder, "INNER JOIN", innerJoin, "", "", "\nINNER JOIN ");

      sqlClause(builder, "OUTER JOIN", outerJoin, "", "", "\nOUTER JOIN ");

      sqlClause(builder, "LEFT OUTER JOIN", leftOuterJoin, "", "", "\nLEFT OUTER JOIN ");

      sqlClause(builder, "RIGHT OUTER JOIN", rightOuterJoin, "", "", "\nRIGHT OUTER JOIN ");

      sqlClause(builder, "WHERE", where, "(", ")", " AND ");

      sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");

      sqlClause(builder, "HAVING", having, "(", ")", " AND ");

      sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");

      return builder.toString();

    }

    private String insertSQL() {

      StringBuilder builder = new StringBuilder();

      sqlClause(builder, "INSERT INTO", tables, "", "", "");

      sqlClause(builder, "", columns, "(", ")", ", ");

      sqlClause(builder, "VALUES", values, "(", ")", ", ");

      return builder.toString();

    }

    private String deleteSQL() {

      StringBuilder builder = new StringBuilder();

      sqlClause(builder, "DELETE FROM", tables, "", "", "");

      sqlClause(builder, "WHERE", where, "(", ")", " AND ");

      return builder.toString();

    }

    private String updateSQL() {

      StringBuilder builder = new StringBuilder();

      sqlClause(builder, "UPDATE", tables, "", "", "");

      sqlClause(builder, "SET", sets, "", "", ", ");

      sqlClause(builder, "WHERE", where, "(", ")", " AND ");

      return builder.toString();

    }

    public String sql() {

      if (statementType == null) {

        return null;

      }

      

      String answer;

      

      switch (statementType) {

      case DELETE:

        answer = deleteSQL();

        break;

          

      case INSERT:

        answer = insertSQL();

        break;

      

      case SELECT:

        answer = selectSQL();

        break;

          

      case UPDATE:

        answer = updateSQL();

        break;

          

      default:

        answer = null;

      }

      return answer;

    }

  }

}

猜你喜欢

转载自gaojingsong.iteye.com/blog/2335927