jpa 元模型如何获取 table 名称
jpa metamodel how to get table name
实体:
@Entity
public class MyAccount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String userId;
private String password;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
命名策略:
public class HibernateNamingStrategy extends PhysicalNamingStrategyStandardImpl implements Serializable {
private static final long serialVersionUID = -4772523898875102775L;
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
protected static String addUnderscores(String name) {
final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
for (int i = 1; i < buf.length() - 1; i++) {
if (Character.isLowerCase(buf.charAt(i - 1)) && Character.isUpperCase(buf.charAt(i))
&& Character.isLowerCase(buf.charAt(i + 1))) {
buf.insert(i++, '_');
}
}
return buf.toString().toLowerCase();
}
}
JPA 元模型:
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(MyAccount.class)
public abstract class MyAccount_ {
public static volatile SingularAttribute<MyAccount, String> password;
public static volatile SingularAttribute<MyAccount, Integer> id;
public static volatile SingularAttribute<MyAccount, String> userId;
public static volatile SingularAttribute<MyAccount, String> email;
}
我将执行如下操作:
Join<Employee,MyAccount> project = emp.join("my_account", JoinType.LEFT);
我没有在 MyAccount_
元模型中看到任何自动生成的 table 名称相关属性。如何在连接条件中使用元模型 table 名称(我不想使用硬编码字符串)?
PS:我正在使用 Spring MVC 和命名策略,所有驼峰式大小写均由下划线分隔。
很遗憾(来自@Neil Stockton),它不是元模型的一部分,我认为它确实应该包括在内。
无论如何,我的代码没有注释,因为我使用的是隐式命名策略。
所以这样做是行不通的,它得到了 NullPointerException:
System.out.println("Table_Name: " + MyAccount.class.getAnnotation(Table.class).name());
所以最简单的方法是重用我的函数 addUnderscores
(将其更改为 public
):
System.out.println("Table_Name: " + HibernateNamingStrategy.addUnderscores(MyAccount.class.getSimpleName()));
虽然代码变长了,但我认为它比硬编码字符串更好。
希望这对其他人也有帮助。
实体:
@Entity
public class MyAccount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String userId;
private String password;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
命名策略:
public class HibernateNamingStrategy extends PhysicalNamingStrategyStandardImpl implements Serializable {
private static final long serialVersionUID = -4772523898875102775L;
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
return new Identifier(addUnderscores(name.getText()), name.isQuoted());
}
protected static String addUnderscores(String name) {
final StringBuilder buf = new StringBuilder(name.replace('.', '_'));
for (int i = 1; i < buf.length() - 1; i++) {
if (Character.isLowerCase(buf.charAt(i - 1)) && Character.isUpperCase(buf.charAt(i))
&& Character.isLowerCase(buf.charAt(i + 1))) {
buf.insert(i++, '_');
}
}
return buf.toString().toLowerCase();
}
}
JPA 元模型:
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(MyAccount.class)
public abstract class MyAccount_ {
public static volatile SingularAttribute<MyAccount, String> password;
public static volatile SingularAttribute<MyAccount, Integer> id;
public static volatile SingularAttribute<MyAccount, String> userId;
public static volatile SingularAttribute<MyAccount, String> email;
}
我将执行如下操作:
Join<Employee,MyAccount> project = emp.join("my_account", JoinType.LEFT);
我没有在 MyAccount_
元模型中看到任何自动生成的 table 名称相关属性。如何在连接条件中使用元模型 table 名称(我不想使用硬编码字符串)?
PS:我正在使用 Spring MVC 和命名策略,所有驼峰式大小写均由下划线分隔。
很遗憾(来自@Neil Stockton),它不是元模型的一部分,我认为它确实应该包括在内。
无论如何,我的代码没有注释,因为我使用的是隐式命名策略。
所以这样做是行不通的,它得到了 NullPointerException:
System.out.println("Table_Name: " + MyAccount.class.getAnnotation(Table.class).name());
所以最简单的方法是重用我的函数 addUnderscores
(将其更改为 public
):
System.out.println("Table_Name: " + HibernateNamingStrategy.addUnderscores(MyAccount.class.getSimpleName()));
虽然代码变长了,但我认为它比硬编码字符串更好。
希望这对其他人也有帮助。