Java 使用EclipseLink自定义JPA字段名映射
由于历史原因,我需要在当前使用EclipseLink的项目中,将驼峰大小写名称映射为下划线分隔的名称。我知道我们可以在JPA中单独定制名称映射,但是我们有一个很长的驼峰大小写名称列表要更改,所以如果可能的话,我们希望避免这种样板代码 我想达到的目标如下。假设我们有一个实体类,如下所示:Java 使用EclipseLink自定义JPA字段名映射,java,jakarta-ee,jpa,eclipselink,Java,Jakarta Ee,Jpa,Eclipselink,由于历史原因,我需要在当前使用EclipseLink的项目中,将驼峰大小写名称映射为下划线分隔的名称。我知道我们可以在JPA中单独定制名称映射,但是我们有一个很长的驼峰大小写名称列表要更改,所以如果可能的话,我们希望避免这种样板代码 我想达到的目标如下。假设我们有一个实体类,如下所示: @Entity public class FooBar { @Id @GeneratedValue private Long id; @Temporal( TemporalType.TI
@Entity
public class FooBar {
@Id @GeneratedValue
private Long id;
@Temporal( TemporalType.TIMESTAMP )
private Date dateCreated;
}
我希望这个类映射到一个名为“foo_bar”的表,列为“id”和“date_created”。请注意,数据库中的所有名称都是小写的
我搜索了一下,找到了一个更改表名的解决方案。但是,我不知道如何更改实体类中的字段名
下面是我的名称映射自定义程序,其中方法updateFieldNameMappings()
没有将fieldName
映射到field\u name
,这正是我想要实现的。问题归结为如何获得类定义中的字段名。那么,在日食中我该怎么做呢
public class JpaNameMappingCustomizer implements SessionCustomizer {
@Override
public void customize( Session session ) throws Exception {
Map<Class, ClassDescriptor> descs = session.getDescriptors();
Collection<ClassDescriptor> descriptors = descs.values();
// This code assumes single table per descriptor!
for (ClassDescriptor desc : descriptors) {
updateTableNameMapping( desc );
updateFieldNameMapping( desc );
}
}
private void updateTableNameMapping ( ClassDescriptor desc ) {
Class clazz = desc.getJavaClass();
String tableName = camelCaseToUnderscore( clazz.getSimpleName() );
desc.setTableName( tableName );
}
private void updateFieldNameMapping ( ClassDescriptor desc ) {
// build name maps
Field[] fields = desc.getJavaClass().getDeclaredFields();
String tableName = desc.getTableName();
Map<String,String> nameMap = new HashMap<>();
String prefix = tableName + ".";
for( Field field : fields ) {
String name = field.getName();
String key = prefix + name.toUpperCase();
String value = prefix + camelCaseToUnderscore( name );
nameMap.put( key, value );
}
for (DatabaseMapping mapping : desc.getMappings()) {
if (mapping.isDirectToFieldMapping()) {
DirectToFieldMapping directMapping = (DirectToFieldMapping) mapping;
String oldFieldName = directMapping.getFieldName(); // format: table_name.FIELD
directMapping.setFieldName( nameMap.get( oldFieldName ) );
}
}
}
private String camelCaseToUnderscore( String camelCase ) {
return camelCase.trim().replaceAll("(?<!^)[A-Z](?!$)", "_$0").toLowerCase();
}
}
我认为您没有在
persistence.xml中添加以下行,即EclipseLink
使用自己的SessionCustomizer
<property name="eclipselink.session.customizer" value="your.company.package.name.JpaNameMappingCustomizer"/>
提及
而不是
directMapping.setFieldName(nameMap.get(oldFieldName ));
尝试:
在EclipseLink 2.5.0下,这为我提供了窍门。也许你可以使用我的会话定制器。它将表名和字段名转换为大小写。它支持继承和嵌入的实体。
我测试了2年,没有任何问题或副作用。享受吧
import java.sql.SQLException;
import java.util.Locale;
import java.util.Vector;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.schemaframework.IndexDefinition;
public class CamelNamingStrategy implements SessionCustomizer {
public static String unqualify(final String qualifiedName) {
int loc = qualifiedName.lastIndexOf(".");
return loc < 0 ? qualifiedName : qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
}
@Override
public void customize(final Session session) throws SQLException {
for (ClassDescriptor descriptor : session.getDescriptors().values()) {
if (!descriptor.getTables().isEmpty()) {
// Take table name from @Table if exists
String tableName = null;
if (descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
tableName = unqualify(descriptor.getJavaClassName());
} else {
tableName = descriptor.getTableName();
}
tableName = camelCaseToUnderscore(tableName);
descriptor.setTableName(tableName);
for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
index.setTargetTable(tableName);
}
Vector<DatabaseMapping> mappings = descriptor.getMappings();
camelCaseToUnderscore(mappings);
} else if (descriptor.isAggregateDescriptor() || descriptor.isChildDescriptor()) {
camelCaseToUnderscore(descriptor.getMappings());
}
}
}
private void camelCaseToUnderscore(Vector<DatabaseMapping> mappings) {
for (DatabaseMapping mapping : mappings) {
DatabaseField field = mapping.getField();
if (mapping.isDirectToFieldMapping() && !mapping.isPrimaryKeyMapping()) {
String attributeName = mapping.getAttributeName();
String underScoredFieldName = camelCaseToUnderscore(attributeName);
field.setName(underScoredFieldName);
}
}
}
private String camelCaseToUnderscore(final String name) {
StringBuffer buf = new StringBuffer(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(Locale.ENGLISH);
}
}
import java.sql.SQLException;
导入java.util.Locale;
导入java.util.Vector;
导入org.eclipse.persistence.config.SessionCustomizer;
导入org.eclipse.persistence.descriptors.ClassDescriptor;
导入org.eclipse.persistence.internal.helper.DatabaseField;
导入org.eclipse.persistence.mappings.DatabaseMapping;
导入org.eclipse.persistence.sessions.Session;
导入org.eclipse.persistence.tools.schemaframework.IndexDefinition;
公共类CamelNamingStrategy实现SessionCustomizer{
公共静态字符串不合格(最终字符串合格名称){
int loc=qualifiedName.lastIndexOf(“.”);
返回loc<0?qualifiedName:qualifiedName.substring(qualifiedName.lastIndexOf(“.”+1);
}
@凌驾
public void customize(最终会话)引发SQLException{
for(类描述符描述符:session.getDescriptors().values()){
如果(!descriptor.getTables().isEmpty()){
//如果存在,则从@table获取表名
字符串tableName=null;
if(descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())){
tableName=不合格(descriptor.getJavaClassName());
}否则{
tableName=descriptor.getTableName();
}
tableName=camelCaseToUnderscore(tableName);
descriptor.setTableName(tableName);
for(IndexDefinition索引:descriptor.getTables().get(0.getIndexes()){
index.setTargetTable(表名);
}
向量映射=descriptor.getMappings();
camelCaseToUnderscore(映射);
}else if(descriptor.isaggregatedDescriptor()| | descriptor.isChildDescriptor()){
camelCaseToUnderscore(descriptor.getMappings());
}
}
}
private CaseTounderScore(向量映射){
for(数据库映射:映射){
DatabaseField=mapping.getField();
if(mapping.isDirectToFieldMapping()&&!mapping.isPrimaryKeyMapping()){
字符串attributeName=mapping.getAttributeName();
字符串下划线FieldName=camelCaseToUnderscore(attributeName);
field.setName(下划线FieldName);
}
}
}
私有字符串camelCaseToUnderscore(最终字符串名称){
StringBuffer buf=新的StringBuffer(名称.replace('.','');
对于(int i=1;i
如果您想使用@Column注释区分非注释元素和注释元素,那么我发现了一个非常漂亮的示例:
public class CamelCaseSessionCustomizer implements SessionCustomizer {
@Override
public void customize(Session session) throws SQLException {
for (ClassDescriptor descriptor : session.getDescriptors().values()) {
// Only change the table name for non-embedable entities with no
// @Table already
if (!descriptor.getTables().isEmpty() && descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
String tableName = addUnderscores(descriptor.getTableName());
descriptor.setTableName(tableName);
for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
index.setTargetTable(tableName);
}
}
for (DatabaseMapping mapping : descriptor.getMappings()) {
// Only change the column name for non-embedable entities with
// no @Column already
if (mapping instanceof AggregateObjectMapping) {
for (Association association : ((AggregateObjectMapping) mapping).getAggregateToSourceFieldAssociations()) {
DatabaseField field = (DatabaseField) association.getValue();
field.setName(addUnderscores(field.getName()));
for (DatabaseMapping attrMapping : session.getDescriptor(((AggregateObjectMapping) mapping).getReferenceClass()).getMappings()) {
if (attrMapping.getAttributeName().equalsIgnoreCase((String) association.getKey())) {
((AggregateObjectMapping) mapping).addFieldTranslation(field, addUnderscores(attrMapping.getAttributeName()));
((AggregateObjectMapping) mapping).getAggregateToSourceFields().remove(association.getKey());
break;
}
}
}
} else if (mapping instanceof ObjectReferenceMapping) {
for (DatabaseField foreignKey : ((ObjectReferenceMapping) mapping).getForeignKeyFields()) {
foreignKey.setName(addUnderscores(foreignKey.getName()));
}
} else if (mapping instanceof DirectMapMapping) {
for (DatabaseField referenceKey : ((DirectMapMapping) mapping).getReferenceKeyFields()) {
referenceKey.setName(addUnderscores(referenceKey.getName()));
}
for (DatabaseField sourceKey : ((DirectMapMapping) mapping).getSourceKeyFields()) {
sourceKey.setName(addUnderscores(sourceKey.getName()));
}
} else {
DatabaseField field = mapping.getField();
if (field != null && !mapping.getAttributeName().isEmpty() && field.getName().equalsIgnoreCase(mapping.getAttributeName())) {
field.setName(addUnderscores(mapping.getAttributeName()));
}
}
}
}
}
private static String addUnderscores(String name) {
if (name.equalsIgnoreCase("begintime")) {
System.err.println();
}
StringBuffer buf = new StringBuffer(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();
}
}
公共类CamelCaseSessionCustomizer实现SessionCustomizer{
@凌驾
public void customize(会话)引发SQLException{
for(类描述符描述符:session.getDescriptors().values()){
//仅更改不带
//@已经有桌子了
if(!descriptor.getTables().isEmpty()&&descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())){
String tableName=add下划线(descriptor.getTableName());
descriptor.setTableName(tableName);
for(IndexDefinition索引:descriptor.getTables().get(0.getIndexes()){
index.setTargetTable(表名);
}
}
for(数据库映射:descriptor.getMappings()){
//仅更改具有的不可嵌入实体的列名
//已经没有@列了
if(聚合对象映射的映射实例){
对于(关联:((AggregateObjectMapping)映射)。GetAggregateSourceFieldAssociations(){
DatabaseField=(DatabaseField)association.getValue();
field.setName(add下划线(field.getName());
对于(DatabaseMapping attrMapping:session.getDescriptor(((AggregateObjectMapping)映射)。getReferenceClass()
import java.sql.SQLException;
import java.util.Locale;
import java.util.Vector;
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.tools.schemaframework.IndexDefinition;
public class CamelNamingStrategy implements SessionCustomizer {
public static String unqualify(final String qualifiedName) {
int loc = qualifiedName.lastIndexOf(".");
return loc < 0 ? qualifiedName : qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
}
@Override
public void customize(final Session session) throws SQLException {
for (ClassDescriptor descriptor : session.getDescriptors().values()) {
if (!descriptor.getTables().isEmpty()) {
// Take table name from @Table if exists
String tableName = null;
if (descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
tableName = unqualify(descriptor.getJavaClassName());
} else {
tableName = descriptor.getTableName();
}
tableName = camelCaseToUnderscore(tableName);
descriptor.setTableName(tableName);
for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
index.setTargetTable(tableName);
}
Vector<DatabaseMapping> mappings = descriptor.getMappings();
camelCaseToUnderscore(mappings);
} else if (descriptor.isAggregateDescriptor() || descriptor.isChildDescriptor()) {
camelCaseToUnderscore(descriptor.getMappings());
}
}
}
private void camelCaseToUnderscore(Vector<DatabaseMapping> mappings) {
for (DatabaseMapping mapping : mappings) {
DatabaseField field = mapping.getField();
if (mapping.isDirectToFieldMapping() && !mapping.isPrimaryKeyMapping()) {
String attributeName = mapping.getAttributeName();
String underScoredFieldName = camelCaseToUnderscore(attributeName);
field.setName(underScoredFieldName);
}
}
}
private String camelCaseToUnderscore(final String name) {
StringBuffer buf = new StringBuffer(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(Locale.ENGLISH);
}
}
public class CamelCaseSessionCustomizer implements SessionCustomizer {
@Override
public void customize(Session session) throws SQLException {
for (ClassDescriptor descriptor : session.getDescriptors().values()) {
// Only change the table name for non-embedable entities with no
// @Table already
if (!descriptor.getTables().isEmpty() && descriptor.getAlias().equalsIgnoreCase(descriptor.getTableName())) {
String tableName = addUnderscores(descriptor.getTableName());
descriptor.setTableName(tableName);
for (IndexDefinition index : descriptor.getTables().get(0).getIndexes()) {
index.setTargetTable(tableName);
}
}
for (DatabaseMapping mapping : descriptor.getMappings()) {
// Only change the column name for non-embedable entities with
// no @Column already
if (mapping instanceof AggregateObjectMapping) {
for (Association association : ((AggregateObjectMapping) mapping).getAggregateToSourceFieldAssociations()) {
DatabaseField field = (DatabaseField) association.getValue();
field.setName(addUnderscores(field.getName()));
for (DatabaseMapping attrMapping : session.getDescriptor(((AggregateObjectMapping) mapping).getReferenceClass()).getMappings()) {
if (attrMapping.getAttributeName().equalsIgnoreCase((String) association.getKey())) {
((AggregateObjectMapping) mapping).addFieldTranslation(field, addUnderscores(attrMapping.getAttributeName()));
((AggregateObjectMapping) mapping).getAggregateToSourceFields().remove(association.getKey());
break;
}
}
}
} else if (mapping instanceof ObjectReferenceMapping) {
for (DatabaseField foreignKey : ((ObjectReferenceMapping) mapping).getForeignKeyFields()) {
foreignKey.setName(addUnderscores(foreignKey.getName()));
}
} else if (mapping instanceof DirectMapMapping) {
for (DatabaseField referenceKey : ((DirectMapMapping) mapping).getReferenceKeyFields()) {
referenceKey.setName(addUnderscores(referenceKey.getName()));
}
for (DatabaseField sourceKey : ((DirectMapMapping) mapping).getSourceKeyFields()) {
sourceKey.setName(addUnderscores(sourceKey.getName()));
}
} else {
DatabaseField field = mapping.getField();
if (field != null && !mapping.getAttributeName().isEmpty() && field.getName().equalsIgnoreCase(mapping.getAttributeName())) {
field.setName(addUnderscores(mapping.getAttributeName()));
}
}
}
}
}
private static String addUnderscores(String name) {
if (name.equalsIgnoreCase("begintime")) {
System.err.println();
}
StringBuffer buf = new StringBuffer(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();
}
}