my batis Map 조회 결과 밑줄 을 그 어 낙타 봉 을 돌 리 는 인 스 턴 스

설정 클래스 MybatisCamelConfig 를 추가 하면 됩 니 다.

package com.fpi.notify.config;
 
import com.google.common.base.CaseFormat;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapper;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; 
import java.util.Map;
 
/**
 * mybatis  Map         
 * @author xingxing_yuan
 * @since 2020-02-18 13:47
 */
@Configuration
public class MybatisCamelConfig {
 @Bean
 public ConfigurationCustomizer mybatisConfigurationCustomizer() {
//              
  return configuration -> configuration.setObjectWrapperFactory(new MapWrapperFactory());
 }
 
 /**
  *     
  */
 static class MapWrapperFactory implements ObjectWrapperFactory {
  @Override
  public boolean hasWrapperFor(Object object) {
//     Map      
   return object instanceof Map;
  }
 
  @Override
  public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
//                
   return new CamelWrapper(metaObject, (Map) object);
  }
 }
 
 /**
  *      ;      
  */
 static class CamelWrapper extends MapWrapper {
 
  CamelWrapper(MetaObject metaObject, Map<String, Object> map) {
   super(metaObject, map);
  }
 
  /**
   * mybatis          
   *
   * @param name
   * @param useCamelCaseMapping       。yaml    map-underscore-to-camel-case=true
   * @return
   */
  @Override
  public String findProperty(String name, boolean useCamelCaseMapping) {
   if (useCamelCaseMapping) {
//      guava     ,  Map      
    return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
   }
   return name;
  }
 
 }
}
보충 지식:Springboot+Mybatis 에서 결과 집합 을 맵 으로 되 돌 릴 때 그 안의 Key 를 낙타 봉 으로 바 꾸 는 이름(2 가지 방법)
사용 필드:
my batis 를 사용 할 때 간단 한 연결 표 조회,Map 으로 받 을 때 DB 가 정의 하 는 필드 처럼 다음 student 와 유사 합 니 다.name,student_id,낙타 봉 으로 전환 되 지 않 았 지만,이 정의 하나 때문에 데이터베이스 필드 집합 을 매 핑 할 수 없습니다.그러면 무궁무진 한 javabean 이 있 을 수 있 습 니 다.전혀 방법 이 아 닙 니 다.그리고 mybatis-spring-boot 설정 문 서 를 봤 어 요.
http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/,이런 속성 이 발견 되 었 습 니 다.
mybatis.configuration.map-underscore-to-camel-case=true
속성 을 보면 map 밑줄 을 낙타 봉 으로 바 꾸 는 것 같 습 니 다.그리고 저 는 순진 하 게 이것 을 넣 으 면 맵 안의 key 를 낙타 봉 의 이름 으로 바 꾸 는 것 이 너무 순진 하 다 고 생각 했 습 니 다.어 쩔 수 없 었 습 니 다.이어서 찾 아 보 니 공식 문서http://www.mybatis.org/mybatis-3/configuration.html#properties가 이 역할 을 묘 사 했 습 니 다.다음 과 같 습 니 다.

비로소 이 속성의 작용 은 javabean 의 field 에 작용 하 는 것 이지 맵 이 아니 라 는 것 을 발견 하 였 다.map-underscore-to-camel-case 가 map 에 작용 하지 못 하 는 이상 스스로 손 을 써 야 합 니 다.그리고 두 가지 해결 방안 을 생각 했 습 니 다.
HashMap 을 계승 하여 Put 함 수 를 다시 쓰 고 my batis 가 돌아 오 는 Map 을 사용자 정의 Map 경 로 를 쓰 고 사용자 정의 Map 을 쓰 며 모든 key 내 부 를 낙타 봉 표현 식 으로 변환 합 니 다.
my batis 의 Handler 를 찾 아 Handler 를 통 해 맵 관 계 를 바 꾸 는 인터페이스 정 의 를 찾 고 인 터 페 이 스 를 계승 하거나 실현 한 다음 에 사용자 정의 전환 규칙 으로 Map 맵 맵 의 낙타 봉 전환 을 실현 합 니 다.
최종 결정 은 두 번 째 종 류 를 채택 하여 나중에 확장 하 는 것 이 편리 하 다.
다음은 두 번 째 두 가 지 를 사용 하여 프로젝트 에서 의 구체 적 인 실현 이다.
첫 번 째 실현 방법:
우선,my batis configuration 에 있 는 mapUnderscore ToCamelCase 속성 이 호출 된 곳 을 찾기 시 작 했 습 니 다.

두 곳 에서 호출 되 었 습 니 다.그리고 우 리 는 첫 번 째 호출 된 곳 을 보 았 습 니 다.이름 은 createAutomatic Mappings 이 고 map 의 맵 필드 가 만들어 져 야 합 니 다.다음 코드,커서 가 표시 되 는 곳 이 바로 호출 된 곳 입 니 다.

그리고 우 리 는 속성 이 전 달 된 후의 조작 을 살 펴 보고 metaObject.findProperty 의 실현 을 클릭 합 니 다.

이 어 object Wrapper.find Property 를 보고 인터페이스 라 는 것 을 알 게 되 었 습 니 다.그리고 우 리 는 해당 하 는 것 이 무엇 인지 확인 해 야 합 니 다.그리고 debug 는 MapWrapper 의 실현 이라는 것 을 발 견 했 습 니 다.아무런 조작 도 하지 않 고 name 으로 돌 아 왔 습 니 다.

여기까지 소스 코드 의 디 렉 터 리 구 조 를 볼 수 있 고 다음 과 같은 것 을 발견 했다.

마음속 으로 어떻게 된 일 인지 대충 알 았 으 니,구체 적 인 과정 은 아래 와 같 아야 한다.
인터페이스 Object Wrapper 를 통 해 행 위 를 정의 하고 기본 적 인 실현 이 있 습 니 다.그리고 공장 Object Wrapper Factory 인 터 페 이 스 를 통 해 Object Wrapper 인 터 페 이 스 를 만 들 고 마지막 으로 상대방 의 자동 맵 과 포장 을 합 니 다.이로써 어떻게 바 꿀 지 생각 이 났 습 니 다.
1.우선,우 리 는 먼저 MapWrapper 를 계승 하여 find Property 를 다시 쓰 고 useCamelCase Mapping 을 통 해 낙타 봉 을 사용 하 는 지 여 부 를 판단 합 니 다.

public class CustomWrapper extends MapWrapper{
 
 public CustomWrapper(MetaObject metaObject, Map<String, Object> map) {
 super(metaObject, map);
 }
 
 @Override
 public String findProperty(String name, boolean useCamelCaseMapping) {
 if(useCamelCaseMapping){
   //CaseFormat     guava ,        ,         ,pom  
   /**
    **   <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <version>24.1-jre</version>
       </dependency>
    **/
 return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,name);
 }
 return name;
 }
}
2.그 다음 에 저 희 는 인터페이스 Object Wrapper Factory 를 실현 하고 포장 공장 을 통 해 사용자 정의 포장 류 를 만 듭 니 다.hasWrapper For 를 통 해 매개 변수 가 비어 있 지 않 고 유형 이 Map 일 때 만 자신 이 확장 한 Object Wrapper 를 사용 합 니 다.

public class MapWrapperFactory implements ObjectWrapperFactory {
 @Override
 public boolean hasWrapperFor(Object object) {
 return object != null && object instanceof Map;
 }
 @Override
 public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
 return new CustomWrapper(metaObject,(Map)object);
 }
}
3.상기 작업 을 마 친 후에 우 리 는 교체 해 야 합 니 다.예전 에 기본 적 인 실현 이 필요 합 니 다.마침 my batis-spring-boot 위 에 어떻게 하 는 지 알려 주 었 습 니 다.ConfigurationCustomizer 의 bean 을 되 돌려 주 고 익명 내부 류 를 통 해 기본 적 인 MapWrapper 를 덮어 쓰 는 findProperty 함 수 를 실현 합 니 다.

@Configuration
public class MybatisConfig {
 
 @Bean
 public ConfigurationCustomizer mybatisConfigurationCustomizer(){
 return new ConfigurationCustomizer() {
 @Override
 public void customize(org.apache.ibatis.session.Configuration configuration) {
 configuration.setObjectWrapperFactory(new MapWrapperFactory());
 }
 };
 }
}
이상 의 조작 을 한 후에 우 리 는 기본 맵 맵 맵 의 포장 류 를 property 의 부분 을 찾 아 원 하 는 모습 으로 만 들 었 습 니 다.마지막 으로 properties 나 yml 에 my batis.configuration.map-underscore-to-camel-case=true 를 추가 합 니 다.Customer Wrapper 에서 우 리 는 이 를 통 해 낙타 봉 을 바 꿀 지 여 부 를 제어 합 니 다.마지막 으로 테스트 사례 를 써 서 뛰 어 본 후에 예전 에 db 의 필드 에서 밑줄 이 낙타 봉 으로 바 뀌 었 다 는 것 을 알 수 있 습 니 다.
두 번 째 실현 방법:
이런 방법 은 비교적 투기 적 이지 만 맵 집합 의 매 핑 을 간단하게 실현 할 수 있다.다음은 실현 과정 을 구체 적 으로 살 펴 보 자.PS:첫 번 째 방법 을 추천 합 니 다.공식 적 으로!)
1.우선 my batis-3.4.5.jar 의 MapWrapper 류 입 니 다.지금 저 는 이 MapWrapper 류 를 직접 복사 한 다음 에 해당 하 는 가방 을 만 듭 니 다.이 가방 경 로 는 jar 가방 에 있 는 가방 경로 와 똑 같 습 니 다(루트 경로 에 있 는:.그리고 복 사 된 이 MapWrapper 파일 을 이 가방 에 직접 붙 입 니 다.그러면 이것 이 바로 우리 자신의 MapWrapper 류 입 니 다.
2.기본 맵 맵 맵 의 포장 류 에서 property 를 찾 는 find Property 방법 을 개조 하고 자신의 맵 변환 규칙 을 추가 할 수 있 습 니 다.물론 첫 번 째 방법 처럼"인 용 된 guava 라 이브 러 리 에는 낙타 봉 을 바 꾸 는 것 이 있 습 니 다.자신 이 반복 적 으로 바퀴 를 만 들 지 않도록 pom 에 의존 을 추가 하면 됩 니 다."여기 서 우리 가 시도 한 실현 코드 는 다음 과 같다.

@Override
 public String findProperty(String name, boolean useCamelCaseMapping) {
 if (useCamelCaseMapping
    && ((name.charAt(0) >= 'A' && name.charAt(0) <= 'Z')
     || name.indexOf("_") >= 0)) {
   return underlineToCamelhump(name);
  }
  return name;
 }
 private String underlineToCamelhump(String inputString) {
  StringBuilder sb = new StringBuilder();
  boolean nextUpperCase = false;
  for (int i = 0; i < inputString.length(); i++) {
   char c = inputString.charAt(i);
   if (c == '_') {
    if (sb.length() > 0) {
     nextUpperCase = true;
    }
   } else {
    if (nextUpperCase) {
     sb.append(Character.toUpperCase(c));
     nextUpperCase = false;
    } else {
     sb.append(Character.toLowerCase(c));
    }
   }
  }
  return sb.toString();
 }
이상 의 조작 을 한 후에 우 리 는 기본 맵 맵 맵 의 포장 류 를 property 의 부분 을 찾 아 원 하 는 모습 으로 만 들 었 습 니 다.
마지막 으로 저 희 는 Mybatis 프로필 에 다음 과 같은 설정 을 추 가 했 습 니 다.

결국 customer Wrapper 에서 우 리 는 이것 을 사용 하여 낙타 봉 을 바 꾸 는 지 여 부 를 제어 한다.
물론 가장 중요 한 이 유 는 클래스 로 딩 체제 가 허용 하 는 것 을 바탕 으로 해당 하 는 클래스 로 딩 원리 와 로 딩 순 서 를 알 아 본 후에 우 리 는 알 수 있 습 니 다."WEB-INF 디 렉 터 리 에서 사용자 정의 class 류 는 이 디 렉 터 리 의 lib 아래 jar 패키지 의 클래스 로 딩 우선 합 니 다."같은 JVM 에서 두 클래스 가 같은 지 판단 하 는 근 거 는 클래스 의 전체 경로 이름과 클래스 로 더 이름 이 똑 같은 지 여부 입 니 다.
그러나 위임 메커니즘 이 존재 하기 때문에 모든 종 류 는 부모 클래스 로 더 에서 찾 을 수 있 으 면 하위 클래스 로 더 는 로드 를 시도 하지 않 습 니 다.따라서 같은 이름 의 종 류 는 한 번 만 불 러 올 수 있 습 니 다.이것 은 단일 원칙 이 라 고 합 니 다.
이상 의 my batis Map 조회 결과 에 밑줄 을 그 어 낙타 봉 을 돌 리 는 인 스 턴 스 는 바로 소 편 이 여러분 에 게 공유 한 모든 내용 입 니 다.참고 하 실 수 있 고 많은 응원 부 탁 드 리 겠 습 니 다.

좋은 웹페이지 즐겨찾기