Пример #1
0
 public void addComment(Dao dao, Entity<?> en, String commentTable, String commentColumn) {
   if (!en.hasTableComment() && !en.hasColumnComment()) {
     return;
   }
   List<Sql> sqls = new ArrayList<Sql>();
   // 表注释
   if (en.hasTableComment()) {
     Sql tableCommentSQL =
         Sqls.create(Strings.isBlank(commentTable) ? DEFAULT_COMMENT_TABLE : commentTable);
     tableCommentSQL
         .vars()
         .set("table", en.getTableName())
         .set("tableComment", en.getTableComment());
     sqls.add(tableCommentSQL);
   }
   // 字段注释
   if (en.hasColumnComment()) {
     for (MappingField mf : en.getMappingFields()) {
       if (mf.hasColumnComment()) {
         Sql columnCommentSQL =
             Sqls.create(Strings.isBlank(commentColumn) ? DEFAULT_COMMENT_COLUMN : commentColumn);
         columnCommentSQL
             .vars()
             .set("table", en.getTableName())
             .set("column", mf.getColumnName())
             .set("columnComment", mf.getColumnComment());
         sqls.add(columnCommentSQL);
       }
     }
   }
   // 执行创建语句
   dao.execute(sqls.toArray(new Sql[sqls.size()]));
 }
Пример #2
0
 protected List<Sql> createIndexs(Entity<?> en) {
   List<Sql> sqls = new ArrayList<Sql>();
   StringBuilder sb = new StringBuilder();
   List<EntityIndex> indexs = en.getIndexes();
   for (EntityIndex index : indexs) {
     sb.setLength(0);
     if (index.isUnique()) sb.append("Create UNIQUE Index ");
     else sb.append("Create Index ");
     if (index.getName().contains("$"))
       sb.append(TableName.render(new CharSegment(index.getName())));
     else sb.append(index.getName());
     sb.append(" ON ").append(en.getTableName()).append("(");
     for (EntityField field : index.getFields()) {
       if (field instanceof MappingField) {
         MappingField mf = (MappingField) field;
         sb.append(mf.getColumnNameInSql()).append(',');
       } else {
         throw Lang.makeThrow(
             DaoException.class,
             "%s %s is NOT a mapping field, can't use as index field!!",
             en.getClass(),
             field.getName());
       }
     }
     sb.setCharAt(sb.length() - 1, ')');
     sqls.add(Sqls.create(sb.toString()));
   }
   return sqls;
 }
Пример #3
0
  public String evalFieldType(MappingField mf) {
    if (mf.getCustomDbType() != null) return mf.getCustomDbType();
    switch (mf.getColumnType()) {
      case INT:
        // 用户自定义了宽度
        if (mf.getWidth() > 0) return "NUMERIC(" + mf.getWidth() + ")";
        // 用数据库的默认宽度
        return "INT";

      case FLOAT:
        // 用户自定义了精度
        if (mf.getWidth() > 0 && mf.getPrecision() > 0) {
          return "NUMERIC(" + mf.getWidth() + "," + mf.getPrecision() + ")";
        }
        // 用默认精度
        if (mf.getTypeMirror().isDouble()) return "NUMERIC(15,10)";
        return "NUMERIC";

      case BINARY:
        return "BYTEA";

      case DATETIME:
        return "TIMESTAMP";
      default:
        break;
    }
    return super.evalFieldType(mf);
  }
Пример #4
0
 public ValueAdaptor getAdaptor(MappingField ef) {
   Mirror<?> mirror = ef.getTypeMirror();
   // 为数字型枚举的特殊判断
   if (mirror.isEnum() && ColType.INT == ef.getColumnType()) return Jdbcs.Adaptor.asEnumInt;
   // 用普通逻辑返回适配器
   return Jdbcs.getAdaptor(mirror);
 }
Пример #5
0
 @Test
 public void test_override_field() {
   Entity<?> en = en(Pet2.class);
   MappingField ef = en.getField("nickName");
   assertEquals("alias", ef.getColumnName());
   assertEquals(1, en.cloneBeforeInsertMacroes().size());
 }
Пример #6
0
 public String makePksName(Entity<?> en) {
   String name = en.getType().getAnnotation(PK.class).name();
   if (Strings.isBlank(name)) {
     StringBuilder sb = new StringBuilder();
     for (MappingField mf : en.getPks()) {
       sb.append("_").append(mf.getColumnName());
     }
     sb.setLength(sb.length() - 1);
     return sb.toString();
   }
   return name;
 }
Пример #7
0
  /**
   * 执行一个特殊的Chain(事实上普通Chain也能执行,但不建议使用)
   *
   * @see org.nutz.dao.Chain#addSpecial(String, Object)
   */
  @SuppressWarnings({"rawtypes"})
  public static void insertBySpecialChain(Dao dao, Entity en, String tableName, Chain chain) {
    if (en != null) tableName = en.getTableName();
    if (tableName == null) throw Lang.makeThrow(DaoException.class, "tableName and en is NULL !!");
    final StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append(" (");
    StringBuilder _value_places = new StringBuilder(" VALUES(");
    final List<Object> values = new ArrayList<Object>();
    final List<ValueAdaptor> adaptors = new ArrayList<ValueAdaptor>();
    Chain head = chain.head();
    while (head != null) {
      String colName = head.name();
      MappingField mf = null;
      if (en != null) {
        mf = en.getField(colName);
        if (mf != null) colName = mf.getColumnName();
      }
      sql.append(colName);

      if (head.special()) {
        _value_places.append(head.value());
      } else {
        if (en != null) mf = en.getField(head.name());
        _value_places.append("?");
        values.add(head.value());
        ValueAdaptor adaptor = Jdbcs.getAdaptorBy(head.value());
        if (mf != null && mf.getAdaptor() != null) adaptor = mf.getAdaptor();
        adaptors.add(adaptor);
      }

      head = head.next();
      if (head != null) {
        sql.append(", ");
        _value_places.append(", ");
      }
    }
    sql.append(")");
    _value_places.append(")");
    sql.append(_value_places);
    if (log.isDebugEnabled()) log.debug(sql);
    dao.run(
        new ConnCallback() {
          public void invoke(Connection conn) throws Exception {
            PreparedStatement ps = conn.prepareStatement(sql.toString());
            try {
              for (int i = 0; i < values.size(); i++) adaptors.get(i).set(ps, values.get(i), i + 1);
              ps.execute();
            } finally {
              Daos.safeClose(ps);
            }
          }
        });
  }
Пример #8
0
 public Chain updateBy(Entity<?> entity) {
   if (null != entity) {
     Entry current = head;
     while (current != null) {
       MappingField ef = entity.getField(current.name);
       if (null != ef) {
         current.name = ef.getColumnName();
       }
       current = current.next;
     }
   }
   return head();
 }
Пример #9
0
  @Override
  protected String evalFieldType(MappingField mf) {
    if (mf.getCustomDbType() != null) return mf.getCustomDbType();
    switch (mf.getColumnType()) {
      case BOOLEAN:
        return "SMALLINT";
      case INT:
        // 用户自定义了宽度
        // if (mf.getWidth() > 0)
        // return "decimal(" + mf.getWidth() + ")";
        // 用数据库的默认宽度
        return "INTEGER";

      case FLOAT:
        // 用户自定义了精度
        if (mf.getWidth() > 0 && mf.getPrecision() > 0) {
          return "decimal(" + mf.getWidth() + "," + mf.getPrecision() + ")";
        }
        // 用默认精度
        if (mf.getTypeMirror().isDouble()) return "decimal(15,10)";
        return "FLOAT";
      default:
        break;
    }
    return super.evalFieldType(mf);
  }
Пример #10
0
  // TODO not tested!!
  public boolean createEntity(Dao dao, Entity<?> en) {
    StringBuilder sb = new StringBuilder("CREATE TABLE " + en.getTableName() + "(");
    // 创建字段
    for (MappingField mf : en.getMappingFields()) {
      sb.append('\n').append(mf.getColumnName());
      sb.append(' ').append(evalFieldType(mf));
      // 非主键的 @Name,应该加入唯一性约束
      if (mf.isName() && en.getPkType() != PkType.NAME) {
        sb.append(" UNIQUE NOT NULL");
      }
      // 普通字段
      else {
        if (mf.isNotNull() || mf.isPk()) sb.append(" NOT NULL");
        if (mf.hasDefaultValue()) sb.append(" DEFAULT '").append(getDefaultValue(mf)).append('\'');
        if (mf.isAutoIncreasement()) sb.append(" generated by default as identity ");
        if (mf.isPk() && en.getPks().size() == 1) {
          sb.append(" primary key ");
        }
      }
      sb.append(',');
    }
    // 结束表字段设置
    sb.setCharAt(sb.length() - 1, ')');

    // 执行创建语句
    dao.execute(Sqls.create(sb.toString()));

    // 创建联合主键
    if (en.getPks().size() > 1) {
      sb = new StringBuilder();
      sb.append("ALTER TABLE ").append(en.getTableName()).append(" ADD CONSTRAINT PK_");
      sb.append(makePksName(en));
      sb.append(" PRIMARY KEY (");
      for (MappingField mf : en.getPks()) {
        sb.append(mf.getColumnName()).append(",");
      }
      sb.setCharAt(sb.length() - 1, ')');
      dao.execute(Sqls.create(sb.toString()));
    }

    // 创建关联表
    createRelation(dao, en);
    // 创建索引
    dao.execute(createIndexs(en).toArray(new Sql[0]));
    // 添加注释(表注释与字段注释)
    addComment(dao, en);

    return true;
  }
Пример #11
0
  @SuppressWarnings({"unchecked", "rawtypes"})
  public static boolean filterFields(
      Object obj, FieldMatcher matcher, Dao dao, Callback2<MappingField, Object> callback) {
    if (obj == null) return false;
    obj = Lang.first(obj);
    if (obj == null) {
      return false;
    }
    if (obj.getClass() == Class.class) {
      throw Lang.impossible();
    }
    if (obj instanceof String || obj instanceof Number || obj instanceof Boolean) {
      throw Lang.impossible();
    }
    Entity en = dao.getEntity(obj.getClass());
    if (en == null) {
      throw Lang.impossible();
    }

    List<MappingField> mfs = en.getMappingFields();
    if (matcher != null) {
      Iterator<MappingField> it = mfs.iterator();
      while (it.hasNext()) {
        MappingField mf = it.next();
        if (!matcher.match(mf.getName())) it.remove();
      }
    }
    boolean flag = false;
    for (MappingField mf : mfs) {
      if (matcher.isIgnoreId() && mf.isId()) continue;
      if (matcher.isIgnoreName() && mf.isName()) continue;
      if (matcher.isIgnorePk() && mf.isCompositePk()) continue;
      Object val = mf.getValue(obj);
      if (val == null) {
        if (matcher.isIgnoreNull()) continue;
      }
      if (val instanceof Number && ((Number) val).doubleValue() == 0.0) {
        if (matcher.isIgnoreZero()) continue;
      }
      if (val instanceof Date) {
        if (matcher.isIgnoreDate()) continue;
      }
      callback.invoke(mf, val);
      flag = true;
    }
    return flag;
  }
Пример #12
0
 public void setupEntityField(Connection conn, Entity<?> en) {
   Statement stat = null;
   ResultSet rs = null;
   ResultSetMetaData rsmd = null;
   try {
     // 获取数据库元信息
     stat = conn.createStatement();
     rs = stat.executeQuery(createResultSetMetaSql(en));
     rsmd = rs.getMetaData();
     // 循环字段检查
     for (MappingField mf : en.getMappingFields()) {
       try {
         int ci = Daos.getColumnIndex(rsmd, mf.getColumnName());
         // 是否只读,如果人家已经是指明是只读了,那么就不要自作聪明得再从数据库里验证了
         // if (!mf.isReadonly() && rsmd.isReadOnly(ci))
         // mf.setAsReadonly();
         // 是否非空
         if (ResultSetMetaData.columnNoNulls == rsmd.isNullable(ci)) mf.setAsNotNull();
         // 枚举类型在数据库中的值
         if (mf.getTypeMirror().isEnum()) {
           if (Daos.isIntLikeColumn(rsmd, ci)) {
             mf.setColumnType(ColType.INT);
           } else {
             mf.setColumnType(ColType.VARCHAR);
           }
         }
       } catch (Exception e) {
         // TODO 需要log一下不?
       }
     }
   } catch (Exception e) {
     if (log.isDebugEnabled()) log.debugf("Table '%s' doesn't exist!", en.getViewName());
   }
   // Close ResultSet and Statement
   finally {
     Daos.safeClose(stat, rs);
   }
 }
Пример #13
0
 protected String getDefaultValue(MappingField mf) {
   return mf.getDefaultValue(null).replaceAll("@", "@@");
 }
Пример #14
0
  public boolean createEntity(Dao dao, Entity<?> en) {
    StringBuilder sb = new StringBuilder("CREATE TABLE " + en.getTableName() + "(");
    // 创建字段
    for (MappingField mf : en.getMappingFields()) {
      if (mf.isReadonly()) continue;
      sb.append('\n').append(mf.getColumnName());
      // 自增主键特殊形式关键字
      if (mf.isId() && mf.isAutoIncreasement()) {
        sb.append(" SERIAL");
      } else {
        sb.append(' ').append(evalFieldType(mf));
        // 非主键的 @Name,应该加入唯一性约束
        if (mf.isName() && en.getPkType() != PkType.NAME) {
          sb.append(" UNIQUE NOT NULL");
        }
        // 普通字段
        else {
          if (mf.isUnsigned()) sb.append(" UNSIGNED");
          if (mf.isNotNull()) sb.append(" NOT NULL");
          if (mf.isAutoIncreasement()) throw Lang.noImplement();
          if (mf.hasDefaultValue())
            sb.append(" DEFAULT '").append(getDefaultValue(mf)).append('\'');
        }
      }
      sb.append(',');
    }
    // 创建主键
    List<MappingField> pks = en.getPks();
    if (!pks.isEmpty()) {
      sb.append('\n');
      sb.append(
          String.format(
              "CONSTRAINT %s_pkey PRIMARY KEY (",
              en.getTableName().replace('.', '_').replace('"', '_')));
      for (MappingField pk : pks) {
        sb.append(pk.getColumnName()).append(',');
      }
      sb.setCharAt(sb.length() - 1, ')');
      sb.append("\n ");
    }

    // 结束表字段设置
    sb.setCharAt(sb.length() - 1, ')');

    // 执行创建语句
    dao.execute(Sqls.create(sb.toString()));

    // 创建索引
    dao.execute(createIndexs(en).toArray(new Sql[0]));

    // 创建关联表
    createRelation(dao, en);

    // 添加注释(表注释与字段注释)
    addComment(dao, en);

    return true;
  }
Пример #15
0
 @Override
 public ValueAdaptor getAdaptor(MappingField ef) {
   if (ef.getTypeMirror().isOf(Blob.class)) return new BlobValueAdaptor2(Jdbcs.getFilePool());
   return super.getAdaptor(ef);
 }
Пример #16
0
 /**
  * 执行一个特殊的Chain(事实上普通Chain也能执行,但不建议使用)
  *
  * @see org.nutz.dao.Chain#addSpecial(String, Object)
  */
 @SuppressWarnings({"rawtypes"})
 public static int updateBySpecialChain(
     Dao dao, Entity en, String tableName, Chain chain, Condition cnd) {
   if (en != null) tableName = en.getTableName();
   if (tableName == null) throw Lang.makeThrow(DaoException.class, "tableName and en is NULL !!");
   final StringBuilder sql = new StringBuilder("UPDATE ").append(tableName).append(" SET ");
   Chain head = chain.head();
   final List<Object> values = new ArrayList<Object>();
   final List<ValueAdaptor> adaptors = new ArrayList<ValueAdaptor>();
   while (head != null) {
     MappingField mf = null;
     if (en != null) mf = en.getField(head.name());
     String colName = head.name();
     if (mf != null) colName = mf.getColumnName();
     sql.append(colName).append("=");
     if (head.special()) {
       if (head.value() != null && head.value() instanceof String) {
         String str = (String) head.value();
         if (str.length() > 0) {
           switch (str.charAt(0)) {
             case '+':
             case '-':
             case '*':
             case '/':
             case '%':
             case '&':
             case '^':
             case '|':
               sql.append(colName);
               break;
           }
         }
       }
       sql.append(head.value());
     } else {
       sql.append("?");
       values.add(head.value());
       ValueAdaptor adaptor = Jdbcs.getAdaptorBy(head.value());
       if (mf != null && mf.getAdaptor() != null) adaptor = mf.getAdaptor();
       adaptors.add(adaptor);
     }
     sql.append(" ");
     head = head.next();
     if (head != null) sql.append(", ");
   }
   if (cnd != null) sql.append(" ").append(cnd.toSql(en));
   if (log.isDebugEnabled()) log.debug(sql);
   final int[] ints = new int[1];
   dao.run(
       new ConnCallback() {
         public void invoke(Connection conn) throws Exception {
           PreparedStatement ps = conn.prepareStatement(sql.toString());
           try {
             for (int i = 0; i < values.size(); i++) adaptors.get(i).set(ps, values.get(i), i + 1);
             ints[0] = ps.executeUpdate();
           } finally {
             Daos.safeClose(ps);
           }
         }
       });
   return ints[0];
 }
Пример #17
0
 public void addDefaultValue(StringBuilder sb, MappingField mf) {
   if (!mf.hasDefaultValue()) return;
   if (mf.getTypeMirror().isNumber()) sb.append(" DEFAULT ").append(getDefaultValue(mf));
   else sb.append(" DEFAULT '").append(getDefaultValue(mf)).append('\'');
 }
Пример #18
0
 public ValueAdaptor getAdaptor(MappingField ef) {
   if (ef.getTypeMirror().isBoolean()) return new DB2BooleanAdaptor();
   return super.getAdaptor(ef);
 }
Пример #19
0
  /** 根据Pojo生成数据字典,zdoc格式 */
  public static StringBuilder dataDict(DataSource ds, String... packages) {
    StringBuilder sb = new StringBuilder();
    List<Class<?>> ks = new ArrayList<Class<?>>();
    for (String packageName : packages) {
      ks.addAll(Scans.me().scanPackage(packageName));
    }
    Iterator<Class<?>> it = ks.iterator();
    while (it.hasNext()) {
      Class<?> klass = it.next();
      if (klass.getAnnotation(Table.class) == null) it.remove();
    }
    // log.infof("Found %d table class", ks.size());

    JdbcExpert exp = Jdbcs.getExpert(ds);
    NutDao dao = new NutDao(ds);

    Method evalFieldType;
    try {
      evalFieldType = exp.getClass().getDeclaredMethod("evalFieldType", MappingField.class);
    } catch (Throwable e) {
      throw Lang.wrapThrow(e);
    }
    evalFieldType.setAccessible(true);
    Entity<?> entity = null;
    String line = "-------------------------------------------------------------------\n";
    sb.append("#title:数据字典\n");
    sb.append("#author:wendal\n");
    sb.append("#index:0,1\n").append(line);
    for (Class<?> klass : ks) {
      sb.append(line);
      entity = dao.getEntity(klass);
      sb.append("表名 ").append(entity.getTableName()).append("\n\n");
      if (!Strings.isBlank(entity.getTableComment()))
        sb.append("表注释: ").append(entity.getTableComment());
      sb.append("\t").append("Java类名 ").append(klass.getName()).append("\n\n");
      sb.append("\t||序号||列名||数据类型||主键||非空||默认值||java属性名||java类型||注释||\n");
      int index = 1;
      for (MappingField field : entity.getMappingFields()) {
        String dataType;
        try {
          dataType = (String) evalFieldType.invoke(exp, field);
        } catch (Throwable e) {
          throw Lang.wrapThrow(e); // 不可能发生的
        }
        sb.append("\t||")
            .append(index++)
            .append("||")
            .append(field.getColumnName())
            .append("||")
            .append(dataType)
            .append("||")
            .append(field.isPk())
            .append("||")
            .append(field.isNotNull())
            .append("||")
            .append(field.getDefaultValue(null) == null ? " " : field.getDefaultValue(null))
            .append("||")
            .append(field.getName())
            .append("||")
            .append(field.getTypeClass().getName())
            .append("||")
            .append(field.getColumnComment() == null ? " " : field.getColumnComment())
            .append("||\n");
      }
    }
    return sb;
  }
Пример #20
0
  public String evalFieldType(MappingField mf) {
    if (mf.getCustomDbType() != null) return mf.getCustomDbType();
    switch (mf.getColumnType()) {
      case CHAR:
        return "CHAR(" + mf.getWidth() + ")";

      case BOOLEAN:
        return "BOOLEAN";

      case VARCHAR:
        return "VARCHAR(" + mf.getWidth() + ")";

      case TEXT:
        return "TEXT";

      case BINARY:
        return "BLOB";

      case TIMESTAMP:
        return "TIMESTAMP";

      case DATETIME:
        return "DATETIME";

      case DATE:
        return "DATE";
      case TIME:
        return "TIME";

      case INT:
        // 用户自定义了宽度
        if (mf.getWidth() > 0) return "INT(" + mf.getWidth() + ")";
        // 用数据库的默认宽度
        return "INT";

      case FLOAT:
        // 用户自定义了精度
        if (mf.getWidth() > 0 && mf.getPrecision() > 0) {
          return "NUMERIC(" + mf.getWidth() + "," + mf.getPrecision() + ")";
        }
        // 用默认精度
        if (mf.getTypeMirror().isDouble()) return "NUMERIC(15,10)";
        return "FLOAT";

      case PSQL_ARRAY:
        return "ARRAY";

      case PSQL_JSON:
      case MYSQL_JSON:
        return "JSON";
        // TODO 这里不用加 default 么
    }
    throw Lang.makeThrow(
        "Unsupport colType '%s' of field '%s' in '%s' ",
        mf.getColumnType(), mf.getName(), mf.getEntity().getType().getName());
  }