Spring(IntelliJ + Boot) - 스프링부트 환경설정

songmin jeon·2024년 3월 20일
0


Spring Boot(initializr) 활용해보기

  • https://start.spring.io/
    • 인터넷으로 부트 환경 가능
    • initializr 에서 설정 후 > IDE에서 불러들임 > 맞춤 설정 > 프로젝트 사용

  • 다음과 같이 설정

  • D 드라이브 workspace에 붙여넣기

  • 파일 > 오픈 > 경로 찾기

  • springboot에 build.gradle 선택

창에서 > open as project > 프로젝트 > new window... 선택 > 오류가 있든 없은 열리기만 하면됨

  • 파일 > 세팅스

  • 프로덕트 스트럭툴 에서도 다음과 같이 확인


기존 프로젝트와 Boot 차이

  • jsp를 안씀으로 wepapp 폴더가 없음(타임리프로 대체됨)

    • 대신 여기에 view가 됨.
  • boot는 메인 어플리케이션부터 시작되는 구조로 되어 있음.

    • 패키지 생성 위치는 SpringbootApplication 의 내부 패키지를 만들어줘야함
    • 스캔 영역을 내부에 인식하기 때문
  • 해당 파일의 확장자 변경 -> yml

  • 메인 어플리케이션 에서 구동하면 톰켓도 같이 실행 됨


  • test 폴더
    • 단위 및 통합 테스트 진행 가능
    • 컨트롤러 테스트, 서비스 테스트, Rest 테스트
    • Juit 으로 API형식의 테스트 가능(배우지 않을 예정)


application.yml 설정

  • 파이선 처럼 띄어쓰기가 중요함 적용 내 범위 2칸!
  • 코드 다음과 같이 작성
server:
  port: 8081


spring:
  datasource:
    driver-class-name : com.mysql.cj.jdbc.Driver
    url : jdbc:mysql://localhost:3306/ai
    username : root
    password: 12345

  • templates 폴더에 index.html 파일 생성(테스트용)
    • 스프링부트어플리케이션 Run > localhost:8081 > 화면 뜨는지 확인


그외, 컨버팅해주는 사이트


html에 타임리프 써보기

  • html에 해당 코드 넣어주기
<html  xmlns:th="http://www.thymeleaf.org" lang="en">

  • src/main/java/com.example.springboot 경로에 controller 패키지 생성

  • controller 패키지에 TestController.java 생성

package com.example.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
public class TestController {

    @RequestMapping("/start")
    public String start(Model model){
        List<String> list = new ArrayList<>();
        list.add("사과");
        list.add("바나나");
        list.add("오렌지");
        list.add("포도");
        list.add("귤");
        model.addAttribute("list", list);
        return "index"; // index.html 에 list 모델을 보냄(${list})
    }
}
  • index.html
    • 컨트롤러에서 모델로 list를 전달 받음
    • 타임리프 th:each="data : ${list}"를 사용하여 반복문을 생성
    • th:text="${data}"에 값을 뿌려줌

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org" lang="en">
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <tr>
        <td>과일목록</td>
    </tr>

    <tr th:each="data : ${list}">
        <td th:text="${data}"></td>
    </tr>

</table>
</body>
</html>

Boot에서 mySQL 테이블 생성하기

VO를 테이블 형태로 설정 (ORM)

  • mySQL에 별도 테이블 생성할 필요없이 VO설정을 통해 신규 테이블 생성가능

  • ORM (하이버 네이트)

    • 오브젝트 + 릴레리션 + 모델의 약자
  • src/main/java/com.example.springboot 경로에 entity 패키지 생성

  • entity 패키지에 Book.java 생성

    • @Entity 어노테이션을 사용함으로써 Book은 테이블이 됨 !
    • @Id로 PK 지정
    • @GeneratedValue() : sql의 시퀀스와 같은 개념 ()에 규칙을 넣어줌
      • (strategy = GenerationType.IDENTITY) : mySQL 인 경우
      • (strategy = GenerationType.SEQUENCE) : 오라클 인 경우

  • 속성들의 도메인 크기를 정해주는 어노테이션
    • @Column(length = 50, nullable = false)
    • 컬럼의 크기는 50, nulldmf = false : not null이라는 조건
package com.example.springboot.entity;

import jakarta.persistence.*;
import lombok.Data;

@Entity
@Data
public class Book { // 책(오브젝트) ---ORM(하이퍼 엔진 설정)---> 테이블(Table)

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 번호 자동증가 규칙
    private Long id; // PK : 1, 2, 3, 4, ....

    @Column(length = 50, nullable = false)
    private  String title; // 책제목
    private  int price;
    @Column(length = 50, nullable = false)
    private  String name; // 저자
    private  int page;
}

JPA 설정


  • 하이버 네이트를 확인가능

  • application.yml 에 하이버 네이트 설정(테이블 생성) 코드 추가
  jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: create
    show-sql: true
    properties:
      hibernate:
        format_sql: true

  • 테이블이 생성된 것을 확인 가능
  • 서버 구동 > mySQL > Book이라는 테이블이 생성된 것을 확인 가능

중요 !

  • 테이블이 이미 있다면 application.yml에서 해당 코드를 update로 수정 !!!

  • 다시 서버 구동시 테이블이 지워지고 새로 만들어지는 순환을 거친다.

    • 테이블이 생성되었다면 반드시 변경 ! ddl-auto: create => update


Rest 방식 적용

BookRestController 생성

  • controller에서 BookRestController.java 생성

repository 패키지 생성

  • 패키지 생성하고 내부에 BookRepository를 인터페이스 파일 형식으로 생성

public interface BookRepository extends CrudRepository

  • 상속받는 extends CrudRepository 에 CRUD의 메소드가 정의되어 있다. (기능을 상속받아서 사용가능 !)

    • CrudRepository 가 부모 -> JpaRepository 가 자식 개념
    • 코드는 주로 JpaRepository 를 자주 사용한다.
    • JpaRepository<Book(테이블 명),Long(PK의 데이터 타입)>
package com.example.springboot.repository;

import com.example.springboot.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;

import java.util.List;
import java.util.Optional;

public interface BookRepository extends JpaRepository<Book,Long> {

    // 1. 정해진 메소드 사용(JpaRepository)
    // findAll() --> select * from Book
    // save() --> insert into 가 된다. 기존에 데이터가 없으면 insert
    // save() --> Update 기능도 한다. 구분은 기존에 데이터가 있으면 update
    // findById(id) --> select * from Book where id = #{id}
    // deleteById(id) --> delete from Book where id = #{id}

    // 2. 쿼리 메소드 사용
    // (find + By + 맴버변수 의 조합으로 생성) -> 여러 조합방식이 있음
    // 책 제목에 해당하는 책 정보 1개를 가지고 오기 -> 해당 메소드를 만들어줘야함
    // --> public Optional<Book> findByTitle(String title);
}
  • find는 select와 관련 있다.
    • findAll() 은 전부 select
    • findAllById() 하나 만 select
  • BookRestController 에서 코드 추가
    @Autowired
    private BookRepository repository;

    //http://localhost:8081/api/book
    @GetMapping("/book")
    public ResponseEntity<?> books(){
        // DB에서 book 정보를 가져오기
        return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
    }

Book 테이블의 데이터 추가하기

  • Postman을 실행하여 (또는 임의로) JSON 값 추가
    {
        "title":"java",
        "price":43000,
        "name":"smart",
        "page":1200
    },
    {
        "id": 2,
        "title": "java",
        "price": 43000,
        "name": "smart",
        "page": 1200
    }


Book 리스트 불러오기

- findAll() --> select * from Book
- save() --> insert into 가 된다.
- findById(id) --> select * from Book where id = #{id}
  • BookRestController 에 코드 추가
	// select All
    @PostMapping("/book")
    public ResponseEntity<?> save(@RequestBody Book book){
        return new ResponseEntity<>(repository.save(book), HttpStatus.CREATED);
    }

	// select where id = ${id}
    @GetMapping("/book/{id}")
    public ResponseEntity<?> findById(@PathVariable Long id){
        return new ResponseEntity<>(repository.findById(id), HttpStatus.OK);
    }
  • Postman 에서 검색 결과 해당 정보를 찾아 볼 수 있다.

데이터 삭제하기

  • BookRestController 코드 추가
    @DeleteMapping("/book/{id}")
    public ResponseEntity<?> deleteById(@PathVariable Long id){
        repository.deleteById(id);
        return new ResponseEntity<>("Deleted...",HttpStatus.OK);
    }


데이터 수정하기

- Optional<Book> optional = repository.findById(id); 
  -> repository.findById(id) 을 통해 결과를 0 또는 1을 받음
  -> 결과가 1일때 관련 Book의 정보를 가져와야함
  -> 이를 모두 허용하는 기능 Optional<Book> 을 쓰임
  -> 결과가 1이면 Book에 대한 정보 값을 가져오겠다.
    @PutMapping("/book/{id}")
    public ResponseEntity<?> update(@PathVariable Long id, @RequestBody Book book){
         Optional<Book> optional = repository.findById(id);
         // optional.isPresent() : optional에 값이 들어 있는지 확인
         if (optional.isPresent()){
             // update 방법 1 :더티체킹 이용
             // 더티체킹을 통해 원본내용이 수정되면 자동으로 업데이트
             Book dbbook = optional.get();
             dbbook.setTitle(book.getTitle());
             dbbook.setPrice(book.getPrice());

             // update 방법 2 : 명시적방법을 이용
             // repository.save(dbbook); 
             
             return new ResponseEntity<>(dbbook, HttpStatus.OK);
         } else {
             return new ResponseEntity<>("Not Found", HttpStatus.NOT_FOUND);
         }
    }

  • postmen 열어서 잘 수정 되는지 확인
    • "title": "Python1997", "price": 19000 으로 변경


쿼리 메소드

  • 책의 특정 이름의 정보만 가져오고 싶은 경우

    • (find + By + 맴버변수 의 조합으로 생성) -> 여러 조합방식이 있음
      • 책 제목에 해당하는 책 정보 1개를 가지고 오기
        - 해당 메소드를 만들어줘야함
        - public Optional findByTitle(String title);

profile
제가 한 번 해보겠습니다.

0개의 댓글