通過實體類獲取對應數據表的主鍵字段名

通過實體類獲取對應數據表的主鍵字段名

前提:

  • 數據表中的主鍵不是聯合
  • 主鍵實體類的主鍵字段上有@Id主鍵,並且有@Column註解,且@Column註解中的name字段中存放了對應數據表的主鍵字段名

實體類示例:

@Entity
@Table(name="user")
public class User {
  
  // 數據表的主鍵字段
  @Id
  @Column(name="id")
  private Integer userId;
  
  ...
}

Java代碼:

import javax.persistence.Column;
import javax.persistence.Id;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DbTableUtil {
  
  private final static Logger LOG = LoggerFactory.getLogger(DbTableUtil.class);
  
  public static void main(String[] args) {

    String idName = getPrimaryKeyName(TranMultiLanguageKey.class);
    LOG.info("主鍵字段名:{}", idName);
  }
  
  /**
     * 獲取實體類所對應數據表的主鍵字段名
     * @param clazz
     * @return
     */
  public static String getPrimaryKeyName(Class clazz) {

    // 獲取該類的所有字段
    List<Field> fields = getAllFieldsWithRoot(clazz);

    for(Field field : fields) {
      Id id = field.getAnnotation(Id.class);
      // 如果該字段是主鍵
      if(id != null) {
        // 從@Column中的name字段中獲取數據表的主鍵字段名
        Column column = field.getAnnotation(Column.class);
        String idName = column.name();
        // 將帶下劃線的字段名變成駝峯命名格式
        if(idName.contains("_")) {
          StringBuilder sb = new StringBuilder();
          String[] strs = idName.split("_");
          sb.append(strs[0]);
          for(int i=1; i<strs.length; ++i) {
            sb.append(strs[i].substring(0,1).toUpperCase() + strs[i].substring(1));
          }
          idName = sb.toString();
        }
        return idName;
      }
    }

    return null;
  }

  //獲取類clazz的所有Field,包括其父類的Field
  private static List<Field> getAllFieldsWithRoot(Class<?> clazz) {
    List<Field> fieldList = new ArrayList<>();
    Field[] dFields = clazz.getDeclaredFields();//獲取本類所有字段
    if (null != dFields && dFields.length > 0)
      fieldList.addAll(Arrays.asList(dFields));

    // 若父類是Object,則直接返回當前Field列表
    Class<?> superClass = clazz.getSuperclass();
    if (superClass == Object.class) return Arrays.asList(dFields);

    // 遞歸查詢父類的field列表
    List<Field> superFields = getAllFieldsWithRoot(superClass);

    if (null != superFields && !superFields.isEmpty()) {
      superFields.stream().
        filter(field -> !fieldList.contains(field)).//不重複字段
        forEach(field -> fieldList.add(field));
    }
    return fieldList;
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章