BeanUtils.copy Properties 가 복사 집합 을 지원 하지 않 는 문 제 를 해결 합 니 다.

작업 중 에 Spring 의 도구 류 인 BeanUtils.copy Properties 를 자주 사용 하여 bean 속성 을 복사 합 니 다.이곳 의 복 제 는 얕 은 복사 에 속 합 니 다.집합 과 배열 을 복사 할 수 없습니다.본 고 는 이 도구 에 대해 약간의 테스트 를 진행 할 것 이다.
글 끝 에 집합 속성 을 복제 하 는 해결 방안 을 제시 할 것 이다.
준비 작업:테스트 준비 에 필요 한 클래스

@Data
public class Class {
    private People[] member;
    private People teacher;
    private List<People> student;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class People {
    private Integer id;
    private String name;
    private Integer age;
    private Integer sex;
}
테스트 코드:BeanUtils.copy Properties 가 복사 배열 과 집합 을 지원 하 는 지,그리고 솔 루 션 이 있 는 지 테스트 합 니 다.

public static void main(String[] args) {
 //        
 People[] member = new People[3];
 member[0] = new People(1, "  ", 30, 1);
 member[1] = new People(2, "  ", 15, 1);
 member[2] = new People(3, "  ", 15, 1);
 People[] member1 = new People[]{};
 BeanUtils.copyProperties(member, member1);
 System.out.println("        :" + (member1.length == 0 ? false : true));
 //   List   (Map     ,   )
 List<People> student = new ArrayList<>();
 student.add(member[1]);
 student.add(member[2]);
 List<People> student1 = new ArrayList<>();
 BeanUtils.copyProperties(student, student1);
 System.out.println("BeanUtils.copyProperties      List:" + (student1.isEmpty() ? false : true));
 //   JSON    List   (    List,   Map              ,         ,    )
 student1 = JSON.parseArray(JSON.toJSONString(student), People.class);
 System.out.println("  JSON    List:" + student1);
 System.out.println("  JSON       :" + (student.get(0) != student1.get(0) ? true : false));
 //        
 Class source = new Class();
 source.setMember(member);
 source.setTeacher(member[0]);
 source.setStudent(student);
 Class target = new Class();
 BeanUtils.copyProperties(source, target);
 System.out.println("BeanUtils.copyProperties     :" + (source.getMember() != target.getMember() ? true : false));
}
테스트 결과
배열 복사 가능 여부:false
BeanUtils.copy Properties List:false 를 복사 할 수 있 습 니까?
JSON 도 구 를 통 해 List:[People(id=2,name=반장,age=15,sex=1),People(id=3,name=학생,age=15,sex=1)]을 복사 합 니 다.
JSON 도 구 를 통 해 깊이 복사 할 지 여부:true
BeanUtils.copy Properties 깊이 복사 할 지 여부:false
List 에 대한 복 제 는 JSON 도 구 를 통 해 하 는 것 을 제외 하고 가장 간단 한 것 은 집합 속성 을 순환 적 으로 복제 하 는 것 이다.다음은 두 가지 방법의 효율 을 측정 한다.

public static void main(String[] args) {
 int count = 1;
 System.out.println("      :" + count);
 List<People> source = new LinkedList<>();
 List<People> target = new LinkedList<>();
 long start;
 for (int i = 0; i < count; i++) {
     source.add(new People(1, "ly", 25, 1));
 }
 
 start = System.nanoTime();
 target = JSON.parseArray(JSON.toJSONString(source), People.class);
 System.out.println("JSON:" + (System.nanoTime() - start));
 
 start = System.nanoTime();
 for (int i = 0; i < count; i++) {
     People p = new People();
     BeanUtils.copyProperties(source.get(i), p);
     target.add(p);
 }
 System.out.println("BeanUtils.copyProperties" + (System.nanoTime() - start));
}
count=1,10,100,1000,10000,100000 의 결 과 를 각각 테스트 합 니 다.함께 실행 하 는 데 영향 을 미 치 는 것 을 방지 하기 위해 매번 한 가지 복제 방법의 한 가지 상황 만 테스트 하고 총 12 회 집행 한다.비 교 를 통 해 JSON 을 통 해 BeanUtils 보다 속성 이 빠 르 고,
테스트 데이터 길이:1
JSON:154767336
Bean:275182853
테스트 데이터 길이:10
JSON:165678435
Bean:275301421
테스트 데이터 길이:100
JSON:167937206
Bean:328461161
테스트 데이터 길이:1000
JSON:187832969
Bean:315815289
테스트 데이터 길이:10000
JSON:297461312
Bean:362763360
테스트 데이터 길이:100000
JSON:562035707
Bean:5815319343
복사 List,Map 을 다음 과 같이 해결 합 니 다.

public static <T> List copyList(List<T> list) {
    if (CollectionUtils.isEmpty(list)) {
        return new ArrayList();
    }
    return JSON.parseArray(JSON.toJSONString(list), list.get(0).getClass());
}

public static Map<String, Object> copyMap(Map map) {
    return JSON.parseObject(JSON.toJSONString(map));
}
BeanUtils.copy Properties 의 용법 과 장단 점
프로필
BeanUtils 는 자바 반사 와 자성 API 에 대한 포장 을 제공 합 니 다.그 주요 목적 은 반사 체 제 를 이용 하여 자바 빈 의 속성 을 처리 하 는 것 이다.자바 빈 은 보통 대량의 속성 을 포함 하고 있 으 며,많은 경우 자바 빈 에 대한 처리 로 인해 대량의 get/set 코드 가 쌓 여 코드 길이 와 읽 기 코드 의 난이 도 를 증가 시 켰 다 는 것 을 알 고 있 습 니 다.
용법
BeanUtils 는 이 가방 에서 자주 사용 하 는 도구 류 로 copy Properties()방법 만 소개 합 니 다.이 방법 은 다음 과 같이 정의 합 니 다.
자바 코드

public static void copyProperties(java.lang.Object dest,java.lang.Object orig)   
throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException 
만약 에 똑 같은 속성 을 가 진 자바 빈 이 두 개 있다 면 하 나 는 Struts 의 PO 대상(영구적 대상)과 해당 하 는 ActionForm 이다.예 를 들 어 Teacher 와 TeacherForm 이다.
저 희 는 Action 에서 Action Form 에서 PO 대상 을 구성 합 니 다.전통 적 인 방식 은 다음 과 같은 문 구 를 사용 하여 속성 에 대해 하나씩 할당 하 는 것 입 니 다.

//  TeacherForm   
TeacherForm teacherForm=(TeacherForm)form;   
  
//  Teacher     
Teacher teacher=new Teacher();   
  
//     
teacher.setName(teacherForm.getName());   
teacher.setAge(teacherForm.getAge());   
teacher.setGender(teacherForm.getGender());   
teacher.setMajor(teacherForm.getMajor());   
teacher.setDepartment(teacherForm.getDepartment());   
  
//   Teacher         
HibernateDAO.save(teacher);  
그리고 BeanUtils 를 사용 한 후에 코드 가 크게 바 뀌 었 습 니 다.다음 과 같 습 니 다.

//  TeacherForm   
TeacherForm teacherForm=(TeacherForm)form;   
  
//  Teacher     
Teacher teacher=new Teacher();   
  
//     
BeanUtils.copyProperties(teacher,teacherForm);   
  
//   Teacher         
HibernateDAO.save(teacher);  
Teacher 와 TeacherForm 사이 에 이름 이 다른 속성 이 존재 한다 면 BeanUtils 는 이러한 속성 을 처리 하지 않 고 프로그래머 가 수 동 으로 처리 해 야 합 니 다.
예 를 들 어 Teacher 는 modifyDate(이 속성 은 마지막 수정 날 짜 를 기록 합 니 다.사용자 가 인터페이스 에 입력 할 필요 가 없습니다)속성 을 포함 하고 TeacherForm 은 이 속성 이 없 으 면 위 코드 의 copy Properties()에 한 마디 더 추가 합 니 다.

teacher.setModifyDate(new Date());  
어 때,편 하지?BeanUtils 를 제외 하고 Property Utils 라 는 도구 류 도 있 습 니 다.copy Properties()방법 도 제공 합 니 다.역할 은 BeanUtils 의 동명 방법 과 매우 비슷 합 니 다.주요 한 차이 점 은 후자 가 유형 전환 기능 을 제공 하 는 것 입 니 다.즉,두 자바 빈 의 동명 속성 이 서로 다른 유형 임 을 발견 하면 지원 하 는 데이터 유형 범위 내 에서 전환 하 는 것 입 니 다.전 자 는 이 기능 을 지원 하지 않 습 니 다.하지만 속도 가 더 빨 라 질 겁 니 다.
BeanUtils 가 지원 하 는 변환 형식 은 다음 과 같 습 니 다.

* java.lang.BigDecimal   
* java.lang.BigInteger   
* boolean and java.lang.Boolean   
* byte and java.lang.Byte     
* char and java.lang.Character    
* java.lang.Class   
* double and java.lang.Double    
* float and java.lang.Float
* int and java.lang.Integer   
* long and java.lang.Long   
* short and java.lang.Short   
* java.lang.String   
* java.sql.Date   
* java.sql.Time   
* java.sql.Timestamp  
여기 서 주의해 야 할 것 은 java.util.Date 는 지원 되 지 않 으 며,하위 클래스 인 java.sql.Date 는 지원 되 지 않 습 니 다.따라서 대상 이 시간 형식의 속성 을 포함 하고 변환 되 기 를 원할 때 는 반드시 java.sql.Date 형식 을 사용 해 야 합 니 다.그렇지 않 으 면 변환 할 때 argument mistype 이상 을 알려 줍 니 다.
장단 점
Apache Jakarta Commons 프로젝트 는 매우 유용 하 다.나 는 많은 다른 항목 에서 각종 유행 하 는 comons 구성 요 소 를 직접 또는 간접 적 으로 사용 한 적 이 있다.그 중의 강력 한 구성 요 소 는 바로 BeanUtils 이다.나 는 BeanUtils 를 사용 하여 local 실체 bean 을 대응 하 는 value 대상 으로 바 꾸 는 방법 을 설명 할 것 이다.

BeanUtils.copyProperties(aValue, aLocal)  
위의 코드 는 aLocal 대상 에서 aValue 대상 으로 속성 을 복사 합 니 다.그것 은 상당히 간단 하 다!이것 은 local(또는 대응 하 는 value)대상 이 몇 개의 속성 이 있 든 지 간 에 복사 만 할 수 있 습 니 다.우 리 는 local 대상 에 100 개의 속성 이 있다 고 가정 합 니 다.
위의 코드 는 최소 100 줄 의 지루 하고 오류 가 발생 하기 쉬 우 며 반복 되 는 get 과 set 방법 을 입력 하지 않 아 도 됩 니 다.이거 대 박이다!너무 강해!너무 쓸모 가 있어!
지금 또 하나의 나 쁜 소식 이 있다.BeanUtils 를 사용 하 는 비용 은 놀 라 울 정도 로 비싸다!저 는 간단 한 테스트 를 했 습 니 다.BeanUtils 는 데 이 터 를 추출 하고 해당 하 는 value 대상(수 동 으로 get 과 set 방법 을 호출)으로 복사 하 며 직렬 화 를 통 해 원 격 클 라 이언 트 로 돌아 가 는 시간 을 합 쳤 습 니 다.그 러 니 이런 위력 을 조심해 야 해!
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기