【问题标题】:Spring boot JPA insert in TABLE with uppercase name with HibernateSpring Boot JPA 使用 Hibernate 在 TABLE 中插入大写名称
【发布时间】:2015-04-18 18:13:53
【问题描述】:

我有一个表实体映射为:

@Entity
public class ItemsToRegister implements Serializable{

@Id
@Column(name = "ID_ITEM_TO_REGISTER")
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
.....

当我尝试在数据库中插入新记录时,表名被翻译成小写为: items_to_register ,但我的表名是 ITEMS_TO_REGISTER 如何在不更改 MySql 配置的情况下解决我的问题? (my.cnf)

我的 application.properties 文件中有:

spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy

【问题讨论】:

    标签: java mysql hibernate jpa spring-data-jpa


    【解决方案1】:

    在休眠 5 上,它会是

    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    

    在您的 application.properties 文件中。

    【讨论】:

    • hibernate 3怎么办?
    【解决方案2】:

    正如@jasonleakey 建议的那样,我们可以考虑使用如下命名策略。

    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    

    这告诉 Hibernate 生成与 @Table (name=" ") 或 @Column(name=" ") 中指定的完全相同的 SQL。一切顺利。

    但请记住——在实体类中使用不带@Table、@Column 注释的 PhysicalNamingStrategy 时,hibernate 使用类名和变量名生成 SQL。考虑下面的java类

    Class Employee {
       private String firstName;
       private String lastName; 
    }
    

    那么生成的sql就是,

    select employee0_.firstName,employee0_lastName from Employee employee0_;
    

    不幸的是,这不是一个好的选择,因为通常我们会将 DB 中的列定义为 FIRST_NAME 和 LAST_NAME,将表名定义为 EMPLOYEE。如果您不使用 PhysicalNamingStrategy,SQL 将是

    select employee0_.first_name,employee0_last_name from employee employee0_;
    

    所以它确实是在以下两个选项之间进行选择。

    • 使用 PhysicalStrategy 并使用 @Table 和 @Column 注释在 java 代码中显式定义所有表名/列名。
    • 在db中定义小写表名,让hibernate自动为我们生成表名/列名。

    【讨论】:

    • 我认为最好的方法是始终使用 PhysicalNamingStrategy 并以小写 @Table(name="name_in_lowercase") 显式定义表名。并设置数据库以使表名保持小写(对于 mysql,lower_case_table_names=1)。
    【解决方案3】:

    解决方法是添加:

    spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
    

    application.properties

    【讨论】:

      【解决方案4】:

      您需要使用 tics(`) 对表名进行转义以使其区分大小写。

      @Table(name = "`ITEMS_TO_REGISTER`")
      

      【讨论】:

      • 抽动不起作用,但转义双引号可以。 IE。 @Table(name = "\"ITEMS_TO_REGISTER\"")。我在 postgres 上并使用 eclipselink。也许这会有所作为。
      • 是的,这是正确的做法:正如 Josh C. 指出的那样,使用常规引号 (")。如果 hibernate 看到这些,它会为方言适当地引用给定的标识符,例如使用反引号 (` ) 对于 MySQL。
      • 使用正斜杠是可行的,尽管它看起来非常恶心。
      【解决方案5】:

      您可以实现自己的策略并从 application.properties 调用它:

      spring.jpa.hibernate.naming.physical-strategy=com.proto.CustomPhysicalNamingStrategy
      

      下面是一个总是首字母大写的例子

      import java.io.Serializable;
      import org.apache.commons.lang3.StringUtils;
      import org.hibernate.boot.model.naming.Identifier;
      import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
      import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
      
      public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy, Serializable {
          /**
           * Singleton access
           */
          public static final CustomPhysicalNamingStrategy INSTANCE = new CustomPhysicalNamingStrategy();
      
          @Override
          public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment context) {
              return capitalize(name);
          }
      
          @Override
          public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment context) {
              return capitalize(name);
          }
      
          @Override
          public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
              return capitalize(name);
          }
      
          @Override
          public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {
              return capitalize(name);
          }
      
          @Override
          public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
              return capitalize(name);
          }
      
          private Identifier capitalize(Identifier name) {
              if (name == null)
                  return null;
              if (name.isQuoted())
                  return name;
              String text = StringUtils.capitalize(name.getText());
              return Identifier.toIdentifier(text);
          }
      }
      

      【讨论】:

        【解决方案6】:

        你可以试试:

        @Entity
        @Table(name = "ITEMS_TO_REGISTER")
        public class ItemsToRegister implements Serializable {
           ...
        

        【讨论】:

          【解决方案7】:

          我在示例中使用 H2 数据库。

          使用反引号将表名设为“用户”会在数据库中为您提供小写的表名。

          实体类:

          数据库中的表名:

          附:您可以将实体命名为“用户”(大写),无论如何它都会给您“用户”(小写)

          来源: http://coddingbuddy.com/article/56566857/jpa-uppercase-table-names

          【讨论】:

            猜你喜欢
            • 2017-11-20
            • 1970-01-01
            • 2018-03-25
            • 1970-01-01
            • 2021-02-09
            • 1970-01-01
            • 1970-01-01
            • 2021-04-02
            • 2020-03-16
            相关资源
            最近更新 更多