Package cn.org.zeronote.orm.dao.parser

Source Code of cn.org.zeronote.orm.dao.parser.SqlUpdGenerator

/**
*
*/
package cn.org.zeronote.orm.dao.parser;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.org.zeronote.orm.DataAccessException;
import cn.org.zeronote.orm.ORMAutoAssemble;
import cn.org.zeronote.orm.ORMCanUpdate;
import cn.org.zeronote.orm.ORMColumn;
import cn.org.zeronote.orm.ORMHash;
import cn.org.zeronote.orm.ORMTable;

/**
* UPDATE sql 语句生成器
* @author <a href='mailto:lizheng8318@gmail.com'>lizheng</a>
*
*/
public class SqlUpdGenerator implements Generator {
 
  private static Logger logger = LoggerFactory.getLogger(SqlUpdGenerator.class);
 
  /** orm fields cache*/
  private transient static Map<Class<?>, Field> updateCheckCache = new HashMap<Class<?>, Field>();
  private transient byte[] synObj = new byte[0];
 
  private Object pojo;
 
  private String sql;
  private Object[] args;
 
  private boolean usePhysicalPk;
 
  /**
   *
   */
  public SqlUpdGenerator() {
  }
 
  /**
   *
   * @param pojoClazz
   */
  public SqlUpdGenerator(Object pojo, boolean usePhysicalPk) throws DataAccessException{
    this.pojo = pojo;
    this.usePhysicalPk = usePhysicalPk;
    if (!updateCheckCache.containsKey(pojo.getClass())) {
      synchronized (synObj) {
        if (!updateCheckCache.containsKey(pojo.getClass())) {
          boolean add = false;
          Field[] fields = pojo.getClass().getDeclaredFields();
          for (Field field : fields) {
            ORMCanUpdate ocu = field.getAnnotation(ORMCanUpdate.class);
            if (ocu != null) {
              field.setAccessible(true);
              updateCheckCache.put(pojo.getClass(), field);
              add = true;
              break;
            }
          }
          if (!add) {
            updateCheckCache.put(pojo.getClass(), null);
          }
        }
      }
    }
    Field field = updateCheckCache.get(pojo.getClass());
    if (field != null) {
      field.setAccessible(true);
      try {
        boolean c = field.getBoolean(pojo);
        if (!c) {
          logger.debug("POJO Do not allow update");
          throw new DataAccessException("POJO Do not allow update");
        }
      } catch (IllegalArgumentException e) {
        throw new DataAccessException("read can update field fail, field:" + field.getName(), e);
      } catch (IllegalAccessException e) {
        throw new DataAccessException("read can update field fail, field:" + field.getName(), e);
      }
    }
   
  }

  /**
   * 生成主键依赖的
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws ParseException
   */
  private void generate() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ParseException {
   
    Class<?> pojoClazz = pojo.getClass();
    // TABLE
    ORMAutoAssemble ormaa = pojoClazz.getAnnotation(ORMAutoAssemble.class);
    if (ormaa == null) {
      throw new IllegalAccessException("It not a ORMAutoAssemble Class!");
    }
   
    ORMTable ormTable = pojoClazz.getAnnotation(ORMTable.class);
    if (ormTable == null) {
      throw new IllegalAccessException("It not a ORMTable Class!");
    }
    ORMHash ormHashTable = pojoClazz.getAnnotation(ORMHash.class);
   
   
    String tableName = ormHashTable == null ? ormTable.tableName() : DBUtils.getInstance().getHashTableName(ormHashTable, ormTable, pojo);
    generate(tableName);
  }
 
  /**
   * 生成sql
   * @param tableName
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   * @throws ParseException
   */
  private void generate(String tableName) throws IllegalArgumentException, IllegalAccessException, ParseException {

    Class<?> pojoClazz = pojo.getClass();
    StringBuilder upd = new StringBuilder("UPDATE ");
    List<Object> params = new ArrayList<Object>();
    // TABLE
    upd.append(tableName).append(" ");
    // UPDATE
    upd.append("SET ");
    Field[] fields = pojoClazz.getDeclaredFields();
    List<String> pks = null;
    if (usePhysicalPk) {
      pks = new ArrayList<String>();
      for (Field f : fields) {
        ORMColumn ormc = f.getAnnotation(ORMColumn.class);
        if (ormc != null && ormc.physicalPkFld()) {
          pks.add(ormc.value());
        }
      }
    } else {
      pks = new ArrayList<String>();
      for (Field f : fields) {
        ORMColumn ormc = f.getAnnotation(ORMColumn.class);
        if (ormc != null && ormc.LogicPkFld()) {
          pks.add(ormc.value());
        }
      }
    }
   
    for (Field field : fields) {
      field.setAccessible(true);
      ORMColumn ormc = field.getAnnotation(ORMColumn.class);
      // 主键不允许修改
      if (ormc != null && !pks.contains(ormc.value())) {
        Object val = field.get(pojo);
        if (val != null) {
          // 不是空才去设置
          if (ormc.append()) {
            upd.append(ormc.value()).append("=").append(ormc.value()).append("||?, ")// XXX 只适合Oracle,需要方言支持
          } else {
            upd.append(ormc.value()).append("=?, ");
          }
          params.add(val);
        } else if (!"null".equalsIgnoreCase(ormc.defaultValue())) {
          // 是null,但是有默认值,则设置
          switch (ormc.defaultValueScope()) {
          case ALL:
          case UPDATE:
              if (ormc.append()) {
                          upd.append(ormc.value()).append("=").append(ormc.value()).append("||?, ")// XXX 只适合Oracle,需要方言支持
                      } else {
                          upd.append(ormc.value()).append("=?, ");
                      }
             
                Object value = ORMColumn.DEFAULT_DATE.equals(ormc.defaultValue()) ? new Date() : ValueUtils.conversionType(ormc.defaultValue(), field.getType());
                        params.add(value);
            break;
          default:
            break;
          }
        }
      }
    }
    upd.replace(upd.length() - 2, upd.length(), " ");
    // WHERE
    if (pks != null && pks.size() > 0) {
      upd.append("WHERE ");
      for (String pk : pks) {
        for (Field field : fields) {
          field.setAccessible(true);
          ORMColumn ormc = field.getAnnotation(ORMColumn.class);
          if (ormc != null && ormc.value().equalsIgnoreCase(pk)) {
            // 是主键,作为条件
            upd.append(pk).append("=? AND ");
            Object val = field.get(pojo);
            params.add(val);
          }
        }
      }
      upd.replace(upd.length() - 4, upd.length(), " ");
    }
    this.sql = upd.toString();
   
    // params
    args = params.toArray();
  }
 
  /**
   * @return the sql
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws ParseException
   */
  public String getSql() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ParseException {
    if (sql == null) {
      generate();
    }
    return sql;
  }

  /**
   * @return the args
   * @throws IllegalAccessException
   * @throws IllegalArgumentException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws ParseException
   */
  public Object[] getArgs() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ParseException {
    if (args == null) {
      generate();
    }
    return args;
  }

}
TOP

Related Classes of cn.org.zeronote.orm.dao.parser.SqlUpdGenerator

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.