Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

wintertreey 님의 블로그

@MVC DB연동4 : Spring DATA JPA JpaRepository CRUD 본문

Spring

@MVC DB연동4 : Spring DATA JPA JpaRepository CRUD

wintertreey 2024. 7. 22. 18:06

 

세팅작업 

properties build 체크. 

build 고쳤을경우 build> refresh 필!

 

 

 

package pack.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;


@Data
@Entity
@Table(name="sangdata")
public class Sangpum {
	@Id
	private int code;
	
	@Column(nullable = false)
	private String sang;
	
	private int su;
	private int dan;
	
	// 변수 ff
    //private int ff;  // 이 필드는 DB 테이블에는 존재하지 않음

}

 

@Data

빌드없으면 데이타오케이. 빌드있으면 게터세터. 

 

변수 ff
private int ff;  

 

JPA는 클래스와 테이블 간의 매핑을 할 때, Java 클래스의 필드와 테이블의 컬럼이 1:1 대응할 필요는 없습니다. 즉, 엔티티 클래스에 존재하는 모든 필드가 데이터베이스의 컬럼과 매핑될 필요는 없습니다. ff와 같은 필드는 데이터베이스와 상관없이 JPA 엔티티의 속성으로만 존재할 수 있습니다.

 

ff와 같은 필드는 다음과 같은 목적으로 사용될 수 있습니다:

 

  • 계산된 값: 특정 연산의 결과를 저장하기 위한 임시 변수.
  • 데이터 처리: 비즈니스 로직에서 필요하지만 데이터베이스에는 저장하지 않는 값.
  • DTO와의 변환: 엔티티와 DTO(Data Transfer Object) 간의 변환 시 필요한 속성.

JPA의 연관관계 매핑:

  • ff와 같은 필드는 JPA 엔티티의 상태를 보관하거나 처리하는 용도로 사용될 수 있으며, 데이터베이스에 저장되지 않는 속성입니다.

직급입력하여 해당 직원 찾기 연습문제는 

깃허브의 sprweb15sangpum_jpa_ex를  참고하자.

https://github.com/yoonah0327/spring_source.git

 

GitHub - yoonah0327/spring_source

Contribute to yoonah0327/spring_source development by creating an account on GitHub.

github.com

 


CRUD 작업

세팅작업

application.properties

spring.application.name=sprweb16jpa_mem_crud

server.port=80
spring.thymeleaf.cache=false

#mariadb server connect
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://127.0.0.1:3306/gooddb
spring.datasource.username=root
spring.datasource.password=123

#jpa: hibernate setting
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect

 

 

시작하기

@Controller
public class MemController {
	@Autowired
	private DataProcess dataProcess;
	
	@GetMapping("/")
	public String main() {
		return "chulbal";
	}

 

 

전체보기

	@GetMapping("list")
	public String list(Model model) {
		ArrayList<Mem> slist = (ArrayList<Mem>)dataProcess.getDataAll();
		model.addAttribute("datas", slist);
		return "list";
	}
	//전체 자료 읽기
	public List<Mem> getDataAll(){
		List<Mem> list = memRepository.findAll();
		return list;
	}

 

 

추가하기

 

추가포맷 띄우기

@GetMapping("insert")
	public String insert() {
		return "insert";
	}

 

추가페이지.html

<h3>🥦자료 입력🥦</h3>
<form th:action="@{/insert}" method="post">
번호 : <input type="text" name="num"><br>
이름 : <input type="text" name="name"><br>
주소 : <input type="text" name="addr"><br>
<br>
<input type="submit" value="등록">
</form>

 

포맷에서 작성한 정보 넣어주기.

@PostMapping("insert")
	public String insertProcess(MemBean bean, Model model) {
		String msg = dataProcess.insert(bean);
		
		if(msg.equals("success"))
			return "redirect:/list"; //추가 후 목록보기
		else {
			model.addAttribute("msg", msg);// msg 담아옴. 중복해서실패했다는등의..
			return "error"; //중복혹은실패한경우, 에러메시지던지기.
		}
	}

 

return "redirect:/list";

 

클라이언트에게 새로운 요청을 하게 만들어서 URL을 바꾸고, 새로운 요청을 통해 데이터를 갱신

 

  • 데이터 상태 변경새로운 페이지로 이동할 때 사용합니다. 예를 들어, 데이터베이스에 새로운 데이터가 성공적으로 삽입된 후에는 사용자를 list 페이지로 리다이렉트하여 업데이트된 데이터 목록을 보여줍니다.
  • POST/Redirect/GET 패턴을 사용하여, 폼 제출 후 새로 고침 시 동일한 요청이 반복되지 않도록 방지.

 

 

model.addAttribute("msg", msg);

return "list";

 

리다이렉트 없이 클라이언트에게 list 페이지를 직접 반환

 

  • POST 요청 후 리다이렉트 없이 list 페이지를 반환하면, 클라이언트는 페이지를 새로 고침 할 때 POST 요청이 다시 발생할 수 있습니다. 이는 중복 데이터 삽입 같은 부작용을 일으킬 수 있습니다.
  • 단일 페이지에서 데이터 변경과 표시를 모두 처리하는 경우에는 유용하지만, 데이터 변경 후에는 새로운 상태를 반영하기 위해 리다이렉트가 권장

적절한 상황에 따른 선택

  • 리다이렉트 (return "redirect:/list";): 데이터 변경 후 목록새로 고침하고자 할 때 사용합니다.
    • 예: 데이터 삽입, 삭제, 수정 후 목록 페이지를 보여줄 때.
  • 뷰 반환 (return "list";): 페이지를 새로 생성하거나 다시 렌더링 할 때 사용합니다.
    • 예: 데이터 조회 시 페이지를 보여줄 때.

return "error";

Spring Boot에서 컨트롤러에서 매핑되지 않은 URL에 접근할 때, 기본적으로 404 에러 페이지를 반환하게 됩니다. 
이 404 에러 페이지를 사용자 정의한 error.html로 설정해두셨기 때문에, 수정이나 삭제 작업에 대한 매핑이 없는 URL로 접근하면 자동으로 error.html이 호출되는 것입니다.
이 현상을 이해하려면 몇 가지 중요한 개념을 알아야 합니다.
  컨트롤러 매핑: 컨트롤러에서 특정 URL에 대한 매핑을 정의하지 않으면 Spring Boot는 해당 요청을 처리할 수 없습니다.
  404 Not Found: 매핑되지 않은 URL로 접근하면 Spring Boot는 404 상태 코드를 반환합니다.
  에러 페이지 설정: Spring Boot는 src/main/resources/templates/error.html 파일을 사용하여 기본 에러 페이지를 사용자 정의할 수 있습니다. 
따라서 매핑 에러가 발생하면 이 파일이 호출됩니다.

 

 

 

추가시 @repository  파일

	//추가
	public String insert(MemBean bean) {
    	//num 자동증가
		//int max = memRepository.findByMaxNum();
		
		//num 중복확인
		try {
			Mem mem = memRepository.findById(bean.getNum()).get();
			System.out.println("mem: "+mem);
			return "이미 등록된 번호입니다";
		} catch (Exception e) {
			try {
				Mem mem = new Mem();
				mem.setNum(bean.getNum());
				mem.setName(bean.getName());
				mem.setAddr(bean.getAddr());
				mem = memRepository.save(mem);
				System.out.println("mem: "+mem);
				return "success";
			} catch (Exception e2) {
				return "입력오류: "+ e.getMessage();
			}
		}
	}

 

이번에는 num 중복확인 을 추가하였다. 

 

 

선택자료 읽기

수정 및 삭제를 위해, 선택한 자료1개를 읽어오는 작업을 준비해두자.

//레코드 1개 읽기 : 수정, 삭제시 사용
	public Mem getData(String num) {
		Mem mem = memRepository.findByNum(num);
		return mem;
		
	}
@Query("select m from Mem as m where m.num=?1")
	Mem findByNum(String num);

 

수정하기 

@GetMapping("update")
	public String update(@RequestParam("num") String num, Model model) {
		//System.out.println("num: " + num); //넘어온거확인완료
		
		Mem mem = dataProcess.getData(num);//수정할 자료 읽어오자
		model.addAttribute("data", mem); // 읽어온자료 넣어주자
		return "update";
	}
	@PostMapping("update")
	public String updateProcess(MemBean bean, Model model) {
		String msg = dataProcess.update(bean);
		
		if(msg.equals("success"))
			return "redirect:/list"; //추가 후 목록보기
			
		else {
			model.addAttribute("msg", msg);// msg 담아옴. 중복해서실패했다는등의..
			return "error"; //중복혹은실패한경우, 에러메시지던지기.
		}
	}
//수정
	public String update(MemBean bean) {
		try {
			Mem mem = new Mem();
			mem.setNum(bean.getNum());
			mem.setName(bean.getName());
			mem.setAddr(bean.getAddr());
			mem = memRepository.save(mem);
			return "success";
		} catch (Exception e2) {
			return "수정오류: "+ e2.getMessage();
		}
	}

삭제하기

@GetMapping("delete")
	public String deleteProcess(@RequestParam("num") int num, Model model) {
		String msg = dataProcess.delete(num);
		
		if(msg.equals("success"))
			return "redirect:/list"; //추가 후 목록보기
			
		else {
			model.addAttribute("msg", msg);// msg 담아옴. 중복해서실패했다는등의..
			return "error"; //중복혹은실패한경우, 에러메시지던지기.
		}
	}
//삭제
	public String delete(int num) {
		try {
			memRepository.deleteById(num);
			return "success";
		} catch (Exception e2) {
			return "삭제오류: "+ e2.getMessage();
		}
	}