❔ 언제 사용?
➖ Class 간 복사가 필요할 때
-. 웹개발을 하다보면 VO와 Entity 간 동일한 멤버변수를 복사하는 경우가 많이 발생한다.
-. Front단에서 입력받거나, Back에서 처리된 VO를 DB에 저장하기 위해 Entity로 옮기는(=복사하는) 경우 등
-. 그러한 경우에 각 멤버변수(=property)를 하나씩 get() -> set() 한다면, 굉장히 번거롭고 후에 유지보수하기도 불편하다.
❔ 번거롭다? 유지보수가 어렵다? 이유는?
-. 멤버변수가 많으면 많을수록 복사하기 위해 굉장히 많은 Line의 get->set 코드가 필요할 것이며,
-. 후에 변수명이 바뀌거나 변수가 추가된다면 ,해당 복사 코드에 찾아가서 수정해야 한다.
❗ 그래서 BeanUtils.copyProperties() !
-. org.springframework.beans 패키지에 있는 BeanUtils 클래스를 이용하여
다른 클래스의 동일 멤버변수 간 복사할 수 있다.
-. BeanUtils에는 copyProperties 함수 외에도 유용하게 쓰일 수 있는 함수들이 있으며,
-. 더 포괄적인 활용을 위해, Apache Commons BeanUtils같은 패키지를 활용할 수도 있다.
-. 아래는 copyProperties 3개의 오버로딩 설명.
❗ 간단한 예시 코드
@Entity
@Table(name="PERSON")
public class Person{
@Id
private Integer id;
private String name;
private Integer age;
private String email;
}
@Getter @Setter
@Alias("PersonVO")
public class PersonVO {
public PersonVO(Integer Id,String name, Integer age, String emailId, String emailAddress){
this.id = id;
this.name = name;
this.age = age;
this.emailId = emailId;
this.emailAddress = emailAddress;
this.email = emailId + "@" + emailAddress;
}
private Integer id;
private String name;
private Integer age;
private String email;
private String emailId;
private String emailAddress;
}
위와 같은 2개의 클래스가 있고,
화면에서 PersonVO 멤버변수의 모든 값을 받아서 값이 있다는 상황과 비슷하게 만들기 위해,
임의의 값으로 생성한 personVO를 만들어 아래와 같이 예시 코드를 작성하였다.
private void coppyTest(){
PersonVO personVO = new PersonVO(1, "venaCode", 7, "superLucky", "abc.com");
Person person = new Person();
BeanUtils.copyProperties(personVO, person);
}
❗ 주의해야할 점
1. copyProperties은 Reflection을 이용하여 getter setter 함수를 조회하여 구현하였기 때문에,
source(위에서 personVO)는 getter 메서드가 필수이며,
target(위에서 person)은 setter 함수가 필수다.
2. target에 있는 변수가 source 동일변수 값이 null인 경우 오류 발생한다.
1번의 경우는 getter setter 생성하여 해결한다.
2번의 경우에는 null값인 멤버변수를 무시하고 복사하고 싶은 경우가 있다. (ex: 화면에서 모든 값이 넘어오지 않을 경우) stackoverflow에 좋은 답변이 있어, 답변에 적힌 코드와 링크를 아래에 첨부한다.
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
// then use Spring BeanUtils to copy and ignore null using our function
public static void myCopyProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}
-. null값인 멤버변수(property)의 name을 구하여 ignoreProperties 매개변수에 할당하였다.
'Programming > Java' 카테고리의 다른 글
[eclipse][spring]개발 작업에 영향을 끼치는 옵션 (0) | 2022.05.26 |
---|---|
[JAVA][JUnit]자주 사용하는 Annotation (0) | 2022.03.04 |
[JAVA]JUnit5 (0) | 2022.03.04 |
[JAVA][TDD][CleanCode]자바 플레이그라운드 with TDD, 클린코드 시작 (0) | 2022.03.02 |