BeanPropertyRowMapper 매핑의 기본 원리와 낙타의 경우 필드 매핑 실패의 재발 및 해결 방법

[본 글은 '신인인재창출식' 이벤트에 참여하였으며, 함께 너겟창업의 길을 함께 시작하겠습니다.]

1. 이 글의 핵심 내용

  1. BeanPropertyRowMapper가 엔티티 클래스를 캡슐화하는 데 자동으로 도움이 되는 이유에 대해 자세히 알아보세요.
  2. BeanPropertyRowMapper가 매핑을 위해 멤버 변수와 열 필드를 식별하는 방법.
  3. 필드 낙타 케이스 매핑이 재현되지 않는 현상과 해결 방법.

2. BeanPropertyRowMapper 매핑 원리

  1. 변수 이름은 필드 이름과 정확히 동일하며 매핑이 자동으로 수행됩니다.
  2. CamelCase 매핑.

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. 위 (hump mapping method) 코드의 이유를 설명하시오.

  1. 이제 위의 (hump mapping 방식) 코드의 문제점을 설명하자면, cfg010과 cfg020은 mapping이 되지 않고,
    1. 첫째, 모든 소문자 는 여전히 cfg010이고 cfg020은 문제가 없습니다.
    2. 둘째, hump는 밑줄로 대체되어 결과적으로 tm 번호를 수행할 수 없으므로 no와 같습니다.
    3. 그런 다음 필드 CFG_010, CFG_020, 여기에 있는 모든 공백이 제거되고 소문자 cfg_010, cfg_020이 여기에 해당할 수 있으므로 매핑되지 않고 null입니다.

2. 솔루션

1. 필드명 사양

  1. 숫자로 이상한 일을하지 마십시오. 역겨운 사람들, 진짜 고비를 표준화하십시오.

2. 별칭을 사용하는 SQL 문

여기에 이미지 설명 삽입

3. BeanPropertyRowMapper를 상속하고 내부에 underscoreName 메소드를 다시 작성하십시오.

  1. 내부의 underscoreName 메서드를 다시 작성할 수 있으며, mappingFields 생성을 위한 주요 조건이 개인화됩니다.

    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의 소스 코드가 실제로 복사된 것이지 직접 상속하지 않느냐고 묻습니다.처음에는 같은 생각을 했지만 그 안에 있는 속성은 private이거나 private이거나 private이고 상속이 영향을 미치지 않습니다.

추천

출처juejin.im/post/7117270478569340959