DB에 저장된 데이터값을 ajax로 그래프 그리기
JS
중괄호{} => 객체
대괄호[] => 배열
ajax 비동기 통신 => json구조로 변환 라이브러리
pom.xml
jackson-databind
https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.14.2
BroadCastController
package kr.smhrd.controller;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.smhrd.entity.BroadCast;
import kr.smhrd.mapper.BroadCastMapper;
@Controller // 1) 클래스파일이 Controller (POJO)임을 알려주기
public class BroadCastController {
// -> 동기통신 요청만 처리하는 controller
// Mapper 인터페이스를 사용할 수 있게끔 연결
@Autowired
private BroadCastMapper mapper;
@GetMapping("/") // 2) url mapping을 "/"로 들어왔을 때 잡아주기
public String index(Model model) {
BroadCast list = mapper.select();
model.addAttribute("list", list);
return "index"; // 3) "/"로 들어왔을 때 index.jsp 페이지를 forward 방식으로 되돌려주기
}
// // 월별 데이터 조회할 수 있는 url
// // getMonthData ==> return null
// @RequestMapping("/getMonthData")
// public @ResponseBody ArrayList<BroadCast> getMonthData() {
// // @ResponseBody => 비동기 통신으로 요청이 들어왔을 때
// // => 반환하는 결과값이 페이지 이름이 아니라,
// // => 웹 화면에 출력해야하는 결과값임을 나타내는 annotation
//
// // ajax(비동기) 요청이 들어왔을 때, 결과값을 반환하려면 웹페이지 화면에 출력
//
//
// System.out.println("요청이 들어오닝");
//
// // 1. DB에서 월별 전체 시청률 평균 조회해오기
// ArrayList<BroadCast> result = mapper.getMonthData();
//
// // 2. 조회한 결과값을 return 반환 시켜주기
// return result;
// // 만약에 객체, ArrayList 복잡한 형태를 화면에 출력하려면?
// // => jsp/servlet => Gson 라이브러리 사용
// // => spring framework => jackson-databind 라이브러리 사용(자동으로 결과값을 convert)
//
// }
//
// // 연령대별 데이터 조회
// @RequestMapping("/getSData")
// public @ResponseBody BroadCast getSData() {
//
// System.out.println("요청");
//
// BroadCast result = mapper.getSData();
//
// return result;
// }
}
BroadCastRESTController
package kr.smhrd.controller;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import kr.smhrd.entity.BroadCast;
import kr.smhrd.mapper.BroadCastMapper;
@RestController // @Controller + @ResponseBody
public class BroadCastRESTController {
// -> 비동기통신 요청을 처리해주는 Controller
// -> 웹페이지 화면에 데이터를 돌려주는 역할
// -> 메소드를 선언할 때 @ResponseBody 생략이 가능
@Autowired
private BroadCastMapper mapper;
// 월별 데이터 조회할 수 있는 url
@RequestMapping("/getMonthData")
public ArrayList<BroadCast> getMonthData() {
System.out.println("요청이 들어오닝");
ArrayList<BroadCast> result = mapper.getMonthData();
return result;
}
// 연령대별 데이터 조회
@RequestMapping("/getSData")
public BroadCast getSData() {
System.out.println("요청");
BroadCast result = mapper.getSData();
return result;
}
// 출연진 Top5 조회
@RequestMapping("/getCastCount")
public ArrayList<BroadCast> getCastCount() {
// 1. DB에서 데이터 조회
ArrayList<BroadCast> result = mapper.getCastCount();
// 2. 조회한 결과값 화면에 출력될 수 있는 형태로 변환
// 1개의 column안에 여러 명의 이름이 들어있음
// 2-1) result의 0번 인덱스에 접근
System.out.println(result.get(0));
// 2-2) fixing_cast_nm 데이터에 접근
System.out.println(result.get(0).getFixing_cast_nm());
// 2-3) , 를 기준으로 데이터 쪼개기
System.out.println(result.get(0).getFixing_cast_nm().split(",")[0]);
return result;
}
}
BroadCastMapper.java => DAO
package kr.smhrd.mapper;
import java.util.ArrayList;
import org.apache.ibatis.annotations.Select;
import kr.smhrd.entity.BroadCast;
// @Mapper => 버전 업그레이드로 생략 가능
public interface BroadCastMapper {
// 남, 여, 전체 시청률 평균을 조회하는 기능
// 조회한 결과 행이 하나이기 때문에 BroadCast로 받아오기
// session.selectOne();
public BroadCast select();
public ArrayList<BroadCast> getMonthData();
public BroadCast getSData();
@Select("SELECT FIXING_CAST_NM, CAST_NM FROM BROADCAST WHERE PROGRAM_NM = '뮤직뱅크'")
public ArrayList<BroadCast> getCastCount();
}
BroadCastMapper.xml => mybatis
<?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.smhrd.mapper.BroadCastMapper">
<select id="select" resultType="kr.smhrd.entity.BroadCast">
select PROGRAM_NM,
round(avg(MALE_RT), 3) as MALE_RT,
round(avg(FEMALE_RT), 3) AS FEMALE_RT,
round(avg(WTCHNG_RT), 3) AS WTCHNG_RT
from COM.BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크'
</select>
<!-- DB에서 조회해 온 결과값의 column과
객체의 필드명이 서로 달랐을 때 사용할 수 있는 resultMap -->
<!-- id : resultMap의 이름(변수명) 정하는 attribute
type : 내가 표현하고 싶은 객체(자료형)
-->
<resultMap type="kr.smhrd.entity.BroadCast" id="monthData">
<!-- column : 조회해온 column 명칭 / property : 객체의 필드명 -->
<result column="DE" property="brdcst_de"/>
<result column="RT" property="wtchng_rt"/>
</resultMap>
<!-- 월별 전체시청률 평균 조회 -->
<select id="getMonthData" resultMap="monthData">
SELECT MONTH(BRDCST_DE) AS DE,
round(avg(WTCHNG_RT), 3) AS RT
FROM BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크'
GROUP BY DE
</select>
<!-- 10 ~ 60대 평균시청률 조회 -->
<resultMap type="kr.smhrd.entity.BroadCast" id="sData">
<result column="10대" property="n10s_rt"/>
<result column="20대" property="n20s_rt"/>
<result column="30대" property="n30s_rt"/>
<result column="40대" property="n40s_rt"/>
<result column="50대" property="n50s_rt"/>
<result column="60대" property="n60s_above_rt"/>
</resultMap>
<select id="getSData" resultMap="sData">
SELECT round(avg(N10S_RT), 3) AS 10대
, round(avg(N20S_RT), 3) AS 20대
, round(avg(N30S_RT), 3) AS 30대
, round(avg(N40S_RT), 3) AS 40대
, round(avg(N50S_RT), 3) AS 50대
, round(avg(N60S_ABOVE_RT), 3) AS 60대
FROM BROADCAST
WHERE PROGRAM_NM = '뮤직뱅크'
</select>
</mapper>
index.jsp
char-area-demo.js
// VS코드에서 수정 후에 반드시 ctrl+s 저장하기!!
// eclipse로 돌아가서 해당하는 파일을 다시 한 번 열어주기! => 반영이 빨라짐.
// 링크 클릭, 버튼 클릭, 페이지 변환이 일어나면서 데이터 응답 => 동기통신
// 비동기통신 방식으로 DB에서 데이터를 조회해와서 차트를 그리기!
// => $.ajax()
// 문법
$(function () {
$.ajax({
// 1) 어디로 요청을 보내야하는지
url: 'getMonthData',
// 2) 보내줄 값이 있는지
// data : '있을 때만 사용',
// 3) 받아올 결과값의 자료형 지정
dataType: 'json',
// 4) 성공했을 때 실행할 함수
success: function (res) {
console.log(res);
// res => 배열 => 객체들이 존재
// res의 0번 인덱스에 있는 객체안에 wtchng_rt를 console에 출력하기
console.log(res[0].wtchng_rt);
// 1. labels에 들어갈 수 있는 배열을 하나 생성
let monthData = [];
// 3. data에 들어갈 수 있는 배열을 하나 생성
let wtchngData = []
for (let i = 0; i < res.length; i++) {
// 2. 배열에 res 안에 들어있는 brdcst_de라는 데이터를 하나씩 추가
monthData.push(res[i].brdcst_de);
// 4. 배열에 res 안에 들어있는 wtchng_rt라는 데이터를 하나씩 추가
wtchngData.push(res[i].wtchng_rt);
}
// 5. 차트 그리는 전체 코드를 함수로 만들고, 함수를 사용해서 배열 2개를 매개변수로 넘기기
makeAreaChart(monthData, wtchngData);
},
// 5) 실패했을 때 실행할 함수
error: function () {
console.log('실패!');
}
})
})
// Set new default font family and font color to mimic Bootstrap's default styling
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#858796';
// Area Chart Example
function makeAreaChart(monthData, wtchngData) {
var ctx = document.getElementById("myAreaChart");
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
// x축 라벨(DB에서 조회한 값으로 수정)
labels: monthData,
datasets: [{
label: "Earnings",
lineTension: 0.3,
backgroundColor: "rgba(78, 115, 223, 0.05)",
borderColor: "rgba(78, 115, 223, 1)",
pointRadius: 3,
pointBackgroundColor: "rgba(78, 115, 223, 1)",
pointBorderColor: "rgba(78, 115, 223, 1)",
pointHoverRadius: 3,
pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
pointHoverBorderColor: "rgba(78, 115, 223, 1)",
pointHitRadius: 10,
pointBorderWidth: 2,
// data에 DB에서 조회한 값 가져오기
data: wtchngData,
}],
},
options: {
maintainAspectRatio: false,
layout: {
padding: {
left: 10,
right: 25,
top: 25,
bottom: 0
}
},
scales: {
xAxes: [{
time: {
unit: 'date'
},
gridLines: {
display: false,
drawBorder: false
},
ticks: {
maxTicksLimit: 7
}
}],
yAxes: [{
ticks: {
maxTicksLimit: 5,
padding: 10,
},
gridLines: {
color: "rgb(234, 236, 244)",
zeroLineColor: "rgb(234, 236, 244)",
drawBorder: false,
borderDash: [2],
zeroLineBorderDash: [2]
}
}],
},
legend: {
display: false
},
tooltips: {
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
titleMarginBottom: 10,
titleFontColor: '#6e707e',
titleFontSize: 14,
borderColor: '#dddfeb',
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
intersect: false,
mode: 'index',
caretPadding: 10,
}
}
});
}
index.jsp
chart-pie-demo.js
// 페이지가 로드 완료되면 비동기통신 시작하도록 코드 작성
$(function(){ // document.ready() => jquery로 표현한 것
$.ajax({
url : 'getSData',
dataType : 'json',
success: function(res){
console.log(res);
let age = ['10대', '20대', '30대', '40대', '50대', '60대 이상']
// json으로 변환 시 필드는 무조건 소문자로 변경됨!
// 따라서 대문자말고 소문자로 작성 기억!!
let ageData = [res.n10s_rt, res.n20s_rt, res.n30s_rt, res.n40s_rt, res.n50s_rt, res.n60s_above_rt];
console.log(res.n10s_rt);
// 함수선언할 때 매개변수의 순서는 무조건 맞춰야함!
makePieChart(age, ageData);
},
error: function () {
console.log('실패!');
}
})
});
// Set new default font family and font color to mimic Bootstrap's default styling
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#858796';
// Pie Chart Example
// 함수명은 무조건 중복없이 선언해줘야 함!!
function makePieChart(age, ageData){
var ctx = document.getElementById("myPieChart");
var myPieChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: age,
datasets: [{
//data에 DB에서 조회한 값 가져오기
data: ageData,
backgroundColor: ['#4e73df', '#1cc88a', '#36b9cc', '#4e73df', '#1cc88a', '#36b9cc'],
hoverBackgroundColor: ['#2e59d9', '#17a673', '#2c9faf', '#2e59d9', '#17a673', '#2c9faf'],
hoverBorderColor: "rgba(234, 236, 244, 1)",
}],
},
options: {
maintainAspectRatio: false,
tooltips: {
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
borderColor: '#dddfeb',
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
caretPadding: 10,
},
legend: {
display: false
},
cutoutPercentage: 80,
},
});
}
'프레임워크(Framework) > Spring' 카테고리의 다른 글
동적 쿼리 + JS 변수로 ajax 데이터 보내기 (0) | 2023.06.13 |
---|---|
알고리즘_Java 로직 + ajax 비동기통신 (0) | 2023.06.12 |
DB에 저장된 데이터 불러오기 (0) | 2023.06.08 |
mysql 연결&데이터 불러오기 (0) | 2023.06.07 |
Spring 코드 흐름 (0) | 2023.06.05 |
댓글