BeanPropertyRowMapperマッピングの基本原則、およびキャメルケースとソリューションでのフィールドマッピングの失敗の再発

【この記事は「新タレントクリエーションセレモニー」イベントに参加しており、一緒にナゲッツクリエイションの道を歩み始めます】

1.この記事のコアコンテンツ

  1. BeanPropertyRowMapperがエンティティクラスのカプセル化に自動的に役立つ理由の詳細をご覧ください。
  2. BeanPropertyRowMapperが、マッピング用のメンバー変数と列フィールドを識別する方法。
  3. フィールドキャメルケースマッピングが再現できない現象とその解決策。

2.BeanPropertyRowMapperマッピングの原則

  1. 変数名はフィールド名とまったく同じであり、マッピングは自動的に行われます。
  2. キャメルケースマッピング。

1.変数名はフィールド名と同じです(コードデモ)

  1. 次のように、最初にテーブルを準備します。ここに画像の説明を挿入 ここに画像の説明を挿入

  2. エンティティクラスコード:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class CfgInfo {
    
        private Integer id;
        private String CFG_NAM;
        private String CFG_TYP;
        private String CFG_010;
        private String CFG_020;
    
    }
    
  3. コード:

    public class demo {
    
        public static final String DRIVER = "com.mysql.cj.jdbc.Driver";
        public static final String URL = "jdbc:mysql://localhost:3306/test_mysql?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8";
        public static final String USERNAME = "root";
        public static final String PASSWORD = "xxxxxx";
    
        public static void main(String[] args) {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(DRIVER);
            dataSource.setUrl(URL);
            dataSource.setUsername(USERNAME);
            dataSource.setPassword(PASSWORD);
    
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            CfgInfo cfgInfo = jdbcTemplate.queryForObject("SELECT * FROM CFG_TB",
                    new BeanPropertyRowMapper<>(CfgInfo.class));
            System.out.println(cfgInfo);
        }
    }
    

    ここに画像の説明を挿入この場合、言うまでもなく、どのような方法でも完全かつ自動的にマッピングできます。

2.キャメルケースマッピング(エラー再現)

  1. 表は上記と同じです。

  2. エンティティクラスはキャメルケースに変更されます(idを除く):

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class CfgInfo {
    
        private Integer id;
        private String cfgNam;
        private String cfgTyp;
        private String cfg010;
        private String cfg020;
    
    }
    
  3. jdbcTemplateコードは変更されずに再実行されます。一部のマッピングが成功し、一部のマッピングが失敗したここに画像の説明を挿入ことがわかりました。具体的な理由については、以下の基本的なソースコード分析を参照してください。

3.BeanPropertyRowMapperの基本原則

1.BeanPropertyRowMapper初期化ソースコード

  1. ソースコードを直接クリックします。ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入 ここに画像の説明を挿入

2.BeanPropertyRowMapperマッピングソースコード

ここに画像の説明を挿入

小さな知識ポイントを挿入します:jdbcメタデータ関連のブログ

ここに画像の説明を挿入

ここに画像の説明を挿入

4.ハンプマッピングの問題解決

1.上記(ハンプマッピング方式)コードの理由を説明してください

  1. 上記(ハンプマッピング方式)コードの問題点を説明するために、cfg010とcfg020をマッピングできません。
    1. まず、すべての小文字はまだcfg010であり、cfg020は問題ありません
    2. 次に、こぶがアンダースコアに置き換えられます。その結果、tm番号を実行できないため、noに等しくなります。
    3. 次に、フィールドCFG_010、CFG_020、ここのすべてのスペースが削除され、小文字のcfg_010、cfg_020があります。対応する可能性があるため、マップされないため、nullになります。

2.解決策

1.フィールド名の指定

  1. 数字でそのような奇妙なことをとらないでください、嫌な人々、本当のこぶを標準化してください。

2.エイリアスを使用したSQLステートメント

ここに画像の説明を挿入

3. BeanPropertyRowMapperを継承し、内部のunderscoreNameメソッドを書き直します

  1. 内部のunderscoreNameメソッドを書き換えることができ、mappedFieldsを生成するための主要な条件がパーソナライズされます。

    public class MyBeanPropertyRowMapper<T> extends BeanPropertyRowMapper<T> {
    
        public MyBeanPropertyRowMapper(Class<T> mappedClass) {
            super(mappedClass);
        }
    
        @Override
        protected String underscoreName(String name) {
            // 就在name 中 第四个位置加上 下划线
            if (!StringUtils.hasLength(name)) {
                return "";
            }
            // 写的很不规范 别介意 理解意思就行
            // 除掉 id
            if (name.length() < 3) {
                return name;
            }
            StringBuilder result = new StringBuilder();
            result.append(name).insert(3, "_");
            return result.toString().toLowerCase();
        }
    }
    
    

    ここに画像の説明を挿入

4.実装RowMapperを自分で実装します

  1. マッピング関係のマッパーを自分で実装することもできます。このためのコードを記述する必要はありません(少し面倒です。最も簡単な方法は、BeanPropertyRowMapperソースコードをコピーして変更することです)。誰もが一般的な意味を理解しています。
  2. BeanPropertyRowMapperのソースコードを実際にコピーして、直接継承しないようにという質問もあります。最初は同じように考えましたが、プロパティはプライベート、プライベート、プライベートのいずれかであり、継承は効果がありません。

おすすめ

転載: juejin.im/post/7117270478569340959