개발 창고/Java

[Nexacro] DataSet to Class

로이제로 2023. 1. 27. 22:00
반응형
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nexacro.java.xapi.data.DataSet;

public class DataSetToObject {
    private static final Logger logger = LoggerFactory.getLogger(DataSetToObject.class);
    
    /**
     * DataSet를 Class 데이터 목록으로 변환
     * @param dsList  변환할 넥사크로 데이터 셋
     * @param clazz   변환 결과로 전달될 클래스
     * @return 변환된 결과 목록
     */
    @SuppressWarnings("rawtypes")
    public static <T> List<T> convert(DataSet dsList, Class<T> clazz){
        List<T> result = new ArrayList<>();    // 전달된 제너릭 기준으로 반환할 목록을 담을 List
        
        try{
            // Cond. DataSet이 없거나 데이터가 없는 경우 null
            if(dsList == null || dsList.getRowCount() == 0)    return null;
            
            // Step. 각 Row별 데이터 세팅
            for(int nRow = 0; nRow < dsList.getRowCount(); nRow++){
                logger.debug(String.format("############################# ROW %d #############################", nRow + 1));
                
                // Step. 기존 클래스의 정의된 생성자를 활용하여 신규 인스턴스 생성
                T vo = clazz.getDeclaredConstructor().newInstance();
                Class aClass = vo.getClass();
                
                // Step. 전달된 class의 클래스에서 선언된 Field 항목들을 기준으로 데이터 입력
                for(Field field : aClass.getDeclaredFields()){
                    String fieldName = field.getName();    // 선언된 필드의 명
                    
                    // Cond. 전달된 데이터 셋에 전달된 클래스의 필드와 동일한 명이 있는 경우
                    if(dsList.getColumn(fieldName) != null){
                        Object value = dsList.getObject(nRow, fieldName);    // 데이터셋에서 각 Row별 값 추출
                        field.setAccessible(true);                           // Lombok의 경우 Getter/Setter 사전에 지정되지 않아 등록되 않으므로
                        
                        // Cond. 전달된 클래스의 필드가 java.sql.Date 타입인 경우
                        if(field.getType() == java.sql.Date.class){
                            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                            if(value == null)    field.set(vo, null);
                            else                 field.set(vo, new java.sql.Date(formatter.parse(String.valueOf(value)).getTime()));
                        
                        // Cond. 전달된 클래스의 필드가 java.util.Date 타입인 경우
                        } else if(field.getType() == java.util.Date.class){
                            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                            if(value == null)    field.set(vo, null);
                            else                 field.set(vo, formatter.parse(String.valueOf(value)));
                        
                        // Cond. 전달된 클래스의 필드가 java.lang.Boolean 타입인 경우
                        } else if (field.getType() == Boolean.class){
                            if(value == null)    field.set(vo, null);
                            else                 field.set(vo, value.equals("true"));
                        
                        // Cond. 그 외
                        } else {
                            field.set(vo, value);
                        }
                    }
                }
                result.add(vo);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        
        return result;
    }
}

 넥사크로 개발 중에 nexacro-core를 import 하기에는 본격적인 것 같아 DataSet을 전달받은 Class의 목록으로 변환하도록 작성해 보았습니다.

 

사용 방법은 아래와 같습니다.

List<Product> list = DataSetToObject.convert(dsList, Product.class);
반응형