Package org.fto.jthink.jdbc

Source Code of org.fto.jthink.jdbc.SQLBuilder

/*
* SQLBuilder.java  2005-7-15
*
* 版权所有: 自由思考组织(FTO)软件团队 2000-2005, 保留所有权利.
* 这个软件是自由思考组织(FTO)软件团队开发的,如果要使用这个软件,请首先阅读并接受许可协议。
*
* Copyright 2000-2005 FTO Software Team, Inc. All Rights Reserved.
* This software is the proprietary information of FTO Software Team, Inc.
* Use is subject to license terms.
*
* FTO站点:http://www.free-think.org
*/
package org.fto.jthink.jdbc;

import java.util.Iterator;
import java.util.Map;

import org.fto.jthink.exception.JThinkRuntimeException;
import org.fto.jthink.lang.ObjectBuffered;
import org.fto.jthink.lang.StringBuffered;

/**
* 构建SQL。 此类型已经提供了构建常用SQL语句的方法,但如果要构建复杂SQL,
* 建议扩展此类型,然后覆盖在此类型中没有实现的方法:constructSQL()和constructSQLForSelect()。
* 如果扩展了此类型,相应的也需要实现SQLBuilderFactory工厂来创建SQLBuilder类型的实例。
*
* <p><pre><b>
* 历史更新记录:</b>
* 2005-07-15  创建此类型
* 2009-07-29  优化SQL构建
* </pre></p>
*
* </pre>
*   想法:
*      
* </pre>
*
* @author   wenjian
* @version  1.0
* @since    JThink 1.0
*
*/
public class SQLBuilder {

  /**
   * 根据sqlParameter中描述的信息构建SQL声明, 此方法需要在子类中实现。
   * 可以用此方法来构建与数据库特性相关的SQL语句,充分利用了数据库的特性,
   * 且又能非常方便的在数据库之间移植应用
   *
   * @param type           类别, 根据不同的类别构建SQL
   * @param sqlParameters   构建SQL需要的数据信息
   *
   * @return  包含SQL串和值的SQL声明
   */
  public SQL constructSQL(String type, Map sqlParameters){
    throw new java.lang.UnsupportedOperationException(
                "Method constructSQL() not yet implemented.");

  }
 
 
  /**
   * 构建Insert操作的SQL声明
   *
   * @param tableName  表名
   * @param columns    将要创建的记录的列和列值
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForInsert(String tableName, Map columns){
   
    if(tableName==null){
      throw new IllegalArgumentException(
          "The name of an table cannot be null.");
    }
    if(columns.size()==0){
      throw new IllegalArgumentException(
          "The value of an columns cannot be empty.");
    }
    int size = columns.size();
    StringBuffered names = new StringBuffered(size*2);
    StringBuffered valueStatement = new StringBuffered(size);
    ObjectBuffered values  = new ObjectBuffered(size);
    Iterator columnsIT = columns.entrySet().iterator();
   
    for(int i=0;i<size;i++){
    //while(columnsIT.hasNext()){
      Map.Entry column = (Map.Entry)columnsIT.next();
      Object value = column.getValue();
      if(value!=null){
        if(values.size()==0){
          names.append(column.getKey());
          valueStatement.append("?");
        }else{
          names.append(",").append(column.getKey());
          valueStatement.append(",?");
        }
        values.append(value);
      };     
    }
    StringBuffered sql = new StringBuffered(5+names.size()+valueStatement.size())
      .append("INSERT INTO ")
      .append(tableName)
      .append(" (").append(names)
      .append(") VALUES (").append(valueStatement)
      .append(") ");
    return new SQL(SQL.UPDATE, sql, values);
  }  
 
  /**
   * 构建Insert操作的SQL声明
   *
   * @param data 数据对象,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForInsert(DataObject data){
    return constructSQLForInsert(data.getTableName(), data.getValues());
  }
 
  /**
   * 构建更新记录操作的SQL声明
   *
   * @param tableName  表名
   * @param columns    包含有列和列值的Map
   * @param condition  条件
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForUpdate(String tableName, Map columns, Condition condition){
    if(tableName==null){
      throw new IllegalArgumentException(
          "The name of an table cannot be null.");
    }
    if(columns.size()==0){
      throw new IllegalArgumentException(
          "The value of an columns cannot be empty.");
    }
    int columnsCapacity = columns.size();

    ObjectBuffered values  = new ObjectBuffered(columnsCapacity+1);
    StringBuffered sql = new StringBuffered(columnsCapacity+columnsCapacity+columnsCapacity+4)
    .append("UPDATE ")
    .append(tableName)
    .append(" SET ");

    /* 处理被更新的字段 */
    Iterator columnsIT = columns.entrySet().iterator();
    //while(columnsIT.hasNext()){
    for(int i=0;i<columnsCapacity;i++){
      Map.Entry column = (Map.Entry)columnsIT.next();
      Object value = column.getValue();
      int valuesSize = values.size();
      if(value==null){
        sql.append(valuesSize>0?",":"").append(column.getKey()).append("=NULL");
      }else{
        sql.append(valuesSize>0?",":"").append(column.getKey()).append("=?");
        values.append(value);
      }
    }
    /* 处理条件 */
    if(condition!=null && condition.size()!=0){
      sql.append(" WHERE ").append(condition.getConditionStatement());
      values.append(condition.getValueBuffered());
    }
    return new SQL(SQL.UPDATE, sql, values);
 

  /**
   * 构建更新记录操作的SQL声明
   *
   * @param data 数据对象,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForUpdate(DataObject data){
    Condition condition = new Condition();
    Map pkeys = data.getPrimaryKeys();
    int size = pkeys.size();
    Iterator pks = pkeys.entrySet().iterator();
    //while(pks.hasNext()){
    for(int i=0;i<size;i++){
      Map.Entry pk = (Map.Entry)pks.next();
      Object value = pk.getValue();
      if(value==null){
        throw new IllegalArgumentException(
          "The primary key value cannot be null.");
      }
      condition.add(new ConditionItem(pk.getKey().toString(), "=", (Object)value));
    }
     
    if(condition.size()==0){
      throw new JThinkRuntimeException("The condition size cannot be 0");
    }
    return constructSQLForUpdate(data.getTableName(), data.getValues(), condition);
  }
 
  /**
   * 构建删除记录操作的SQL声明
   *
   * @param tableName 表名
   * @param condition 条件
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForDelete(String tableName, Condition condition){
    if(tableName==null){
      throw new IllegalArgumentException(
          "The name of an table cannot be null.");
    }
    StringBuffered sqlstr = new StringBuffered(4)
      .append("DELETE FROM ")
      .append(tableName);
    ObjectBuffered values = null;
    if (condition != null && condition.size()>0) {
      sqlstr.append(" WHERE ").append(condition.getConditionStatement());
      values = condition.getValueBuffered();
    }
    return new SQL(SQL.UPDATE, sqlstr, values);
  }
 
  /**
   * 构建删除记录操作的SQL声明
   *
   * @param data 数据对象,只有采用DataObjectResultMaker时此参数才有意义
   *
   * @return 包含SQL串和值的SQL声明
   */
  public SQL constructSQLForDelete(DataObject data){
    Condition condition = new Condition();
    Map pkeys = data.getPrimaryKeys();
    int size = pkeys.size();   
    Iterator pks = pkeys.entrySet().iterator();
    //while(pks.hasNext()){
    for(int i=0; i<size; i++){
      Map.Entry pk = (Map.Entry)pks.next();
      Object value = pk.getValue();
      if(value==null){
        throw new IllegalArgumentException(
          "The primary key value cannot be null.");
      }
      condition.add(new ConditionItem(pk.getKey().toString(), "=", (Object)value));
    }
     
    if(condition.size()==0){
      throw new JThinkRuntimeException("The condition size cannot be 0");
    }
   
    return constructSQLForDelete(data.getTableName(), condition);
  }
 
  /**
   * 构建查询记录操作的SQL。
   *
   * @param tableName          表名称,确定对那个表进行操作
   * @param distinct           在SELECT中是否加上DISTINCT子句
   * @param columns            列名,指定须要返回的数据字段列
   * @param condition          条件
   * @param groupby            分组字段
   * @param orderby            排序字段
   *
   * @return 包含SQL串和值的SQL声明
   */

  public SQL constructSQLForSelect(String tableName,
                                              boolean distinct,
                                              Column[] columns,
                                              Condition condition,
                                              String groupby, String orderby
                                              ){
    if(tableName==null){
      throw new IllegalArgumentException(
          "The name of an table cannot be null.");
    }
   
    StringBuffered sqlStr = new StringBuffered(11)
    .append("SELECT ");
    ObjectBuffered values = null;

    /* 生成DISTINCT串 */
    if (distinct) {
      sqlStr.append(" DISTINCT ");
    }
    /* 生成返回列的串 */
    if (columns != null && columns.length != 0) {
      SQL columnSQL = constructSelectedColumn(columns);
      sqlStr.append(columnSQL.getSQLStatement());
      values = columnSQL.getValueBuffered();
    }else{
      sqlStr.append("*");
    }
   
    /* 生成FROM子串, 如果tableName为空,将不构建FROM子句 */
    if (tableName != null && tableName.length() != 0) {
      sqlStr.append(" FROM ").append(tableName);
    }
   
    /* 生成查询条件串 */
    if (condition != null && condition.size() != 0) {
      sqlStr.append(" WHERE ")
            .append(condition.getConditionStatement());
      if(values==null){
        values = condition.getValueBuffered();
      }else{
        values.append(condition.getValueBuffered());
      }
    }
    /* 生成GROUP BY串 */
    if (groupby != null && groupby.length() != 0) {
      sqlStr.append(" GROUP BY ").append(groupby);
    }
    /* 生成ORDER BY串 */
    if (orderby != null && orderby.length() != 0) {
      sqlStr.append(" ORDER BY ").append(orderby);
    }
    return new SQL(SQL.SELECT, sqlStr, values);
  }

 
  /**
   * 构建查询记录操作的SQL。
   *
   * @param tableName          表名称,确定对那个表进行操作
   * @param columns           列名,指定须要返回的数据字段列
   * @param condition          条件
   *
   * @return        包含SQL串和值的SQL声明
   *
   */ 
  public SQL constructSQLForSelect(String tableName,
                                            Column[] columns,
                                            Condition condition){
    return constructSQLForSelect(tableName, false, columns, condition, null, null);
  }

 
  /**
   * 构建查询记录操作的SQL。此方法需要在子类中实现
   *
   * @param tableName          表名称,确定对那个表进行操作
   * @param distinct           在SELECT中是否加上DISTINCT子句
   * @param columns            列名,指定须要返回的数据字段列
   * @param condition          条件
   * @param groupby            分组字段
   * @param orderby            排序字段
   * @param startIndex         开始行记录索引, 此值不能小于0
   * @param len                返回记录的行数, 此值不能小于0
   *
   * @return   包含SQL串和值的SQL声明
   */
  public SQL constructSQLForSelect(String tableName,
                                              boolean distinct,
                                              Column[] columns,
                                              Condition condition,
                                              String groupby, String orderby,
                                              int startIndex, int len
                                              ){
    throw new java.lang.UnsupportedOperationException(
    "Method constructSQLForSelect() not yet implemented.");
  }
 
 
 
  /**
   * 构建统计记录数量的SQL。
   *
   * @param tableName      表名称,确定对那个表进行操作
   * @param fieldName      字段列名,可以是“*”字符, 也可以是列名
   * @param attrName       属性名,通过此属性名称得到统计数据值
   * @param condition      条件
   *
   * @return               包含SQL串和值的SQL声明
   */
  public SQL constructSQLForCount(
      String tableName, String fieldName, String attrName,Condition condition) {
    fieldName = fieldName==null?"*":fieldName;

    StringBuffered sqlstr = new StringBuffered(8)
      .append("SELECT COUNT(").append(fieldName).append(") AS ").append(attrName).append(" FROM ").append(tableName);
    ObjectBuffered values = null;
    if (condition != null && condition.size() != 0) {
      sqlstr.append(" WHERE ").append(condition.getConditionStatement());
      values = condition.getValueBuffered();
    }
    return new SQL(SQL.SELECT, sqlstr, values);
  }

 
  /**
   * 构建被选择的列
   *
   * @param columns 列对象数组 
   *
   * @return  描述列的SQL子语句
   */
  protected SQL constructSelectedColumn(Column[] columns){
    int len = columns.length;
    StringBuffered columnsStr = new StringBuffered(len);
    ObjectBuffered valuesLT = new ObjectBuffered(len+1);
    for(int i=0;i<len;i++){
      Column column = columns[i];
      columnsStr.append(i==0?"":",");
      if(column.isSimpleColumn()){
        columnsStr.append(column.getColumnName());
      }else{
        SQL columnSQL = column.getColumn();
        if(columnSQL.isStringBufferedType()){
          columnsStr.append(columnSQL.getSQLStatement());
        }else{
          columnsStr.append(columnSQL.getSQLString());
        }
       
        ObjectBuffered values = columnSQL.getValueBuffered();
        if(values!=null){
          valuesLT.append(values);
        }
      }
    }
    return new SQL(SQL.UNDEFINED, columnsStr, valuesLT);
  }

}
TOP

Related Classes of org.fto.jthink.jdbc.SQLBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.