JPA + Modal 맛보기
2024. 8. 20. 13:58ㆍJSP+Spring Boot
application.properties는 평소대로 작성하되, 추가로 2개 구문 추가
spring.application.name=JPA_Chicken
server.port=9090
spring.datasource.url=jdbc:mysql://localhost:3306/KH_WORKBOOK
spring.datasource.username=root
spring.datasource.password=kh1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mysql 자동으로 테이블을 생성해주는 설정
spring.jpa.hibernate.ddl-auto=update
#sql에서 자동으로 생성이 되고 쿼리가 실행이 잘 되는지 보기
spring.jpa.show-sql=true
그리고 DTO 작성
package com.kh.dto;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Entity
@Getter
@Setter
@ToString
public class Chicken {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY
private int id;
private String chickenName;
private String description;
private double price; //소수점 고려
}
@Entity : mysql에 테이블이 존재하지 않으면 테이블 생성
@Id : 기본키 지정
@GeneratedValue(strategy = GenerationType.IDENTITY) : 시퀀스 지정
그 다음 Repository 생성.
JPA에서 Repository는 일반 스프링부트의 mapper와 mybatis 역할을 함. + Repository도 mapper랑 같이 interface임
CRUD같은 기본 기능은 JpaRepository 안에 모두 들어있음 -> 기본적인 기능은 생략 가능
package com.kh.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.kh.dto.Chicken;
@Repository
public interface ChickenRepository extends JpaRepository<Chicken, Integer>{
}
Service 작성
package com.kh.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kh.dto.Chicken;
import com.kh.repository.ChickenRepository;
@Service
public class ChickenService {
@Autowired
private ChickenRepository chickenRepository;
//치킨 테이블 모두 보기 -> List
public List<Chicken> getAllChickens() {
return chickenRepository.findAll();
}
//치킨 메뉴 추가
public Chicken createChicken(Chicken chicken) {
return chickenRepository.save(chicken); //DTO에 작성된 컬럼들에 모두 삽입
}
}
Service에 입력한 메서드들은 내가 새로 작성한 메서드들이 아니라 JpaRepository가 자체적으로 생성한 메서드.
이제 컨트롤러도 작성
package com.kh.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.kh.dto.Chicken;
import com.kh.service.ChickenService;
@RestController
@RequestMapping("/api/chicken")
public class ChickenController {
@Autowired
private ChickenService chickenService;
@GetMapping
public List<Chicken> getAllChickens() {
return chickenService.getAllChickens();
}
@PostMapping
public Chicken saveChicken(@RequestBody Chicken chicken) {
System.out.println(chicken.toString());
return chickenService.createChicken(chicken);
}
}
이어서 데이터를 넣을 리액트 작성
먼저 메뉴를 DB에 넣을 ChickenForm.js
import React, {useState} from 'react';
import axios from 'axios';
import '../css/ChickenForm.css';
const ChickenForm = () => {
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [price, setPrice] = useState('');
console.log(name);
console.log(description);
console.log(price);
const submitData = {
chickenName : name,
description : description,
price : price
}
const submitBtn = () => {
axios.post("http://localhost:9090/api/chicken", submitData)
.then(res => {
alert("값 들어감");
})
.catch(err => {
alert("안들어감");
})
}
return (
<div className="chickenForm-container">
<label>
메뉴 이름 :
<input value={name} onChange={(e) => setName(e.target.value)}/>
</label>
<label>
메뉴 설명 :
<textarea value={description} onChange={(e) => setDescription(e.target.value)}/>
</label>
<label>
가격 :
<input type="number" value={price} onChange={(e) => setPrice(e.target.value)}/>
<button onClick={submitBtn}>등록하기</button>
<button>메인으로 돌아가기</button>
</label>
</div>
)
}
export default ChickenForm;
그리고 DB에 넣은 메뉴들을 하나씩 꺼내와서 출력할 ChickenList.js
import React, { useState, useEffect } from "react";
import axios from 'axios';
const ChickenList = () => {
const [chickens, setChickens] = useState([]);
useEffect(() => {
axios.get("http://localhost:9090/api/chicken")
.then(res => {
setChickens(res.data); //가져온 데이터를 chickens 변수에 저장
})
.catch(err => {
alert("오류 발생");
})
}, [])
const deleteMenu = (index) => {
setChickens(chickens.filter(chicken => index !== chicken.id));
}
return(
<div className='chicken-container'>
<h1>치킨 메뉴</h1>
<ul>
{chickens.map(chicken => (
<li key={chicken.id}>
{chicken.chickenName} = {chicken.description} = ₩{chicken.price}
<button onClick={() => deleteMenu(chicken.id)}>메뉴삭제</button>
</li>
))}
</ul>
</div>
)
}
export default ChickenList;
여기서 ChickenForm은 Modal로 감싸 특수하게 처리하려고 한다.
먼저 Modal 작성
import '../css/Modal.css';
//버튼을 열거나 닫을 때 동작
const Modal = ({isOpen, onClose, children}) => {
//넘어온 isOpen이 false면 UI가 담긴 return을 보지 않고 컴포넌트 종료 -> 다시 돌려보냄
if(!isOpen) {
return null;
}
return(
<div className="modal-overlay">
<div className="modal-content">
<button className="modal-close" onClick={onClose}>
×
</button>
{children}
</div>
</div>
)
}
export default Modal;
그리고 App.js에서 Modal로 ChickenForm을 감싸준다.
import { useState } from 'react';
import './App.css';
import ChickenForm from './component/ChickenForm';
import ChickenList from './component/ChickenList';
import Modal from './component/Modal';
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
//const에서 동작하는 기능이 1개일 때 { } 생략 가능
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
return (
<div className="app-container">
<ChickenList />
<button onClick={openModal}>메뉴 등록하기</button>
<Modal isOpen={isModalOpen} onClose={closeModal}>
<ChickenForm />
</Modal>
</div>
);
}
export default App;
실행 화면
먼저 폼 화면
등록하면
추가가 된다.
DB에 넣고 출력하는건 이미 여러번 했던거고 오늘의 중점은 JPA와 Modal
'JSP+Spring Boot' 카테고리의 다른 글
공공 데이터 가져오기 (0) | 2024.08.19 |
---|---|
중복 확인하기(ajax) (0) | 2024.07.09 |
이메일 인증 (0) | 2024.06.26 |
마이페이지 조회,수정, 삭제, 검색 (0) | 2024.06.25 |
로그인 (0) | 2024.06.25 |