[2024] 마이데이터 운영에서 배운 소소한 팁들

김희주·2024년 7월 3일
0

개발일지

목록 보기
11/11
post-thumbnail

1. 'A,B,C,D,E,...' 형식으로 데이터가 저장된 sql에서 map으로 꺼내기

SELECT CASE WHEN prd IS NOT NULL THEN REGEXP_SUBSTR(prd, '[^,]+', 1, 1) ELSE '' END AD TEXT1
, CASE WHEN prd IS NOT NULL THEN REGEXP_SUBSTR(prd, '[^,]+',1,2) ELSE '' END AS TEXT2
, CASE WHEN prd IS NOT NULL THEN REGEXP_SUBSTR(prd, '[^,]+',1,3) ELSE '' END AS TEXT3
,CASE WHEN prd IS NOT NULL THEN REGEXP_SUBSTR(prd, '[^,]+',1,4) ELSE '' END AS TEXT4
from TABLE
SELECT REGEXP_SUBSTR(REPLACE((SELECT PRD FROM TABLE WHERE ID = ''),
' ',''),'[^,]+', '1', LEVEL) AS PRD
FROM DUAL
WHERE 1=1
CONNECT BY INSTR(REPLACE((SELECT PRD FROM TABLE WHERE ID = ''),' ',''),',',1,LEVEL-1)>0;

2. SELECT 1 이라는 표현을 사용하는 이유

SELECT 
	1
FROM 
	TABLE
WHERE
	TABLE_CONDITION_DATE BETWEEN SYSDATE-1 AND SYSDATE-7
    AND ROWNUM <=1;

SELECT 1을 사용하는 이유 : WHERE절 조건을 만족하는지 유무를 출력.
ROWNUM <=1을 사용하는 이유 : 다건 조회로 성능 저하되는 현상을 방지.

  • 활용
SELECT 
	CASE
    	WHEN EXISTS (
    SELECT 
        1
    FROM 
        TABLE
    WHERE
        TABLE_CONDITION_DATE BETWEEN SYSDATE-1 AND SYSDATE-7
        AND ROWNUM <=1
        ) THEN 'Y'  
        ELSE 'N'

3. 2와 비슷. 데이터가 있는지 여부. CASE WHEN

SELECT 
		CASE WHEN COUNT (*) > 0 
        	THEN 'Y'
            ELSE 'N'
        	AS 'IS_YN'
            END,
        '수학' AS KIND,
        '1' AS SCORE
FROM TABLE; 

4. 어떤 컬럼의 값이 특정 조건을 충족할때는 최상위 순서로 올릴 때

SELECT * FROM TABLE
		WHERE OPTION = '1' THEN 3 ELSE 0 DESC, DATE;

5. MERGE INTO 사용시 DAUL 사용해 조건 입력

MERGE INTO table_a
USING DAUL 
ON (aColumn = #{})
WHEN MATCHED THEN
UPDATE 
SET bColumn = #{}
, cColumn = #{}
, dColumn = #{}
WHEN NOT MATCHED THEN
INSERT
(bColumn
, cColumn
, dColumn
)
VALUES
(
#{}
, #{}
, #{}
)

6. 조건 있는 쿼리 성능 향상

SELECT * FROM TABLE 
WHERE (REPLACE(column_b, '-', '') IN (SELECT column_c 
										FROM TABLE 
                                        WHERE column_d)
AND column_a LIKE '%조건%')

를 튜닝하면

SELECT * FROM TABLE 
WHERE (column_a LIKE '%조건%'
AND REPLACE(column_b, '-', '') IN (SELECT column_c 
										FROM TABLE 
                                        WHERE column_d))

7.

puvlic static void setNullToDefault(Object dto) thriws Exception {
		
        Class<?> clazz = dto.getClass();
        for(Field field : clazz.getDeclaredFields()) {
        	field.setAccessible(true);
            
            Class<?> fieldType = field.getType();
            
            //@ProjectSpecilaValidation 어노테이션이 없다면 널처리를 하지 않는다.
            if(!field.isAnnotationPresent(LocaValidation.class)) {
            	continue;
            }
            ProjectSpecilaValidation v = field.getAnnotation(ProjectSpecilaValidation.class);
            
            //required가 true인 것만 널처리를 한다.
            if(!ProjectSpecilaValidation.required()) {
            	continue;
            }
        }
        
        if(fieldType == BigDecimal.class) {
        	if(field.get(dto) == null) {
            	foeld.set(dto, "");
            }
        } else if (fieldType == Long.class) {
        	if(field.get(dto) == null) {
            	field.set(dto, new Long(0);
            }
        } else if (fieldType == Integer.class) {
         	if(field.get(dto) == null) {
            	field.set(dto, new Integer(0);
            }       		
        } else if (fieldType == Boolean.class) {
         	if(field.get(dto) == null) {
            	field.set(dto, new Boolean(false);
            }       		
        } else if (fieldType == List.class) {
         	if(field.get(dto) == null) {
            	field.set(dto, new ArrayList<>();
            } else {
            	for(int ii = 0; ii < ((List) field.get(dto)).size(); ii++) {
                setNullToDefault(((List) field.get(dto)).get(ii));
                }
            }
        } else {
        	//dot가 null이면 dto를 세팅 후 널값을 세팅한다.
            if(field.get(dto) == null) {
            	Class<?> subClazz = fieldType;
                field.set(dto,subClazz.newInstance()):
            }
            setNullToDefault(field.get(dto));
        }
        
        
}
Class Dto {
	@ProjectSpecilaValidation(required= true)
    Field field;
}

6. File 읽는 배치를 10개 가까이 만들며 배운 것들

6-1. 파일에서 for문으로 바로 아이템을 가져오기

FixedLengthFileItemReader<DTO> reader = new FixedLengthFileItemReader(path);
Dto dto = null;
reader.open(new ExecutionContext());

while((item = reader.read()!=null) {//파일 읽기
	BCMN9200DTO out = new BCMN9200DTO();
    out.setFiled1(item.getField1());
    out.setFiled2(item.getField2());
    out.setFiled3(item.getField3());
}

이렇게 read 해서 바로 item dto에 담기게 하려면 read()메서드를 구현해야한다.

public T read() throws Exception, UnexpectedInputException, ParseException {   
		if (currentItemCount >= maxItemCount) { 
        return null;  
       		 }   
        currentItemCount++;   
        T item = doRead(); 
        if(item instanceof ItemCountAware) { 
        ((ItemCountAware) item).setItemCount(currentItemCount);  
       		 }   
        
        return item;}
public class FixedLengthFileItemReader{
	protected T doRead() throws Exception {
    if(reader == null) {
    throw new ReaderNotOpenException("Reader must be open befor it can be read");
    String line = reader.readLine();
    
    if(line == null) {
    	return null;
    } else {
    	lineCount++;
        try {
        	byte[] bytes = line.getBytes(encoding);
            
            return (T)unmarshal(bytes,item);
        } catch {
        	throws new Exception("~~");
        }
    }   
    }
    }
unmarshal(byte[] bytes, Class<? extends T> item) throws Exception {
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        int depth = 0;
        try {
        ByteUtils.convertToDto(bis, item, encoding, depth);
        }
}
public static Object convertToDto(ByteArrayInputStream bis, Class<?> class, String charSet, int depth) throws IllegalAccessException, InstantiationException, IOException {
	Object dto = class.newInstance();
    for(Field field : class.getDeclaredFiels()) {
    if(field.isAnnotationPresent(FixedLengthField.class)) {	 
    FixedLengthField fixedLengthField = field.getAnnotation(FixedLengthField.class);
    field.setAccessible(true);
    switch(fixedLengthField.type()) {
    case A:
    case C:
    case AH:
    byte[] alphas = new byte[length];
    read = bis.read(digits);
    Object numValue = null;
    if(fieldType == String.class) {
    	numType = new String(digits).trim();
    }
    field.set(dto,numValue);
   break;
    }
    
    }
    }
}

AND column_a LIKE '%조건%')

profile
백엔드 개발자입니다 ☘

0개의 댓글