[본 글은 '신인인재창출식' 이벤트에 참여하였으며, 함께 너겟창업의 길을 함께 시작하겠습니다.]
1. 이 글의 핵심 내용
- BeanPropertyRowMapper가 엔티티 클래스를 캡슐화하는 데 자동으로 도움이 되는 이유에 대해 자세히 알아보세요.
- BeanPropertyRowMapper가 매핑을 위해 멤버 변수와 열 필드를 식별하는 방법.
- 필드 낙타 케이스 매핑이 재현되지 않는 현상과 해결 방법.
2. BeanPropertyRowMapper 매핑 원리
- 변수 이름은 필드 이름과 정확히 동일하며 매핑이 자동으로 수행됩니다.
- CamelCase 매핑.
1. 변수 이름은 필드 이름과 동일합니다(코드 데모)
-
다음과 같이 먼저 테이블을 준비합니다.
-
엔티티 클래스 코드:
@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; }
-
암호:
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. 카멜 케이스 매핑(오류 재현)
-
표는 위와 같습니다.
-
엔티티 클래스가 카멜 케이스로 변경됩니다(id 제외):
@Data @AllArgsConstructor @NoArgsConstructor public class CfgInfo { private Integer id; private String cfgNam; private String cfgTyp; private String cfg010; private String cfg020; }
-
jdbcTemplate 코드는 변경되지 않고 다시 실행 됩니다 . 일부 매핑은 성공했고 일부 매핑은 실패했습니다. 구체적인 이유는 아래의 기본 소스 코드 분석을 참조하세요.
3. BeanPropertyRowMapper의 기본 원칙
1. BeanPropertyRowMapper 초기화 소스 코드
- 소스 코드로 직접 클릭:
2. BeanPropertyRowMapper 매핑 소스 코드
작은 지식 포인트 삽입: jdbc 메타데이터 관련 블로그
4. 험프 매핑 문제 해결
1. 위 (hump mapping method) 코드의 이유를 설명하시오.
- 이제 위의 (hump mapping 방식) 코드의 문제점을 설명하자면, cfg010과 cfg020은 mapping이 되지 않고,
- 첫째, 모든 소문자 는 여전히 cfg010이고 cfg020은 문제가 없습니다.
- 둘째, hump는 밑줄로 대체되어 결과적으로 tm 번호를 수행할 수 없으므로 no와 같습니다.
- 그런 다음 필드 CFG_010, CFG_020, 여기에 있는 모든 공백이 제거되고 소문자 cfg_010, cfg_020이 여기에 해당할 수 있으므로 매핑되지 않고 null입니다.
2. 솔루션
1. 필드명 사양
- 숫자로 이상한 일을하지 마십시오. 역겨운 사람들, 진짜 고비를 표준화하십시오.
2. 별칭을 사용하는 SQL 문
3. BeanPropertyRowMapper를 상속하고 내부에 underscoreName 메소드를 다시 작성하십시오.
-
내부의 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 구현
- 매핑 관계에 대한 매퍼를 직접 구현할 수도 있으며 이를 위한 코드를 작성할 필요가 없으며(조금 번거롭지만 가장 쉬운 방법은 BeanPropertyRowMapper 소스 코드를 복사하여 변경하는 것입니다) 일반적인 의미를 모두가 이해합니다.
- 어떤 사람들은 BeanPropertyRowMapper의 소스 코드가 실제로 복사된 것이지 직접 상속하지 않느냐고 묻습니다.처음에는 같은 생각을 했지만 그 안에 있는 속성은 private이거나 private이거나 private이고 상속이 영향을 미치지 않습니다.