hmk run dev

크레브 dev 본문

company

크레브 dev

hmk run dev 2022. 3. 24. 14:44

비즈니스 로직

1. 구글 소셜 로그인

2. 유튜버 인증(크레브 어드민에서 수락해주는 건가??) 

- 유튜버 인증은 로그인 시점부터 정해짐 

> 버튼 자체에 조건부 렌더링이 걸려서 인증, 비인증 사용자의 버튼 자체가 다름! 

3. addCreve에서 협찬 등록

4. creve에서 협찬 요청 > /applyproduct/apply/sendmail/creator Controller에서 리마인드 메시지 발송 (sendKakaoAsync)


- pc, mobile  UserAgent를 구분해서 view를 보여주는 것 같음.

> 계속 유지할 프로젝트라면 반응형으로 구현이 시급한 것 같습니다..!

 

 

- 파일 구조

java : controller, service 역할적 구분이 아닌 페이지 기반으로 분리해

contoller, service, dto, dao 등 필요한 파일을 모아놓음

front : 자바 파일과 마찬가지

tiles : tiles-default에 구조가 잡혀 있다. tilesBase는 pc > layout > layout.js로 되어있다. (추후 글로벌 함수 글로벌 css 같은 것들을 넣어놓고 개별로 쓰인 코드 리팩터링)

 

DB table( 테이블명 중 'tb_' 생략 )

content - 메인 페이지 콘텐츠 테이블 

user - 회원들 정보 저장

comment -  댓글 저장, TYPE으로 어디에 등록한 댓글인지 구분하는 것 같음

 

협찬요청 협찬 요청 시

tp_product - 협찬 물품 목록

- PRODUCT_STATE : 9(검수 중), 11(모집 중)

- TOTAL_CNT : 아마 모집 최대 인원? 인 것 같다

- CURRENT_CNT  : TOTAL_CNT 보다 작아야 협찬 리스트 목록에 뜬다.

> 협찬 요청 시 CNT++

- APPLY_DATE_ST : 모집 시작 날짜

- APPLY_DATE_END :  모집 마감 날짜

 

tb_apply_product - 협찬 요청 시 해당 물품 정보와 신청한 요청한 유저의 정보가 들어감( tp_product, many to one )

- cancel_YN : 협찬 취소 가능

- APPLY_STATE : 

- RESULT_STATE : 협찬 결과 상태 값인 듯?? 어드민에서 처리하는 건가?

 

 

tb_click_all - 액션 로그(모든 유저의 움직임 저장)

 

tb_product_basket - 목록

- 클릭 시 INSERT

- 재 클릭 시 DEL_YN = 'N'으로 수정

 

tb_order - 결제주문


개인적으로 생각하는 개선사항

일단 제한된 시간 안에 빠르게 서비스를 배포하고 프로젝트를 마감해주신 분께 존중의 박수를 보내드립니다 :)

남이 작성한 코드는 비판하기 쉽고 저 또한 아직 미천한 실력이지만 며칠 동안 훑어보면서 크레브에 프로젝트에 대한 개선사항을 적어 봤습니다.


주석 꼼꼼히  - DTO 등에 포함 이유 새로운 분이 봐도 이해할 수 있게(작성자 작성 or 추가 날짜 기재 포함)


슬라이더나 세부 콘텐츠가 바뀌는 경우 or 카테고리 선택을 할 뿐인데 페이지가 다시 로드되고 스크롤 또한 맨 위로 이동 

> 유저 경험과 리소스 모두 낭비

> 제이쿼리나 순수 자바스크립트를 이용한 empty(), append()를 활용해 페이지 수정 추천


Constants.java 파일을 만들고 키 or 코드들 모아서 관리(secretKey 등은 properties 파일에)

ex) s3키, 주요 상태 코드(결제상태 같은), oauth키 등등.......  

 

아래와 같은 Constants.java 파일로 코드 관리

 

package com.workerman.config;

public class Constants {

	/****************** BEGIN profile ******************************************************************/
    public static final String SPRING_PROFILE_DEVELOPMENT = "dev";
    public static final String SPRING_PROFILE_STAGE = "stage";
    public static final String SPRING_PROFILE_LOCAL = "local";
    public static final String SPRING_PROFILE_PRODUCTION = "prod";
    /****************** END profile ******************************************************************/

    /****************** BEGIN AWS ******************************************************************/
	public static final long ACCESS_TOKEN_VALIDITY_SECONDS = 300*60*60;
    public static final String HEADER_STRING = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";

    public static final String ERROR_EMPTY_KEY = "조회를 위한 key값이 누락 됐습니다.";

    /* S3 CONSTANTS */
    // TODO : 명칭 정리 필요함. properties 처리...
    public final static String WORK_UPLOAD_BUCKET_NAME = "upload-key";
    public final static String WORK_ACCESSKEY = "access_key";
    public final static String WORK_SECRETKEY = "secret-key";
    /****************** BEGIN END ******************************************************************/

    /****************** Begin Image Type ******************************************************************/
    public final static String IMG_TYPE_SAMPLE = "SAMPLE";	// sample
    public final static String IMG_TYPE_CUSTOMER = "CUSTOMER";	// 고객사업자등록증사본
    //public final static String IMG_TYPE_CUSTOMER_BRANCH = "CUSTOMER_BRANCH"; // 고객지점사업자등록증사본
    public final static String IMG_TYPE_PARTNER_BUSS = "IMG_TYPE_PARTNER_BUSS";	// 사업자번호 사본
    public final static String IMG_TYPE_PARTNER_ACCT = "PARTNER_ACCT";	// 파트너 통장사본

    public final static String IMG_TYPE_CUSTOMER_BUSS = "IMG_TYPE_CUSTOMER_BUSS";	// 사업자번호 사본
    public final static String IMG_TYPE_CUSTOMER_BRANCH_BUSS = "IMG_TYPE_CUSTOMER_BRANCH_BUSS";	// 사업자번호 사본
    public final static String IMG_TYPE_CUSTOMER_BRANCH_ACCT = "IMG_TYPE_CUSTOMER_BRANCH_ACCT";	// 통장 사본
    public final static String IMG_TYPE_VENDOR_BUSS = "IMG_TYPE_VENDOR_BUSS"; // 거래처 사업자등록증사본
    public final static String IMG_TYPE_VENDOR_ACCT = "IMG_TYPE_VENDOR_ACCT"; // 거래처 통장사본

    public final static String IMG_TYPE_MATERIAL = "IMG_TYPE_MATERIAL"; // 자재 이미지
    public final static String IMG_TYPE_MATERIAL_REQ = "IMG_TYPE_MATERIAL_REQ"; // 자재 요청 이미지

    public final static String IMG_TYPE_DISBURSEMENT = "IMG_TYPE_DISBURSEMENT"; // 지출결의 영수증 이미지
    public final static String IMG_TYPE_EXPENSES = "IMG_TYPE_EXPENSES"; // 비용처리 증빙 이미지
    public final static String IMG_TYPE_PAYMENT = "IMG_TYPE_PAYMENT"; // 매출관리 증빙 이미지
    public final static String IMG_TYPE_MATERIAL_PCS = "IMG_TYPE_MATERIAL_PCS"; //구매거래명세서 이미지

    public final static String IMG_TYPE_DAILY_REPORT = "IMG_TYPE_DAILY_REPORT";	// 작업일지 이미지
    public final static String IMG_TYPE_WORK_REG = "IMG_TYPE_WORK_REG";	// 작업등록 이미지

    public final static String IMG_TYPE_ADMIN = "IMG_TYPE_ADMIN";	// 어드민프로필 이미지
    public final static String IMG_TYPE_INSPECTION_FLOOR = "IMG_TYPE_INSPECTION_FLOOR";	// 점검 도면 이미지

    /****************** End Image Type ******************************************************************/

    /****************** BEGIN 이벤트 처리 메시지 ******************************************************************/
    public static final String EVENT_DELETE_SUCCESS = "삭제 됐습니다.";
    public static final String EVENT_SAVE_SUCCESS 	= "저장되었습니다.";
    public static final String EVENT_UPDATE_SUCCESS = "수정 됐습니다.";
    public static final String EVENT_SELECT_SUCCESS = "조회 됐습니다.";
    /****************** END 이벤트 처리 메시지 ******************************************************************/

    /****************** BEGIN return code ******************************************************************/
    public static final String RETURN_SUCCESS = "00";
    public static final String RETURN_DUPLICATE = "98";	 
    public static final String RETURN_ERROR = "99";
    /****************** END return code ******************************************************************/

    /****************** BEGIN init code vlaue ******************************************************************/
    public static final String STATE_NORMAL = "00";
    public static final String DELETED = "Y";
    public static final String NOT_DELETED = "N";
    /****************** END init code vlaue ******************************************************************/

    /****************** BEGIN req stat : 자재요청상태 ******************************************************************/
    public static final String REQ_STAT_REG = "01";	// 등록
    public static final String REQ_STAT_PCS = "02";	// 구매
    public static final String REQ_STAT_OUT = "03";	// 출고
    public static final String REQ_STAT_READY = "04";	// 중비오나료

    /****************** END req stat ******************************************************************/

    /****************** BEGIN pcs stat : 구매요청상태 ******************************************************************/
    public static final String PCS_STAT_INPUT 		= "01";	// 등록
    public static final String PCS_STAT_REQ_PAY 	= "02";	// 결제요청
    public static final String PCS_STAT_REQ_COMP 	= "03";	// 결제완료
    public static final String PCS_STAT_INCOME 		= "04";	// 입고
    /****************** END pcs stat ******************************************************************/

    /****************** BEGIN 입출고타입 code ******************************************************************/
    public static final String BOUND_TYPE_IN = "01";
    public static final String BOUND_TYPE_OUT = "02";
    /****************** END 입출고타입 code ******************************************************************/

    /****************** BEGIN 결제범위 code ******************************************************************/
    public static final String PAY_SCOPE_ALL = "01";
    public static final String PAY_SCOPE_PART = "02";
    /****************** END 입출고타입 code ******************************************************************/

    /****************** BEGIN 파트너 구분 text ******************************************************************/
	public static final String PARTNER_TYPE_01 = "01";// 개인
	public static final String PARTNER_TYPE_02 = "02";// 법인
	public static final String PARTNER_TYPE_03 = "03";// 개인사업자
	public static final String PARTNER_TYPE_99 = "99";// 기타
	/****************** END 작업상태 text ******************************************************************/
}

tiles에 메인 템플릿을 지정해 자주 쓰이는 글로벌 함수 등을 모듈화 해놓기(tiles-default)

>  아래처럼 자주 쓰이는 날짜 포맷, 금액 포맷, ajax요청, 파일 업로드 요청 등의 함수들을 모듈화 해서 사용

/* common utils script */
var Utils = {
	// is not empty
	isNotEmpty: function (param) {
		if (typeof param === "object") {
			if (param == undefined || param == "" || param == null || param.length == 0) {
				return false;
			}
			else {
				return true;
			}
		}
		else {
			if (param == undefined || param == "" || param == null) {
				return false;
			}
			else {
				return true;
			}
		}
	},
	// is empty
	isEmpty: function (param) {

		if (param == undefined || param == null) {
			return true;
		}

		if (typeof param === "object") {
			if (param == undefined || param == "" || param == null || param.length == 0) {
				return true;
			}
			else {
				return false;
			}
		}
		else {
			if (param == undefined || param == "" || param == null) {
				return true;
			}
			else {
				return false;
			}
		}
	},
	// get param
	getParamByName: function (name, uri) {
		uri = uri || window.location.href;
		name = name.replace(/[\[\]]/g, "\\$&");
		var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(uri);
		if (!results) return null;
		if (!results[2]) return "";
		return decodeURIComponent(results[2].replace(/\+/g, " "));
	},
	// replace all
	replace: function (str, trg, chg) {
		if (str == 'undefined' || str == undefined || str == null) return '';
		str = str + "";
		return str.split(trg).join(chg);
	},
	// remove all
	remove: function (str, trg) {
		if (str == 'undefined' || str == undefined || str == null) return '';
		str = str + "";
		return str.split(trg).join('');
	},
	// remove comma
	rmComma: function (str) {
		if (str == 'undefined' || str == undefined || str == null) return '';
		str = str + "";
		return str.split(',').join('');
	},
	// round
	round: function (num, st) {
		if (Utils.isEmpty(st)) return num;
		let e1 = "e+0";
		let e2 = "e-0";
		if (!Utils.isEmpty(st)) {
			e1 = "e+" + st;
			e2 = "e-" + st;
		}
		return +(Math.round(num + e1) + e2);
	},
	// call ajax
	requestAjax: function (desc, url, param, callback, asyncYn) {

		var that = this, url;
		var returnData;	// only async false return value

		console.log("★★★★★★★★★★★★★★★★★★ call ajax ★★★★★★★★★★★★★★★★★★");
		console.log("★ desc :", desc);
		console.log("★ url :", url);
		console.log("★ param :", param);
		console.log("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★");

		$.ajax({
			type: "POST",
			//dataType: "json",
			data: JSON.stringify(param),
			contentType: "application/json",
			async: asyncYn == undefined || asyncYn == null ? true : asyncYn,
			timeout: 3 * 60 * 1000,
			url: url,
			//xhrFields:{withCredentials: true},
			beforeSend: function (xhr) {
				$("#content-loader-id").show();
				xhr.setRequestHeader("Authorization", getAuthToken());
				callback && callback.beforeSend && callback.beforeSend();
			},
			success: function (response) {
				//console.log("suc!!", response);
				//console.log(JSON.stringify(response))
				returnData = response;
				//console.log("request success", returnData['CATEGORY'].length);
				//if(response.ResponseCode && response.ResponseCode.code == 104){}
				callback && callback.success && callback.success(response);
			},
			error: function (request, status, error) {
				$("#content-loader-id").hide();
				console.log("error", JSON.stringify(error));
				console.log("error", request.status);
				console.log("error", request.responseText);

				//callback && callback.error && callback.error();
				alert(desc + ' 실행중에 에러가 발생했습니다.\n관리자에게 문의하세요.');
			},
			complete: function (response) {
				$("#content-loader-id").hide();
				callback && callback.complete && callback.complete();
			}
		});
		return returnData;
	},
	// call multipart ajax
	requestMultiAjax: function (desc, url, formname, callback) {

		var that = this, url;
		var returnData;	// only async false return value

		console.log("★★★★★★★★★★★★★★★★★★ call ajax ★★★★★★★★★★★★★★★★★★");
		console.log("★ desc :", desc);
		console.log("★ url :", url);
		console.log("★ form name :", formname);
		console.log("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★");

		var frm = $('#' + formname)[0];
		var data = new FormData(frm);

		$.when(
			$.ajax({
				type: "POST",
				enctype: 'multipart/form-data',
				url: url,
				data: data,
				processData: false,
				contentType: false,
				cache: false,
				timeout: 3 * 60 * 1000,
				beforeSend: function (xhr) {
					$("#content-loader-id").show();
					xhr.setRequestHeader("Authorization", getAuthToken());
					//xhr.setRequestHeader("req_type", "ajax");
				},
				success: function (response) {
					$("#content-loader-id").hide();
					// alert('success')
					callback && callback.success && callback.success(response);
				},
				error: function (e) {
					$("#content-loader-id").hide();
					// alert('fail');
				}
			})
		).then(function (data, textStatus, jqXHR) {
			//alert( jqXHR.status ); // Alerts 200
			return 'success';
		}).fail(function (result, status, responseobj) {
			//alert('falield');
			return 'fail';
		});
		;

	},
	// call multipart ajax
	AdminrequestMultiAjax: function (desc, url, formname, callback) {

		var that = this, url;
		var returnData;	// only async false return value

		console.log("★★★★★★★★★★★★★★★★★★ call ajax ★★★★★★★★★★★★★★★★★★");
		console.log("★ desc :", desc);
		console.log("★ url :", url);
		console.log("★ form name :", formname);
		console.log("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★");

		var frm = $('#' + formname)[0];
		var data = new FormData(frm);

		$.when(
			$.ajax({
				type: "POST",
				enctype: 'multipart/form-data',
				url: url,
				data: data,
				processData: false,
				contentType: false,
				cache: false,
				timeout: 3 * 60 * 1000,
				beforeSend: function (xhr) {
					xhr.setRequestHeader("Authorization", getAuthToken());
					//xhr.setRequestHeader("req_type", "ajax");
				},
				success: function (response) {
					// alert('success')
					callback && callback.success && callback.success(response);
				},
				error: function (e) {
					alert('중복된 아이디 입니다.');
				}
			})
		).then(function (data, textStatus, jqXHR) {
			//alert( jqXHR.status ); // Alerts 200
			return 'success';
		}).fail(function (result, status, responseobj) {
			alert('중복된 아이디 입니다.');
			return 'fail';
		});
		;

	},
	// get today
	getToday: function (delimeter) {

		var changeDate = new Date();
		var y = changeDate.getFullYear();
		var m = changeDate.getMonth() + 1;
		var d = changeDate.getDate();
		if (m < 10) { m = "0" + m; }
		if (d < 10) { d = "0" + d; }
		var gubunja = delimeter || "";
		var resultDate = y + gubunja + m + gubunja + d;
		return resultDate;
	},
	// gen comma
	comma: function (num) {
		num = Utils.remove(num, ',');
		if (isNaN(num)) return "0";
		return new Intl.NumberFormat().format(num);
	},
	// buss no
	bussNo: function (val) {
		if (val == undefined || val.length != 10) return val;
		else {
			return val.substr(0, 3) + "-" + val.substr(3, 2) + "-" + val.substr(5, 5);
		}
	},
	// phone number
	phone: function (val) {
		if (val == undefined || val.length != 11) {
			return val;
		} else {
			return val.substr(0, 3) + "-" + val.substr(3, 4) + "-" + val.substr(7, 4);
		}
	},
	// json string true/false
	isJsonString: function (str) {
		try {
			var json = JSON.parse(str);
			return (typeof json === 'object');
		} catch (e) {
			return false;
		}
	},
	// nvl
	nvl: function (str, replace) {
		try {
			if (Utils.isEmpty(str)) {
				if (Utils.isEmpty(replace)) {
					return '';
				}
				else {
					return replace;
				}
			} else {
				return str;
			}
		} catch (e) {
			return str;
		}
	},
	// link button create
	linkButton: function (str) {

		try {
			if (Utils.isEmpty(str)) {
				return '';
			}
			else if (str.indexOf("http://") > -1) {
				let _link = str;
				let tmp = '<button onclick="window.open(\'' + str + '\',\'window_name\',\'height=500,location=no,status=no,scrollbars=yes\');">button</button>';
				console.log("link", tmp);
				return tmp;
			}
			else {
				return str;
			}

		} catch (e) {
			return str;
		}
	},
	// datetime
	getDatetime: function (str) {

		try {
			if (Utils.isEmpty(str)) return '';

			let date = new Date(str);
			let year = date.getFullYear();
			let month = date.getMonth() + 1;
			let dt = date.getDate();
			hh = date.getHours();
			mm = date.getMinutes();

			if (dt < 10) { dt = '0' + dt; }
			if (month < 10) { month = '0' + month; }
			if (hh < 10) { hh = '0' + hh; }
			if (mm < 10) { mm = '0' + mm; }
			return year + "-" + month + "-" + dt + " " + hh + ":" + mm;
		} catch (e) {
			return str;
		}
	},
	// date, datetime
	getDate: function (str) {

		try {
			if (Utils.isEmpty(str)) return '';
			str = Utils.remove(str, "-");
			str = Utils.remove(str, ".");
			if (str.length == 8) {
				return str.substr(0, 4) + "-" + str.substr(4, 2) + "-" + str.substr(6, 2);
			}
			else if (str.length == 12) {
				return str.substr(0, 4) + "-" + str.substr(4, 2) + "-" + str.substr(6, 2) + " " + str.substr(8, 2) + ":" + str.substr(10, 2)
			}
			else return str;
		} catch (e) {
			return str;
		}
	},		// get today
	getDayOfWeek: function (str) {
		let week = ['일', '월', '화', '수', '목', '금', '토'];
		return week[new Date(str).getDay()];
	},
	getMaskingJumin: function (str) {
		let _jumin = '';
		if (!Utils.isEmpty(str) && str.length == 7) {
			_jumin = str.substring(0, 6) + "-" + str.substring(6, 7) + "******";
		} else {
			_jumin = str;
		}
		return _jumin;
	}
}

 

 


메인 카테고리 등 주요 코드들은 DB로 관리되면 좋겠습니다.

mainCategoryList.put("PRIZEMONEY", "후원금");
mainCategoryList.put("OFFLINE", "방문체험");
mainCategoryList.put("BEAUTY", "뷰티/패션");
mainCategoryList.put("FOOD", "푸드");
mainCategoryList.put("DIGITAL", "전자제품");
mainCategoryList.put("LIFE", "생활용품");
mainCategoryList.put("CULTURE", "문화생활");
mainCategoryList.put("ETC", "기타");

controller의 코드를 최소화하고 비즈니스 로직 수행은 service가 위주로 담당하게 코드를 짰으면 좋겠다는 개인적인 생각입니다..! (컨트롤러엔 되도록이면 조건에 따른 service호출, model 등등이 있길 희망! )

> service에 여러 로직이 포함될 경우 트랜잭션 처리도 가능하기 때문...! 


RDBMS의 기능 JOIN을 사용하지 않고 DTO를 계속 넘겨주며 DB에 커넥션을 하는 코드가 많음 DB와 연결 횟수가 많아짐 > DB 부담이 높아짐

> 결론 : 여러 번의 DB 커넥션이 아닌 하나의 쿼리로 처리할 수 있는 경우가 많음 


tb_code 같은 테이블을 생성해 자주 쓰이는 값들을 코드를 따서 관리하면 좋겠습니다.

> tb_product를 예로 들어보면 CAMPAIGN_TYPE과 CAMPAIGN_LEVEL 등의 칼럼에 데이터가 VARCHAR 형태로 들어가 있는습니다.

> 이것을 tb_code에

> code_gb(코드 구분) = 'CAMPAIGN_TYPE'  / code_value(코드 값) = '01' 이런 식으로 관리해 join 해서 사용

> DB 디스크를 많이 절약 가능


DTO에 설명 주석 등이 없어 사실 상 타입제한 이외에는 기능이 없는 것 같습니다.

빠르게 개발하기 위해서 생략하셨다면 아래와 같이 CommonDao를 등록해 dto, 타입 제한없이 개발가능해 개발시간이 대폭 낮아질 것 같습니다.

 

/**
 * 데이터베이스 연결클래스
 */
@Repository("commonDao")
public class CommonDao {
	
	@Autowired 
	@Qualifier("sqlSessionTemplate")
	private SqlSession sessionTemplate;

	/**
	 * 암호화메서드
	 */
	public void encrypt(Object obj){
		if(obj instanceof EncryptionInterface){
			((EncryptionInterface)obj).encrypt();
		}
	}
	
	/**
	 * 암호화메서드
	 */
	public void encrypt(Object obj, boolean isEncrypt){
		if(isEncrypt && obj instanceof EncryptionInterface){
			((EncryptionInterface)obj).encrypt();
		}
	}
	
	/**
	 * 복호화메서드
	 */
	public void decrypt(Object obj){
		if(obj instanceof EncryptionInterface){
			((EncryptionInterface)obj).decrypt();
		}
	}
	
	/**
	 * 복호화메서드 
	 */
	public void decryptList(List<?> objectList){
		for (Object object : objectList) {
			decrypt(object);
		}
	}
	
	/**
	 * 쿼리조회 - 오브젝트리턴
	 */
//	public Object queryForObject(String qureyId){
//		
//		Object object = sessionTemplate.selectOne(qureyId);
//
//		decrypt(object);
//		
//		return object;
//	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> queryForObject(String qureyId){
		
		Object object = sessionTemplate.selectOne(qureyId);

		decrypt(object);
		
		return (Map<String, Object>)object;
	}
	
	public Object queryForObjectNoCast(String qureyId, Object obj){
		
		Object object = sessionTemplate.selectOne(qureyId, obj);

		decrypt(object);
		
		return object;
	}
	
	/**
	 * 쿼리조회 - 오브젝트리턴
	 */
//	public Object queryForObject(String qureyId, Object obj){
//		
//		encrypt(obj);
//		
//		Object object = sessionTemplate.selectOne(qureyId, obj);
//
//		decrypt(object);
//		
//		return object;
//	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> queryForObject(String qureyId, Object obj){
		
		encrypt(obj);
		
		Object object = sessionTemplate.selectOne(qureyId, obj);

		decrypt(object);
		
		return (Map<String, Object>)object;
	}
	
	public String queryForString(String qureyId, Object obj){
		
		encrypt(obj);
		
		Object object = sessionTemplate.selectOne(qureyId, obj);
		
		decrypt(object);
		
		return (String)object;
	}
	
	public int queryForInt(String qureyId, Object obj){
		
		encrypt(obj);
		
		Object object = sessionTemplate.selectOne(qureyId, obj);
		
		decrypt(object);
		
		return (int)object;
	}
	
	public float queryForFloat(String qureyId, Object obj){
		
		encrypt(obj);
		
		Object object = sessionTemplate.selectOne(qureyId, obj);
		
		decrypt(object);
		
		return (float)object;
	}
	
	/**
	 * 
	 * 쿼리조회 - 리스트 오브젝트리턴
	 */
	@SuppressWarnings("rawtypes")
	public List queryForList(String qureyId, Object obj){
		
		encrypt(obj);
		
		List<?> objectList = sessionTemplate.selectList(qureyId, obj);
		
		decryptList(objectList);
		
		return objectList; 
	}
	
	/**
	 * 쿼리조회 - 리스트 오브젝트리턴
	 */
	@SuppressWarnings("rawtypes")
	public List queryForList(String qureyId){
		
		List<?> objectList = sessionTemplate.selectList(qureyId);
		
		decryptList(objectList);
		
		return objectList; 
	}
	
	/**
	 * 암호화 - 세션템플릿 update 값 리턴
	 */
	public int update(String qureyId, Object obj){
		
		encrypt(obj, true);
		
		return sessionTemplate.update(qureyId, obj);
	}
	
	/**
     * 암호화 - 세션템플릿 insert 값 리턴
     */
	public int insert(String qureyId, Object obj){
		
		encrypt(obj, true);
		
		return sessionTemplate.insert(qureyId, obj);
	}
	
	/**
     * 암호화 - 세션템플릿 delete 값 리턴
     */
	public int delete(String qureyId, Object obj){
		
		encrypt(obj, true);
		
		return sessionTemplate.delete(qureyId, obj);
	}
	
	public int delete(String qureyId){
		return sessionTemplate.delete(qureyId);
	}

}

 

아래와 같이 dto없이 Map<String, Object>로 간단하게 사용가능

	@Autowired
	private CommonDao commonDao;
    
    /**
	 * 구매요청 조회
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public List<Map<String, Object>> listMaterialPcs(Map<String, Object> param) throws Exception{
		return (List<Map<String, Object>>)commonDao.queryForList("material_pcs.listMaterialPcs", param);
	}
	
	/**
	 * 구매요청 조회 count
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public int listMaterialPcsCnt(Map<String, Object> param) throws Exception{
		return (Integer)commonDao.queryForInt("material_pcs.listMaterialPcsCnt", param);
	}
	
	
	/**
	 * 구매요청 조회 sum price
	 * @param param
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> getMaterialPcsPriceSum(Map<String, Object> param) throws Exception{
		return (Map<String, Object>)commonDao.queryForObject("material_pcs.getMaterialPcsPriceSum", param);
	}

 

 


local, dev, prod 환경구분 & 환경에 따른 CI/CD 구축

 

아래와 같이 개발환경에 따라 properties 파일을 나누고

 

pom.xml에 profile을 나누어 관리하면 CI/CD를 구축할때 dev, prod를 편하게 나누어 관리할 수 있습니다.

<profiles>
    <profile>
        <id>local</id>
         <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <env>local</env>
        </properties>
    </profile>
    <profile>
        <id>dev</id>
        <properties>
            <env>dev</env>
            <log.level>debug</log.level>
        </properties>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <configuration>
                        <outputDirectory>/home/ubuntu/test</outputDirectory>
                        <warName>${war.file.name}</warName>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <env>prod</env>
        </properties>
            <build>
            <!-- <directory>${deploy.target.directory}</directory> -->
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <configuration>
                        <outputDirectory>/home/ubuntu/test</outputDirectory>
                        <warName>${war.file.name}</warName>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

'company' 카테고리의 다른 글

팀을 위하는 개발자란?  (0) 2024.03.30
Comments