通過實體類獲取對應數據表的主鍵字段名
前提:
- 數據表中的主鍵不是聯合
- 主鍵實體類的主鍵字段上有@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;
}
}