D 드라이브 workspace에 붙여넣기
파일 > 오픈 > 경로 찾기
springboot에 build.gradle 선택
창에서 > open as project > 프로젝트 > new window... 선택 > 오류가 있든 없은 열리기만 하면됨
jsp를 안씀으로 wepapp 폴더가 없음(타임리프로 대체됨)
boot는 메인 어플리케이션부터 시작되는 구조로 되어 있음.
해당 파일의 확장자 변경 -> yml
메인 어플리케이션 에서 구동하면 톰켓도 같이 실행 됨
server:
port: 8081
spring:
datasource:
driver-class-name : com.mysql.cj.jdbc.Driver
url : jdbc:mysql://localhost:3306/ai
username : root
password: 12345
<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})
}
}
<!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>
mySQL에 별도 테이블 생성할 필요없이 VO설정을 통해 신규 테이블 생성가능
ORM (하이버 네이트)
src/main/java/com.example.springboot 경로에 entity 패키지 생성
entity 패키지에 Book.java 생성
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:
database-platform: org.hibernate.dialect.MySQL8Dialect
hibernate:
ddl-auto: create
show-sql: true
properties:
hibernate:
format_sql: true
테이블이 이미 있다면 application.yml에서 해당 코드를 update로 수정 !!!
다시 서버 구동시 테이블이 지워지고 새로 만들어지는 순환을 거친다.
public interface BookRepository extends CrudRepository
상속받는 extends CrudRepository 에 CRUD의 메소드가 정의되어 있다. (기능을 상속받아서 사용가능 !)
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);
}
@Autowired
private BookRepository repository;
//http://localhost:8081/api/book
@GetMapping("/book")
public ResponseEntity<?> books(){
// DB에서 book 정보를 가져오기
return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
}
{
"title":"java",
"price":43000,
"name":"smart",
"page":1200
},
{
"id": 2,
"title": "java",
"price": 43000,
"name": "smart",
"page": 1200
}
- findAll() --> select * from Book
- save() --> insert into 가 된다.
- findById(id) --> select * from Book where id = #{id}
// 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);
}
@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에 대한 정보 값을 가져오겠다.
더티체킹
BookRestController 코드 추가
@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);
}
}
책의 특정 이름의 정보만 가져오고 싶은 경우