3월 28일

SJY0000·2022년 3월 28일
0

Springboot

목록 보기
3/24

오늘 배운 것

  • Springboot 코드로 DB table 설정하기
  • 프로그램 실행 시 초기데이터 넣기
  • Chart 넣기

@GeneratedValue(strategy = GenerationType.IDENTITY)로 지정을 해줘야 auto-increment 속성이 테이블 별로 지정이된다.
@GeneratedValue(strategy = GenerationType.AUTO)로 지정 시 모든 테이블의 auto-increment 값이 공유되기 때문에 관리가 어려움

파일경로 지정시 templates, static 등 프로젝트 생성시 기본 생성 되는 폴더들은 경로 지정시 생략가능

1 : n의 관계 설정(project(1), employee(n))

  • 1에 해당하는 클래스에 list 선언하여 복수의 데이터를 받을 준비를 함
  • cascade 속성
  • fetch 속성
    EAGER : 연관된(참조) 데이터까지 한번에 다 가져옴
    LAZY : 필요한 데이터만 가져오고 필요하면 참조 데이터까지 가져옴

언뜻 보면 eager속성이 한번에 가져오니까 좋아보이지만 수많은 테이블이 존재 할 때는 필요하지 않은 데이터까지 불러오게 되므로 리소스를 많이 차지 하게 됨으로써 많은 문제가 발생하므로
LAZY속성을 이용하도록 하자.

// project
@OneToMany(mappedBy = "project") // 1 : n의 관계, 상호연관관계일 때 사용, ManyToOne의 변수명, Project 테이블에 맵핑
														// Cascade는 수정, 삭제 시 연관데이터 조작여부체크, Fetch는 lazy일 때 연관 테이블 데이터를 천천히
	private List<Employee> employees;
// employee
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE,
						CascadeType.PERSIST, CascadeType.REFRESH},
				fetch = FetchType.LAZY) // n : 1 관계, 여러명의 직원 : 하나의 프로젝트
										// Cascade는 수정, 삭제 시 연관데이터 조작여부체크, Fetch는 lazy일 때 연관 테이블 데이터를 천천히
@JoinColumn(name = "project_id") // 테이블에 "project_id" column 넣기, 외래키 열
private Project project;

n : m의 관계 설정

  • 연관된 데이터들을 묶어줄 테이블을 생성하여 출력할 수 있도록 한다.
  • 연관된 칼럼을 inverseJoinColumns속성으로 설정한다.
// project 
@ManyToMany(cascade = { CascadeType.DETACH, CascadeType.MERGE,
			CascadeType.REFRESH }, fetch = FetchType.LAZY) // n : 1 관계, 여러명의 직원 : 하나의 프로젝트
														// Cascade는 수정, 삭제 시 연관데이터 조작여부체크, Fetch는 lazy일 때 연관 테이블 데이터를 천천히
	@JoinTable(name = "project_employee", joinColumns = @JoinColumn(name = "project_id"), 
				inverseJoinColumns = @JoinColumn(name = "employee_id"))
	// n : n 관계에서는 테이블을 만들고 생성한 테이블에 id를 넣고 다른 테이블의 id도 입력
	private List<Employee> employees;
// employee
	@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE,
			 CascadeType.REFRESH},
				fetch = FetchType.LAZY)// n : 1 관계, 여러명의 직원 : 하나의 프로젝트
	// Cascade는 수정, 삭제 시 연관데이터 조작여부체크, Fetch는 lazy일 때 연관 테이블 데이터를 천천히
	@JoinTable(name = "project_employee", joinColumns = @JoinColumn(name = "employee_id"),
				inverseJoinColumns = @JoinColumn(name = "project_id"))
	// n : n 관계에서는 테이블을 만들고 생성한 테이블에 id를 넣고 다른 테이블의 id도 입력
	private List<Project> projects;

데이터 넣기

첫번째 방법

  • main 클래스에 CommandLineRunner 클래스를 이용해 프로그램 실행 시 동작하는 클래스를 이용해 데이터 넣기
  • cascadeType.PERSIST 속성을 제거해줘야 에러가 생기지 않음
package com.myapp.pma;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.myapp.pma.dao.EmployeeRepository;
import com.myapp.pma.dao.ProjectRepository;
import com.myapp.pma.entities.Employee;
import com.myapp.pma.entities.Project;

@SpringBootApplication
public class PmaApplication {
	
	@Autowired
	private EmployeeRepository empRepo;
	
	@Autowired
	private ProjectRepository proRepo;
	
	public static void main(String[] args) {
		SpringApplication.run(PmaApplication.class, args);
	}

	// 프로그램 실행시 자동으로 DB에 입력하는 코드
	@Bean
	CommandLineRunner runner() {
		return args -> {
			// 프로그램 실행시 코드
			Employee emp1 = new Employee("길동", "홍", "hong@gmail.com");
			Employee emp2 = new Employee("라니", "고", "go@gmail.com");
			Employee emp3 = new Employee("스티븐", "킹", "king@gmail.com");

			Employee emp4 = new Employee("날두", "호", "ho@gmail.com");
			Employee emp5 = new Employee("펭수", "김", "kim@gmail.com");
			Employee emp6 = new Employee("피터", "팬", "pen@gmail.com");

			Employee emp7 = new Employee("순신", "이", "lee@gmail.com");
			Employee emp8 = new Employee("감찬", "강", "kang@gmail.com");
			Employee emp9 = new Employee("유신", "김", "yousin@gmail.com");

			
			Project pro1 = new Project("대형 프로젝트", "시작전", "할일이 많음");
			Project pro2 = new Project("새 직원 인사",  "완료", "필요한 부서의 새 직원 고용");
			Project pro3 = new Project("오피스 리모델링", "진행중", "오래된 오피스 환경을 새것처럼 리모델링");
			Project pro4 = new Project("회사 보안 강화", "진행중", "출 입문 인증 지문센서 추가");
				
			
			// project 에 직원들을 추가하고 , employee 객체에 프로젝트들을 추가한다.
			// project에 새 메서드 작성
			pro1.addEmployee(emp1);
			pro1.addEmployee(emp2);
			pro2.addEmployee(emp3);
			pro3.addEmployee(emp1);
			pro4.addEmployee(emp1);
			pro4.addEmployee(emp3);
			
			empRepo.save(emp1);
			empRepo.save(emp2);
			empRepo.save(emp3);
			empRepo.save(emp4);
			empRepo.save(emp5);
			empRepo.save(emp6);
			empRepo.save(emp7);
			empRepo.save(emp8);
			empRepo.save(emp9);
			
			proRepo.save(pro1);
			proRepo.save(pro2);
			proRepo.save(pro3);
			proRepo.save(pro4);
		};
	}
}
// project.java
	// 프로젝트 객체에서 직원을 추가하는 메소드
	public void addEmployee(Employee emp) {
		if (employees == null) {
			employees = new ArrayList<>();
		}
		employees.add(emp);
	}

두번째 방법

  • data.sql 파일을 생성하여 sql Query문을 준비하여 프로그램 실행시 데이터 입력
  1. templates 폴더 안에 data.sql파일 생성
  2. application.properties 파일 안에
    spring.jpa.defer-datasource-initialization=true
    입력

Chart 사용하기

<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
  <head th:replace="layouts::헤드"> </head>
  <body>
    <nav th:replace="layouts:: 네브바"></nav>
    <div class="container">
      <h3>프로젝트 진행 상황</h3>
      <div class="row">
        <div class="col-md-7">
          <table class="table table-hover">
            <thead class="table-dark">
              <tr>
                <th>프로젝트 이름</th>
                <th>현재 진행상태</th>
              </tr>
            </thead>
            <tbody>
              <!-- thymeleaf의 반복문-->
              <tr th:each="project : ${projectList}">
                <td th:text="${project.name}"></td>
                <td class="stage" th:text="${project.stage}"></td>
              </tr>
            </tbody>
          </table>
        </div>
        <div class="col-md-3 ms-5">
          <canvas id="myChart"></canvas>
        </div>
      </div>
    </div>
    <div class="container">
      <h1>직원 현황</h1>
      <table class="table table-hover">
        <thead class="table-dark">
          <tr class="fw-bold">
            <th></th>
            <th>이름</th>
            <th>이메일</th>
          </tr>
        </thead>
        <tbody>
          <tr th:each="employee : ${employeeList}">
            <td th:text="${employee.lastName}"></td>
            <td th:text="${employee.firstName}"></td>
            <td th:text="${employee.email}"></td>
          </tr>
        </tbody>
      </table>
    </div>
    <footer th:replace="layouts::푸터"></footer>
    <!-- 홈페이지에만 필요한 차트 만들기-->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script th:src="@{/js/chart.js}"></script>
  </body>
</html>
  • Project의 stage값을 찾아서 값에 따라 차트데이터를 입력
const stages = document.querySelectorAll('.stage');
let s1 = 0;
let s2 = 0;
let s3 = 0;

stages.forEach((stage) => {
  if (stage.textContent === '시작전') s1++;
  else if (stage.textContent === '진행중') s2++;
  else if (stage.textContent === '완료') s3++;
});

const data = {
  labels: ['시작전', '진행중', '완료'],
  datasets: [
    {
      label: 'My First Dataset',
      data: [s1, s2, s3],
      backgroundColor: ['rgb(255, 99, 132)', 'rgb(54, 162, 235)', 'rgb(255, 205, 86)'],
      hoverOffset: 4,
    },
  ],
};

const config = {
  type: 'pie',
  data: data,
};

const myChart = new Chart(document.getElementById('myChart'), config);

0개의 댓글