본문 바로가기
빅데이터 부트캠프/Spring boot

빅데이터 부트캠프 94일차

by Mecodata 2022. 11. 18.

CRUD 구현

- DTO에서는 @Setter 사용, Entity에서는 @Setter 사용 X

- Service와 Repository는 각각 Controller와 ServiceImpl에서 바로 객체로 불러와 유연하게 사용하기 위해서 interface로 생성

- View의 기능을 Postman을 이용하여 테스트

Postman = 개발한 API를 간단한 방법으로 테스트하여 결과를 확인할 수 있음으로써 API 개발 생산성을 높여주는 플랫폼

Spring Boot JPA 실행 과정

JPA Repository

- public interface Repository명 extends JpaRepository<Entity 타입, Entity의 PK>로 적용

- extends JpaRepository를 통해 외부 클래스에 Repository 객체 생성시 JPA 속성 사용 가능

- JPARepository를 상속받으면 @Repository가 자동 적용되지만 입력하는 것이 좋음

- 외부 클래스에서 불러온 인터페이스 객체 위에 @Autowired를 입력
=> 인터페이스는 기본 생성자를 입력하지 않아도 외부 클래스에서 객체를 생성할 수 있지만 @Autowired를 이용하면 new를 이용하여 따로 객체 생성 코드를 입력하지 않아도 자동으로 객체가 생성됨

JPA 객체 메소드

- JPA 객체 메소드만으로 어느정도의 CRUD 구현 가능 (단, 특정 엔티티 조회는 따로 메소드 정의하여 사용)

- findAll() = 테이블에서 모든 엔티티 객체를 담은 목록 조회 (List<Entity>를 반환)

- save() = 해당 Entity 객체를 테이블에 저장

- delete() = 해당 Entity 객체를 테이블에서 삭제

- flush() = 테이블 변경 사항 적용 (Update시 사용)

쿼리 메소드  기능

- JPA만의 특징중 하나로 메소드 이름을 인식하여 자동으로 쿼리를 생성하여 실행

- 무조건 엔티티명과 컬럼명의 첫 글자는 대문자로 입력해야 JPA가 인식함

- 엔티티의 컬럼명 변경시 JPA의 메소드명도 반드시 변경해줘야 함

- 컬럼명은 DB가 아닌 Entity 기준으로 입력해줘야함!

ex) DB에서는 diary_no, Entity에서는 no일 경우 쿼리 메소드명을 getDiaryByNo로 입력해야함

 

- 조회 = [find or read or get]컬럼명By컬럼명 (By 이전에 컬럼명 대신 엔티티명 입력시 *이 적용됨)

get으로 입력하면 Entity 객체를 반환하고 find로 입력하면 Optional<Entity> 객체를 반환

ex) getDeptByDeptno => SELECT * FROM dept WHERE deptno= ?1 

ex) getDnameAndLocByDeptno =>  SELECT dname, loc FROM dept WHERE deptno=?1

- COUNT = count엔티티타입By컬럼명 (반환타입 long)

- EXISTS: exists엔티티타입By컬럼명 (반환타입 boolean)

 

CRUD 구현 예시

- service와 serviceImlp을 나눈 이유 => 메소드에 대한 기본 규칙(파라미터, 메소드명)을 설정하기 위해서 

Controller

package com.spring.company.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.spring.company.dto.DeptDTO;
import com.spring.company.entity.Dept;
import com.spring.company.service.DeptServiceImpl;

@RestController
@RequestMapping(value="/api")
public class DeptController {
	
	@Autowired
	DeptServiceImpl deptService;
	
	@GetMapping(value = "/dept/{deptno}", produces="application/json")
	@CrossOrigin(origins = {"http://localhost:3000"})
	public DeptDTO getDeptByDeptno(@PathVariable Long deptno) {
		System.out.println(deptno);
		DeptDTO deptDTO = null;
		
		deptDTO = deptService.getDeptByDeptno(deptno);
		
		return deptDTO;
	}
	
	// Read
	@GetMapping("/depts")
	public List<DeptDTO> getAllDept() {
		return deptService.getAllDept();
	}
	
	// Create 
	@PostMapping("/dept/{deptno}/{dname}/{loc}")
	public Dept createDept(@PathVariable Long deptno, @PathVariable String dname, @PathVariable String loc) {
		Dept dept = Dept.builder().deptno(deptno).dname(dname).loc(loc).build();
		return deptService.createDept(dept);
	}
	
	@PostMapping("/dept")
	public void insertDept(@RequestBody DeptDTO deptDTO) {
		System.out.println(deptDTO);
		deptService.insertDept(deptDTO);
	}
	
	// Delete 
	@DeleteMapping("/dept")
	public void deleteDept(@RequestBody DeptDTO deptDTO) {
		deptService.deleteDept(deptDTO);
	}
	
	// Update 
	@PutMapping("/dept")
	public void updateDept(@PathVariable Long deptno, @RequestParam("loc") String newLoc) {
		System.out.println(deptno);
		System.out.println(newLoc);
		deptService.updateDept(deptno, newLoc);
	}
}

ServiceImpl

package com.spring.company.service;

import java.util.List;
import java.util.stream.Collectors;

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

import com.spring.company.dto.DeptDTO;
import com.spring.company.entity.Dept;
import com.spring.company.repository.DeptRepository;

@Service
public class DeptServiceImpl implements DeptService {
	
	@Autowired
	DeptRepository deptRepo;
	
	@Override
	public DeptDTO getDeptByDeptno(Long deptno){
		Dept dept = deptRepo.getDeptByDeptno(deptno); 
		return dept.entityToDTO(dept);
	}
	
	public List<DeptDTO> getAllDept() {
		List<Dept> depts = deptRepo.findAll();
		// List에 담겨있는 dept 객체들을 deptDTO로 변환 (Entity -> DTO 변환)
		List<DeptDTO> deptDTOs = depts.stream()
        		.map(dept -> dept.entityToDTO(dept)).collect(Collectors.toList());
		return deptDTOs;
	}
	
	public Dept createDept(Dept dept) {
		return deptRepo.save(dept);
	}
	
	@Transactional
	@Override
	public void insertDept(DeptDTO deptDTO) {
	   	// DTO => Entity
		Dept dept = deptDTO.dtoToEntity(deptDTO);
		deptRepo.save(dept);
	}
	
	@Transactional
	@Override
	public void deleteDept(DeptDTO deptDTO) {
		// DTO => Entity
		Dept dept = deptDTO.dtoToEntity(deptDTO);
		deptRepo.delete(dept);
	}
	
	@Transactional
	public void updateDept(Long deptno, String newLoc) {
		// 1. 해당 객체
		Dept dept = deptRepo.getDeptByDeptno(deptno);
		DeptDTO deptDTO = DeptDTO.builder()
                                        .deptno(dept.getDeptno())
                                        .dname(dept.getDname())
                                        .loc(dept.getLoc())
                                        .build();
		// 2. 내용 수정
		dept.updateLoc(deptDTO);
		deptRepo.flush(); // 변경 사항 적용
	}
	
}

Service

package com.spring.company.service;

import com.spring.company.dto.DeptDTO;

public interface DeptService {
	public DeptDTO getDeptByDeptno(Long deptno);
	
	public void insertDept(DeptDTO deptDTO);
	
	public void deleteDept(DeptDTO deptDTO);
}

Repository

package com.spring.company.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.spring.company.entity.Dept;

@Repository
public interface DeptRepository extends JpaRepository<Dept, Long> {
	public Dept getDeptByDeptno(Long deptno);

}

DTO

package com.spring.company.dto;

import com.spring.company.entity.Dept;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class DeptDTO {
	private Long deptno;
	private String dname;
	private String loc;
	
	// DTO -> Entity
	public Dept dtoToEntity(DeptDTO deptDTO) {
		Dept dept = Dept.builder()
				.deptno(deptDTO.getDeptno())
				.dname(deptDTO.getDname())
				.loc(deptDTO.getLoc())
				.build();
		
		return dept;
	}
}

Entity

package com.spring.company.entity;

import javax.persistence.Entity;
import javax.persistence.Id;

import com.spring.company.dto.DeptDTO;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Entity
@Getter
@AllArgsConstructor
@NoArgsConstructor  // Entity에서는 @Setter 사용 X
@ToString
@Builder
public class Dept {
	@Id
	private Long deptno;
	private String dname;
	private String loc;	
	
	public void updateLoc(DeptDTO deptDTO) {
		this.loc = deptDTO.getLoc();
		this.dname = deptDTO.getDname();
	}
	
	// Entity => DTO
	public DeptDTO entityToDTO(Dept dept) {
		DeptDTO deptDTO = DeptDTO.builder()
                                        .deptno(dept.getDeptno())
                                        .dname(dept.getDname())
                                        .loc(dept.getLoc())
                                        .build();
		return deptDTO;
	}
}

'빅데이터 부트캠프 > Spring boot' 카테고리의 다른 글

MyBatis 세팅  (0) 2022.12.13
빅데이터 부트캠프 97일차  (0) 2022.11.23
빅데이터 부트캠프 96일차  (0) 2022.11.22
빅데이터 부트캠프 95일차  (0) 2022.11.21

댓글