通过实体类获取对应数据表的主键字段名
前提:
- 数据表中的主键不是联合
- 主键实体类的主键字段上有@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;
}
}