Jpaマルチデータソース、データソースごとに個別のネーミングポリシーを構成

4957 ワード

起因:
  • spring data jpaマルチデータソース構成はJpaマルチデータソース構成を参照できます.私はこの文章を参考に構成しました.
  • 私のデータソースは2つあります.1つはmysqlで、1つはsqlserverです.
  • mysqlデータベースのテーブルフィールド形式はjpaデフォルトのネーミングポリシーを採用し、エンティティ属性はcurrentUserName形式のアルパカネーミングを採用し、マッピング時に自動的に大文字を小文字に変換し、_(下線)接続、すなわちcurrent_user_name.
  • ただし、sqlserverデータベースのテーブル内のフィールドの名前はCurrentUserNameという形式です.したがって、マッピング時に例外が報告されます.無効なカラム名です.関連エンティティのフィールドに@column注記を追加しても無効です.
  • は、jpaのデフォルトのネーミングポリシーがspring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategyであるため、このネーミングポリシーを使用すると、@column注釈が無効になるため、資料を検索しました.ネット上の解決策はすべて単一のデータソースの構成であり、私の現在のプロジェクトで発生している問題を解決することはできません.
  • 仕方なく自分で解決するしかない.

  • 解決策
  • 上記の参考文書によれば、マルチデータソース構成には、
  • というコードがある.
        //  JPA    
        @Autowired
        private JpaProperties jpaProperties;
    
        //  jpa    
        private Map getVendorProperties(DataSource dataSource) {
            return jpaProperties.getHibernateProperties(dataSource);
        }
    
    
  • return jpaProperties.getHibernateProperties(dataSource);このコードの前に以下のコードを追加します:
  • jpaProperties.getHibernate().getNaming().setPhysicalStrategy("org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
    
    

    次のようになります.
    //  jpa    
        private Map getVendorProperties(DataSource dataSource) {
            jpaProperties.getHibernate().getNaming().setPhysicalStrategy("org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
            return jpaProperties.getHibernateProperties(dataSource);
        }
    
    
  • jpaのデフォルト構成は2つあり、必要に応じて選択できます:
  •     //spring      --          
        private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy";
        
        //spring      --            ,        
        private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy";
    
    
  • jpaのデフォルトのネーミングポリシーは、カスタマイズ可能なネーミングポリシーを満たすことができません.ネット上には関連する例がありますが、これ以上説明しません.

  • この構成に関連するソースコードを見てみましょう.
  • HibernateおよびNamingは、JpaPropertiesの2つの内部クラス
  • である.
    @ConfigurationProperties(prefix = "spring.jpa")
    public class JpaProperties {
    
           ......  
    
           private Hibernate hibernate = new Hibernate();
    
           public Hibernate getHibernate() {
              return this.hibernate;
           }
    
          ......  
    
      ......  
      public static class Hibernate {
    
              private static final String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id."
                      + "new_generator_mappings";
    
              public Naming getNaming() {
                  return this.naming;
              }
              ......  
      }
    
      ......  
      public static class Naming {
    
              private static final String DEFAULT_PHYSICAL_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy";
    
              private static final String DEFAULT_IMPLICIT_STRATEGY = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy";
    
              /**
               * Fully qualified name of the physical naming strategy.
               */
              private String physicalStrategy;
    
              public void setPhysicalStrategy(String physicalStrategy) {
                  this.physicalStrategy = physicalStrategy;
              }
              
              private void applyNamingStrategies(Map properties) {
                  applyNamingStrategy(properties, "hibernate.implicit_naming_strategy",
                        this.implicitStrategy, DEFAULT_IMPLICIT_STRATEGY);
                  applyNamingStrategy(properties, "hibernate.physical_naming_strategy",
                        this.physicalStrategy, DEFAULT_PHYSICAL_STRATEGY);
              }
    
              private void applyNamingStrategy(Map properties, String key,
                      String strategy, String defaultStrategy) {
                  if (strategy != null) {
                      properties.put(key, strategy);
                  }
                  else if (defaultStrategy != null && !properties.containsKey(key)) {
                      properties.put(key, defaultStrategy);
                  }
              }
              ......  
      }
    }
    
  • は、連続的な呼び出しによってNamingオブジェクトを取得し、命名ポリシーを設定する属性physicalStrategyがこのオブジェクトに含まれる.
  • return jpaProperties.getHibernateProperties(dataSource);最後に戻ったこの文では、最終的にapplyNamingStrategies()という方法を呼び出します.私たちは前のステップでstrategyを設定しました.applyNamingStrategy()という方法では、空ではないと判断し、putpropertiesに入れます.このポリシーを構成しないと、ソースコードに示すようにデフォルトのネーミングポリシーが設定されます.

  • 間違いがあれば、指摘を歓迎します.