Skip to content

Instantly share code, notes, and snippets.

@jerry80409
Created June 28, 2021 01:47
Show Gist options
  • Save jerry80409/03595192df901496f96be9e51c2dda6f to your computer and use it in GitHub Desktop.
Save jerry80409/03595192df901496f96be9e51c2dda6f to your computer and use it in GitHub Desktop.
Table 欄位註解 comment 工具
@Autowired
private EntityManager entityManager;
@SneakyThrows
@GetMapping("/comment")
@Transactional(noRollbackFor = SQLGrammarException.class)
public ResponseEntity<String> comment(@RequestParam(required = false) String className) {
final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
final Set<BeanDefinition> classes = provider.findCandidateComponents("tw.com.softleader.jasmine.policy.entity");
for (BeanDefinition bean: classes) {
final Class<?> clazz = Class.forName(bean.getBeanClassName());
final String clazzName = clazz.getName().split("\\.")[6];
if (clazzName.contains("Generic")) {
continue;
}
final Table table = clazz.getAnnotation(Table.class);
if (Objects.isNull(table)) {
continue;
}
// table Name
final String tableName = table.name();
for (Field field : FieldUtils.getAllFields(clazz)) {
final ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
final Transient transientAnnotation = field.getAnnotation(Transient.class);
final Column columnAnnotation = field.getAnnotation(Column.class);
if (Objects.isNull(apiModelProperty) || Objects.nonNull(transientAnnotation)) {
continue;
}
// comment
final String comment = apiModelProperty.value();
// column name
final String columnName;
if (Objects.nonNull(columnAnnotation)) {
columnName = columnAnnotation.name().toUpperCase();
} else {
columnName = field.getName()
.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2")
.replaceAll("([a-z])([A-Z])", "$1_$2")
.toUpperCase();
}
log.info("{} - {} - {}", tableName, columnName, comment);
final String sql = StringUtils.format("COMMENT on COLUMN {}.{} IS '{}'",
tableName, columnName, comment).toUpperCase();
log.info("sql: {}", sql);
try {
// execute statement
entityManager.createNativeQuery(sql).executeUpdate();
entityManager.flush();
} catch (Exception e) {
log.error(StringUtils.format("無法處理欄位 {}-{}-{}", tableName, columnName, comment), e);
}
}
}
return ResponseEntity.ok("down ");
}
@KyleCB
Copy link

KyleCB commented Jun 29, 2021

以下是改寫 Code
改為一次可以輸入多筆路徑 path 用 "," 隔開
增加判斷 Money 類別使用 Columns 會讀取不到 Column 導致無法產生註解的問題

import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModelProperty;
import lombok.SneakyThrows;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.hibernate.annotations.Columns;
import org.hibernate.exception.SQLGrammarException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import tw.com.softleader.util.StringUtils;

import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/entity")
public class EntityController {
  @Autowired private EntityManager entityManager;

  @SneakyThrows
  @GetMapping("/comment")
  @Transactional(noRollbackFor = SQLGrammarException.class)
  public ResponseEntity<String> comment(@RequestParam("path") String path) {
    final List<String> dirs = Arrays.asList(path.split(","));
    for (String dir : dirs) {
      final ClassPathScanningCandidateComponentProvider provider =
          new ClassPathScanningCandidateComponentProvider(false);
      provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
      final Set<BeanDefinition> classes = provider.findCandidateComponents(dir);

      List<String> errMsgs = Lists.newArrayList();
      for (BeanDefinition bean : classes) {
        errMsgs.clear();
        try {
          final Class<?> clazz = Class.forName(bean.getBeanClassName());
          final String clazzName = clazz.getSimpleName();
          if (clazzName.contains("Generic")) {
            continue;
          }

          final Table table = clazz.getAnnotation(Table.class);
          if (Objects.isNull(table)) {
            continue;
          }

          // table Name
          final String tableName = table.name();

          for (Field field : FieldUtils.getAllFields(clazz)) {
            final ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
            final Transient transientAnnotation = field.getAnnotation(Transient.class);
            final Column columnAnnotation = field.getAnnotation(Column.class);
            final Columns columnsAnnotation = field.getAnnotation(Columns.class);

            if (Objects.isNull(apiModelProperty) || Objects.nonNull(transientAnnotation)) {
              continue;
            }

            // comment
            final String comment = apiModelProperty.value();

            // column name
            String columnName = null;
            if (Objects.nonNull(columnAnnotation)) {
              columnName = columnAnnotation.name().toUpperCase();
            } else if (Objects.nonNull(columnsAnnotation)) {
              columnName =
                  Arrays.stream(columnsAnnotation.columns())
                      .findFirst()
                      .map(Column::name)
                      .map(String::toUpperCase)
                      .orElse(null);
            }

            // Use camel if no column name
            if (Objects.isNull(columnName)) {
              columnName =
                  field
                      .getName()
                      .replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2")
                      .replaceAll("([a-z])([A-Z])", "$1_$2")
                      .toUpperCase();
            }

            final String sql =
                StringUtils.format(
                        "COMMENT on COLUMN {}.{} IS '{}'", tableName, columnName, comment)
                    .toUpperCase();

            try {
              // execute statement
              entityManager.createNativeQuery(sql).executeUpdate();
              entityManager.flush();
            } catch (Exception e) {
              errMsgs.add(
                  StringUtils.format(
                      "Field: {}, Column: {}, Error: {}",
                      field.getName(),
                      columnName,
                      e.getMessage()));
            }
          }

          if (!errMsgs.isEmpty()) {
            System.out.println(
                String.format("===== Class: %s, Table: %s =====", clazzName, tableName));
            for (String errMsg : errMsgs) {
              System.err.println(errMsg);
            }
          }
        } catch (Exception e) {
          System.err.println(e.getMessage());
        }
      }
    }

    return ResponseEntity.ok("done.");
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment