본문 바로가기
java

스프링 AOP

by rewind 2024. 2. 7.

AOP

joinpoint : 메소드를 호출하는 시점

advice : joinpoint에서 실행되어야 할 코드

weaving : Joinpoint들을 Advice로 감싸는 작업

 

kr.or.ddit.aop 패키지 내에 ServiceLoggerAdvice 클래스 생성

 

@Aspect , @Component , @Slf4j 어노테이션 선언

 

@Component는 해당 클래스가 스프링 빈으로 생성될 수 있게 해준다.

@RequestMapping은 해당 클래스가 Controller 클래스의 기능을 수행할 수 있게 해준다.

@Controller는 위의 2가지 어노테이션을 모두 포함하고 있다.

 

**

스프링 부트 3.0(스프링 프레임워크 6.0)부터는 클래스 레벨에 @RequestMapping이 있어도 스프링
컨트롤러로 인식하지 않는다.

오직 @Controller가 있어야 스프링 컨트롤러로 인식 혹은 @RestController도 인식가능
( RequestMappingHandlerMapping에서 @RequestMapping는 인식하지 않고, @Controller만 인식)

package kr.or.ddit.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;
/*
Aspect(관점) : AOP(Aspect Oriented Programming)의 단위가 되는 횡단 관심사
- 횡단 관심사(Cross-Cutting Concern) : 핵심(core) 비즈니스 로직(삼겹살구워먹기, 빵또아의 아이스크림)과
    다소 거리가 있지만, 여러 모듈에서 공통적이고 반복적인 처리를 요구하는 내용(불판닦기, 불판교체, 빵또아의 빵)
- 횡단 관심사 분리(Separation Of Cross-Cutting Concern) : 횡단 관심사에 해당하는 
    부분(불판닦기, 불판교체, 빵또아의 빵)을 분리해서 한 곳으로 모으는 것을 의미
- Component : @Aspect와 짝궁. component-scan시 "여기 봐주세요"라는 의미
- JoinPoint : 어드바이스가 적용될 수 있는 위치
- Advice(로그출력한다) : 어떤 부가기능(불판닦기)을 언제(삼겹살을 굽기 전(Before)에) 사용할지 정의
            * 언제? 
            - Before : 조인포인트(createPost()) 전에 실행. (삼겹살을 굽기 직전에)
            - After : 조인포인트(createPost())에서 처리가 완료된 후 실행(삽겹살을 굽고 먹은 직후 실행)
            - Around : 조인포인트(createPost()) 전후에 실행(삽겹살을 굽기 직전과 먹은 직후 실행)
            - After Returning : 조인포인트(createPost())가 정상적으로 종료 후 실행
            - After Throwing : 조인포인트(createPost())에서 예외 발생 시 실행. 예외가 발생안되면 실행 안함
*/
@Slf4j
@Component
@Aspect
public class ServiceLoggerAdvice {
	//로보트에 : AOP대상(로그, 보안, 트랜잭션, 에러)
	//포인트컷 표현식. 별쩜쩜별괄호쩜쩜괄호
	//excution : 포인트컷(대상(메소드)을 선별하는 것) 지정자
	//(* : 임의의 1개의 리턴타입
	//.. : 임의의 0개 이상
	//kr.or.ddit.*..*(..) : 패키지 밑의 각각의 패키지가 있고
	//			         	그 하위에 모든 파일/패키지
	//         				각각의 메소드가 있고
	//						(..) : 모든 파라미터
	//결론 : 포인트컷에 포함된 메서드를 대상으로 그 메서드가 실행되기 전에 로그를 출력해보자
	//Before어드바이스 : 조인 포인트 전에 실행됨. 예외가 발생하는 경우만 제외하고 항상 실행됨
	// ↓↓ : kr.or.ddit.* 		=> kr.or.ddit 패키지 내의 1레벨 수준 ,
	// ↓↓ : kr.or.ddit.*..* 	=> kr.or.ddit 패키지 내의 1레벨 수준 패키지(바로 하위패키지) 내의 모든 메소드 ,
	// ↓↓ : kr.or.ddit.*..*(..) => 패키지 내의 1레벨 수준 패키지 내의 모든 메소드 , 모든 파라미터
	@Before("execution(* kr.or.ddit.*..*(..))")
	public void startLog(JoinPoint jp) {
		log.info("startLog");
		//.getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여줌. 파라미터 타입은 무엇인지 보여줌
		// kr.or.ddit.service.BoardServiceImpl.register(BoardVO)
		log.info("startLog : " + jp.getSignature());
		//.getArgs() : 전달 된 파라미터 정보를 보여줌
		// [BoardVO [boardNo=127,title=개똥이]]
		log.info("startLog : " + Arrays.deepToString(jp.getArgs()));
	}
}

 

실행 후 콘솔창에서 aop 컴포넌트 적용 확인 

 

 

Before 다음엔 After , ServiceLoggerAdvice에 메소드 추가작성

// AfterReturning 어드바이스
	// 조인 포인트가 정상적으로 종료한 후에 실행됨. 예외 발생 시 실행 안됨
	@AfterReturning("execution(* kr.or.ddit.*..*(..))")
	public void logReturning(JoinPoint jp) {
		log.info("logReturning");
		// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여줌. 
		// 파라미터 타입은 무엇인지 보여줌
		// kr.or.ddit.service.BoardService.register(BoardVO)
		log.info("logReturning : " + jp.getSignature());
	}

 

실행 후 콘솔창에서 AOP 컴포넌트 적용 확인 

 

Controller - > Service -> ServiceImpl -> Mapper ->

 

ServiceLoggerAdvice에 메소드 추가작성

	// After Throwing 어드바이스
	// 조인 포인트에서 예외 발생 시 실행. 예외가 발생 안 되면 실행 안 됨
	@AfterThrowing(pointcut="execution(* kr.or.ddit.*..*(..))", throwing="e")
	public void logException(JoinPoint jp , Exception e) {
		log.info("logException");
		// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여줌.
		// 파라미터 타입은 무엇인지 보여줌
		// kr.or.ddit.service.BoardService.register(BoardVO)
		log.info("logException : " + jp.getSignature());
		// 예외 메시지를 보여줌
		log.info("logException" + e);
	}
	
	// After 어드바이스
	// 조인 포인트 완료 후 실행 . 예외 발생이 되더라도 항상 실행 됨
	@AfterThrowing("execution(* kr.or.ddit.*..*(..))")
	public void endLog(JoinPoint jp) {
		log.info("endLog");
		//.getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여줌. 파라미터 타입은 무엇인지 보여줌
		// kr.or.ddit.service.BoardServiceImpl.register(BoardVO)
		log.info("endLog : " + jp.getSignature());
		//.getArgs() : 전달 된 파라미터 정보를 보여줌
		// [BoardVO [boardNo=127,title=개똥이]]
		log.info("endLog : " + Arrays.deepToString(jp.getArgs()));
	}

 

ServiceLoggerAdvice에 메소드 추가작성

	// ProceedingJoinPoint : around 어드바이스에서 사용함
	// 횡단관심사 - 포인트컷 대상 core메소드 - 횡단관심사
	// 스프링 프레임워크가 컨트롤 하고 있는 비즈니스로직 호출을 가로챔. 책임이 around 어드바이스로 전가됨
	// 그래서 비즈니스 메소드에 대한 정보를 around 어드바이스 메소드가 가지고 있어야 하고
	// 그 정보를 스프링 컨테이너가 around 어드바이스 메소드로 넘겨주면
	// ProceedingJoingPoint 객체로 받아서 around 어드바이스가 컨트롤 시 활용함
	@Around("execution(* kr.or.ddit.*..*(..))" )
	public Object timeLog(ProceedingJoinPoint pjp) throws Throwable {
		// 메소드 실행 직전 시간 체킹
		long startTime = System.currentTimeMillis();
		//.getArgs() : 전달 된 파라미터 정보를 보여줌
		// [BoardVO [boardNo=127,title=개똥이]]
		log.info("pjpStart : " + Arrays.toString(pjp.getArgs()));
		// 메소드 실행(createPost(ItemVO itemVO)) 실행
		Object result = pjp.proceed();
		
		// 메소드 실행 직후 시간 체킹
		long endTime = System.currentTimeMillis();
		log.info("pjpEnd : " + Arrays.toString(pjp.getArgs()));
		
		// 메소드 실행 직후 시간 - 메소드 실행 직전 시간 = 메소드 실행 시간
		log.info("time : " +pjp.getSignature().getName() + " : " + (endTime - startTime));
		
		return result;
	}

 

실행 후 콘솔 창에서 확인

 

구글차트만들기

https://developers.google.com/chart?hl=ko

 

Charts  |  Google for Developers

브라우저 및 휴대기기용 양방향 차트를 추가하기 위한 리소스를 알아보세요.

developers.google.com

 

 

kr.or.ddit.chart 하위패키지 생성

controller , mapper , service , service.impl

 

 

ChartController 생성

package kr.or.ddit.chart.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import lombok.extern.slf4j.Slf4j;

@RequestMapping("/chart")
@Slf4j
@Controller
public class ChartController {
	//요청 URI : /chart/chartMain
	@GetMapping("/chartMain")
	public String chartMain() {
		
		// forwarding
		return "chart/chartMain";
	}
}

 

 

views -> chart 폴더 생성 -> chart 폴더 내 chartMain.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<p><a href="/chart/chart01">구글차트(JSON)</a></p>
<p><a href="/chart/chart01Multi">구글멀티차트(JSON)</a></p>
<p><a href="/chart/chart02">구글차트(오라클DBMS연동)</a></p>

 

ChartController에 작성

	
	// 요청URI : /chart/chart01
	@GetMapping("/chart01")
	public String chart01() {
		//forwarding
		return "chart/chart01";
	}

 

view/chart/chart01.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// 구글 차트 라이브러리를 로딩
google.load("visualization" , "1" , {"packages" : ["corechart"] } );

//불러오는 작업이 완료되어 로딩이 되었다면 drawChart() 함수를 호출하는 콜백이 일어남 drawChart를 실행해라
google.setOnLoadCallback(drawChart);

//콜백함수
function drawChart() {
	/*
	//아작났어유
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	*/
	let jsonData = 	$.ajax({
		url : "/resources/json/simpleData.json",
		dataType : "json",
		async : false
	}).responseText;
	
	console.log("jsonData : " + jsonData);
	
}
</script>

 

static 폴더 resources내에 json 폴더 생성 -> simpleData.json 파일 생성

simpleData.json파일
{
"cols":[
{"id":"","label":"상품명","pattern":"","type":"string"},
{"id":"","label":"금액","pattern":"","type":"number"}
],
"rows":[
{"c":[{"v":"귤"},{"v":35000}]},
{"c":[{"v":"딸기"},{"v":88000}]},
{"c":[{"v":"레몬"},{"v":16500}]},
{"c":[{"v":"오렌지"},{"v":20000}]},
{"c":[{"v":"키위"},{"v":30000}]},
{"c":[{"v":"포도"},{"v":15000}]}
]
}

 

파일 열때 open with - json editor로 열면 텍스트 색상 구분가능

 

http://localhost/resources/json/simpleData.json 로 직접 열어서 아래 페이지 확인

 

http://localhost/chart/chart01로 이동해서 아래 페이지 확인(f12 개발자도구 console.log확인)

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript"
	src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// 구글 차트 라이브러리를 로딩
google.load("visualization" , "1" , {"packages" : ["corechart"] } );

//불러오는 작업이 완료되어 로딩이 되었다면 drawChart() 함수를 호출하는 콜백이 일어남 drawChart를 실행해라
google.setOnLoadCallback(drawChart);

//콜백함수
function drawChart() {
	/*
	//아작났어유
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	*/
	let jsonData = 	$.ajax({
		url : "/resources/json/simpleData.json",
		dataType : "json",
		async : false
	}).responseText;
	
	console.log("jsonData : " , jsonData);
	
	// 구글 차트용 데이터 테이블 생성
	let data = new google.visualization.DataTable(jsonData);
	// 어떤 차트 모양으로 출력할지를 정해주자 => LineChart
	// LineChart , ColumnChart, PieChart
	let chart = new google.visualization.LineChart(
	document.getElementById("chart_div")
	);
	
	// data 데이터를 chart모양으로 출력해보자
	chart.draw(data , 
		{
			title : "차트 예제",
			width : 500 , 
			height : 400 
		}	
	);	
}
</script>
<div class="row">
	<div class="col-xl-8 col-lg-7">
		<!-- Area Chart -->
		<div class="card shadow mb-4">
			<div class="card-header py-3">
				<h6 class="m-0 font-weight-bold text-primary">상품 가격</h6>
			</div>
			<!-- 구글 차트가 보여질 영역 -->
			<div id="chart_div"></div>
		</div>
	</div>
</div>

 

http://localhost/chart/chart01 페이지 접속 후 아래 차트 확인

 

google 멀티차트

 

ChartController내 아래코드 추가

	// 요청URI : /chart/chart01Multi
	@GetMapping("/chart01Multi")
	public String chart01Multi() {
		//forwarding
		return "chart/chart01Multi";
	}

 

chart01.jsp 복사해서 chart01Multi.jsp 파일 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<script type="text/javascript" src="/resources/js/jquery-3.6.0.js"></script>
<script type="text/javascript"
	src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// 구글 차트 라이브러리를 로딩
google.load("visualization" , "1" , {"packages" : ["corechart"] } );

//불러오는 작업이 완료되어 로딩이 되었다면 drawChart() 함수를 호출하는 콜백이 일어남 drawChart를 실행해라
google.setOnLoadCallback(drawChart);
google.setOnLoadCallback(drawChart2);

//콜백함수
function drawChart() {
	/*
	//아작났어유
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	*/
	let jsonData = 	$.ajax({
		url : "/resources/json/simpleData.json",
		dataType : "json",
		async : false
	}).responseText;
	
	console.log("jsonData : " , jsonData);
	
	// 구글 차트용 데이터 테이블 생성
	let data = new google.visualization.DataTable(jsonData);
	// 어떤 차트 모양으로 출력할지를 정해주자 => LineChart
	// LineChart , ColumnChart, PieChart
	let chart = new google.visualization.LineChart(
	document.getElementById("chart_div")
	);
	
	// data 데이터를 chart모양으로 출력해보자
	chart.draw(data , 
		{
			title : "차트 예제",
			width : 500 , 
			height : 400 
		}	
	);	
}
//콜백함수2 drawChart2
function drawChart2() {
	/*
	//아작났어유
	//dataType : 응답데이터의 형식
	//contentType : 보내는데이터의 형식
	//sync : 동기 / async : 비동기
	*/
	let jsonData = 	$.ajax({
		url : "/resources/json/simpleData2.json",
		dataType : "json",
		async : false
	}).responseText;
	
	console.log("jsonData : " , jsonData);
	
	// 구글 차트용 데이터 테이블 생성
	let data = new google.visualization.DataTable(jsonData);
	// 어떤 차트 모양으로 출력할지를 정해주자 => LineChart
	// LineChart , ColumnChart, PieChart
	let chart = new google.visualization.ColumnChart(
	document.getElementById("chart_div2")
	);
	
	// data 데이터를 chart모양으로 출력해보자
	chart.draw(data , 
		{
			title : "차트 예제",
			width : 500 , 
			height : 400 
		}	
	);	
}
</script>
<div class="row">
	<div class="col-xl-8 col-lg-7">
		<!-- LineChart -->
		<div class="card shadow mb-4">
			<div class="card-header py-3">
				<h6 class="m-0 font-weight-bold text-primary">상품 가격</h6>
			</div>
			<!-- 구글 차트가 보여질 영역 -->
			<div id="chart_div"></div>
		</div>
		
		<!-- Column Chart -->
		<div class="card shadow mb-4">
			<div class="card-header py-3">
				<h6 class="m-0 font-weight-bold text-primary">채소 가격</h6>
			</div>
			<!-- 구글 차트가 보여질 영역 -->
			<div id="chart_div2"></div>
		</div>
	</div>
</div>

 

 

json 폴더내에 simpleData2.json 생성

//simpleData2.json 파일
{
"cols":[
{"id":"","label":"Topping","pattern":"","type":"string"},
{"id":"","label":"Slices","pattern":"","type":"number"}
],
"rows":[
{"c":[{"v":"Mushrooms"},{"v":3}]},
{"c":[{"v":"Onions"},{"v":1}]},
{"c":[{"v":"Olives"},{"v":1}]},
{"c":[{"v":"Zucchini"},{"v":1}]},
{"c":[{"v":"Pepperoni"},{"v":2}]}
]
}

 

http://localhost/chart/chart01Multi 페이지 접속 후 아래 차트 확인

 

 

오라클 sql developer 열기

fruit , vegetable 테이블 생성

create table fruit(
    fruit_id varchar2(10),
    fruit_nm varchar2(90),
    fruit_amt number,
    constraint pk_fruit primary key(fruit_id)   
);
create table vegetable(
    vege_id varchar2(20),
    vege_nm varchar2(90),
    vege_amt number,
    constraint pk_vegetable primary key(vege_id)
);
/*
SET(집합) : 열의 개수가 동일 , 매핑되는 열의 자료형이 동일해야 함.
            첫번째 집합 컬럼명으로 컬럼명이 결정됨
union     : 합집합 , 중복데이터 1회 출력 , 자동정렬 됨
union all : 합집합 , 중복데이터 모두 출력, 자동정렬 안됨
intersect
minus
*/
select fruit_id , fruit_nm , fruit_amt , 'fruit' GUBUN
from fruit
union
select vege_id , vege_nm , vege_amt , 'vegetable' GUBUN
from vegetable;

 

테이블 생성 후 데이터 입력

Insert into VEGETABLE (VEGE_ID,VEGE_NM,VEGE_AMT) values ('VEGE01','Mushrooms',3);
Insert into VEGETABLE (VEGE_ID,VEGE_NM,VEGE_AMT) values ('VEGE02','Onions',1);
Insert into VEGETABLE (VEGE_ID,VEGE_NM,VEGE_AMT) values ('VEGE03','Olives',1);
Insert into VEGETABLE (VEGE_ID,VEGE_NM,VEGE_AMT) values ('VEGE04','Zucchini',1);
Insert into VEGETABLE (VEGE_ID,VEGE_NM,VEGE_AMT) values ('VEGE05','Pepperoni',2);
COMMIT;

 

with t as(
select fruit_id , fruit_nm , fruit_amt , 'fruit' GUBUN
from fruit
union all
select vege_id , vege_nm , vege_amt , 'vegetable'
from vegetable
)
select * from t
where t.gubun = 'fruit';

 

fruit_SQL.xml생성 후 쿼리문 작성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.chart.mapper.FruitMapper">
	<select id="fruitList" parameterType="String" resultType="fruitVO">
		with t as(
			select fruit_id , fruit_nm , fruit_amt , 'fruit' gubun
			from   fruit
			union  all
			select vege_id , vege_nm , vege_amt , 'vegetable'
			from   vegetable
		)
		select * from t
		where t.gubun like '%fruit%'
	</select>
</mapper>

 

root-context.xml 아래와 같이 수정

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="kr.or.ddit.**.mapper" />
	</bean>

 

fruitVO 생성

package kr.or.ddit.chart.vo;

import lombok.Data;

@Data
public class FruitVO {

	private String fruitId;
	private String fruitNm;
	private int fruitAmt;
	private String gubun;
}

 

mybatisAlias.xml에 alias추가

		<typeAlias type="kr.or.ddit.chart.vo.FruitVO" alias="fruitVO" />

 

fruit.xml select 쿼리문 수정

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.chart.mapper.FruitMapper">
	<select id="fruitList" parameterType="String" resultType="fruitVO">
		with t as(
			select fruit_id , fruit_nm , fruit_amt , 'fruit' gubun
			from   fruit
			union  all
			select vege_id , vege_nm , vege_amt , 'vegetable'
			from   vegetable
		)
		select * from t
		where 1 = 1
		<if test="gubun!=null and gubun!=''">
		and	  t.gubun like '%' || #{gubun} || '%'
		</if>
		</select>
</mapper>

 

mapper 인터페이스 생성

package kr.or.ddit.chart.mapper;

import java.util.List;

import kr.or.ddit.chart.vo.FruitVO;

public interface FruitMapper {
	
	//<select id="fruitList" parameterType="String" resultType="fruitVO">
	public List<FruitVO> fruitList(String gubun);

}

 

package kr.or.ddit.chart.service;

import java.util.List;

import kr.or.ddit.chart.vo.FruitVO;

public interface FruitService {

	public List<FruitVO> fruitList(String gubun);
	
}

 

package kr.or.ddit.chart.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.or.ddit.chart.mapper.FruitMapper;
import kr.or.ddit.chart.service.FruitService;
import kr.or.ddit.chart.vo.FruitVO;
@Service
public class FruitServiceImpl implements FruitService {
	@Autowired
	FruitMapper fruitMapper;
	
	/*
	 * 오버로딩	: 같은 이름의 메소드를 다르게 사용가능(파라미터 개수 , 타입 , 순서)
	 * 오버라이드 	: 상속받은 부모의 메소드를 자식 메소드에서 재정의
	 */
	@Override
	public List<FruitVO> fruitList(String gubun) {
		
		return this.fruitMapper.fruitList(gubun);
	}

}

 

ChartController에 메소드 추가 작성

 

// 요청URI : /chart/chart02
	@ResponseBody
	@GetMapping("/chart02")
	public List<FruitVO> chart02() {
		
		List<FruitVO> fruitVOList = this.fruitService.fruitList("fruit");
		
		log.info("fruitVOList : " + fruitVOList);
		
		//forwarding
		return fruitVOList;
	}

 

서버 재기동 후 http://localhost/chart/chart02 접속해서 아래 페이지 확인(json데이터 받아오는지)

FruitServiceImpl 구현 클래스 수정

package kr.or.ddit.chart.service.impl;

import java.util.List;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.or.ddit.chart.mapper.FruitMapper;
import kr.or.ddit.chart.service.FruitService;
import kr.or.ddit.chart.vo.FruitVO;

@Service
public class FruitServiceImpl implements FruitService {
	@Autowired
	FruitMapper fruitMapper;

	/*
	 * 오버로딩 : 같은 이름의 메소드를 다르게 사용가능(파라미터 개수 , 타입 , 순서) 오버라이드 : 상속받은 부모의 메소드를 자식 메소드에서
	 * 재정의
	 */
	@Override
	public List<FruitVO> fruitList(String gubun) {
		/*
		 * JSONObject 만들기
		 * 
		 */

		List<FruitVO> fruitVOList = this.fruitMapper.fruitList(gubun);

		JSONObject data = new JSONObject();

		// fruitVOList -> json 데이터로 변환
		// 1. cols 배열에 넣기(상품명 , 금액)
		/*
		 * "cols":[
		 * {"id":"","label":"상품명","pattern":"","type":"string"},
		 * {"id":"","label":"금액","pattern":"","type":"number"}
		 * ],
		 */
		JSONObject col1 = new JSONObject();
		JSONObject col2 = new JSONObject();
		
		JSONArray title = new JSONArray();
		col1.put("label" , "상품명");
		col1.put("type" , "string");
		col2.put("label" , "금액");
		col2.put("type" , "number");
		
		title.add(col1);
		title.add(col2);
		
		data.put("cols" , title);	// 여기까지 cols 완성
	}

}