https://docs.jboss.org/hibernate/orm/5.6/javadocs/org/hibernate/dialect/package-summary.html
org.hibernate.dialect (Hibernate JavaDocs)
An SQL dialect for MariaDB 10.3 and later, provides sequence support, lock-timeouts, etc.
docs.jboss.org
다시 한번 JPA 설정을 해보자
스프링 프로젝트 새로 생성, Controller, Service, Repository, Entity 생성하기
@Controller
public class BoardController {
	// 서비스 -> Service
	// DAO -> Repository
	// DTO -> Entity
	
	@Autowired
	private BoardService boardService;
	
	@GetMapping("/")
	public String index() {
		return "redirect:/board";
	}
	
	@GetMapping("/board")
	public String board() {
		return "board";
	}
}
@Service
public class BoardService {
	@Autowired
	private BoardRepository boardRepository;
}
// Repository
public interface BoardRepository extends JpaRepository<JPABoard, Integer> {
}
@Entity
@Getter
@Setter
public class JPABoard {
	// JPA 에서 주의해야할 점
	// 언더바, 언더스코어 "_" 를 못 씀, 인식 오류
	
	@Id // PK 설정
	@GeneratedValue(strategy = GenerationType.IDENTITY) // Auto_increment 설정
	private int jbno;
	
	// Column 의 도메인을 지정할 수 있음 (도메인 : 해당 칼럼의 제약 조건)
	@Column(columnDefinition = "TEXT")
	private String jbtitle;
	
	@Column(columnDefinition = "LONGTEXT")
	private String jbcontent;
	
	// Column 의 기본 값 설정, 여기서는 행이 삽입될 때의 시간을 입력
	@ColumnDefault("CURRENT_TIMESTAMP")
	private LocalDateTime jbdate = LocalDateTime.now();
	
	@ColumnDefault("0")
	private int jblike;
	
	@ColumnDefault("1")
	private int jbread;
}
여기서 테이블이 없는 상태로 서버 실행 시 자동으로 테이블을 생성해 줌

데이터 출력해보기
Controller, Service, Repository 연결하기
// Controller
List<JPABoard> list = boardService.boardList();
// Service
public List<JPABoard> boardList() {
  return boardRepository.findAll();
}
// Repository
Repository 는 할 것이 없음, Controller 에서 Model 로 넘기기

title 클릭 시 detail 로 연결해보기
두가지 방법으로 링크할 수 있음
<td th:onclick="|location.href='@{detail(no=${j.jbno})}'|" th:text="${j.jbtitle}"></td>
<td><a th:text="${j.jbtitle}" th:href="@{detail(no=${j.jbno})}"></a></td>
Detail 창을 열어보자
DB 에서 모든 값을 받아오는 것이 아닌 하나만 가져오기
// Controller
@GetMapping("/detail")
  public String detail(@RequestParam("no") int no, Model model) {
    JPABoard detail = boardService.detail(no);
    model.addAttribute("detail", detail);
    return "detail";
  }
BoardService 에서 값 받기
원래 JpaRepository 에 있는 findById() 를 이용하면 Optional 로 객체를 받아야 하기 때문에
BoardRepository 에 findByJbno() 라는 메소드를 추가 생성
findBy + 찾고 싶은 칼럼명을 입력하면 해당 칼럼을 기준으로 해서 값을 찾음
// Service
public JPABoard detail(int no) {
  // Optional<JPABoard> detail = boardRepository.findById(no);
  JPABoard detail = boardRepository.findByJbno(no);
  return detail;
}
// Repository
JPABoard findByJbno(int no);
값이 정상 출력되는 모습을 확인할 수 있음, SQL 은 자동으로 실행됨


글 작성하기
write.html 생성
<form action="/write" method="post">
  <input type="text" name="jbtitle"/>
  <textarea name="jbcontent"></textarea>
  <button type="submit">작성</button>
</form>
Controller 에 Get, Post 다 생성하기
@GetMapping("/write")
public String write() {
  return "write";
}
	
@PostMapping("/write")
public String write(@RequestParam Map<String, Object> map) {
  JPABoard board = new JPABoard();
  board.setJbtitle((String)map.get("jbtitle"));
  board.setJbcontent((String)map.get("jbcontent"));
  boardService.write(board);
  return "redirect:/board";
}
BoardService 에 값 저장 넘기기
public void write(JPABoard board) {
  boardRepository.save(board);
}
==> 실제 저장된 값 확인해보기


실제 적용되는 쿼리문

JPABoard, Entity 에 객체 생성 시 기본 값을 대입하면 해결할 수 있음
@ColumnDefault("0")
private int jblike = 1;
	
@ColumnDefault("1")
private int jbread = 1;
글 삭제하기
detail.html 에 삭제 버튼 추가하기
<h1>DETAIL</h1>
<h3 th:text="${detail.jbtitle}"></h3>
<button th:onclick="|location.href='@{postDel(no=${detail.jbno})}'|">삭제</button>
Controller 에서 값을 받아 넘기기
@GetMapping("/postDel")
public String postDel(@RequestParam("no") int no) {
  // 첫 번째 방법
  boardService.postDel(no);
  
  // 두 번째 방법
  JPABoard board = new JPABoard();
  board.setJbno(no);
  boardService.postDel2(board);
  return "redirect:/board";
}
Controller 에서 값을 넘기는 2가지 방법으로 삭제할 수 있음
하나는 PK 의 value 값만 받아서 삭제하는 방법과 객체를 넘겨 삭제하는 방법
여기서는 둘 다 jbno 값만 넘겨 쿼리문은 동일하게 작동
public void postDel(int no) {
  boardRepository.deleteById(no);
}
public void postDel2(JPABoard board) {
  boardRepository.delete(board);
}

글 수정하기
detail.html 에 update 버튼 추가
<button th:onclick="|location.href='@{update(no=${detail.jbno})}'|">수수정</button>
GetMapping 으로 받기
@GetMapping("/update")
public String update(@RequestParam("no") int no, Model model) {
  JPABoard detail = boardService.detail(no);
  model.addAttribute("detail", detail);
  return "write";
}
update.html 을 만들어서 편하게 해도 되지만
하나의 write.html 을 가지고 사용해보았지만.. 그냥 따로 html 만드는게 편한 것 같음
<th:block th:if="${detail ne null}">
  <form action="/update" method="post">
</th:block>
<th:block th:unless="${detail ne null}">
  <form action="/write" method="post">
</th:block>
  <th:block th:if="${detail ne null}">
    <input type="text" name="jbtitle" th:value="${detail.jbtitle}"/>	
  </th:block>
  <th:block th:unless="${detail ne null}">
    <input type="text" name="jbtitle"/>
  </th:block>	
  <textarea name="jbcontent"><th:block th:if="${detail ne null}">[(${detail.jbcontent})]</th:block></textarea>
  <th:block th:if="${detail ne null}">
    <input type="hidden" name="jbno" th:value="${detail.jbno}"/>	
  </th:block>
  <button type="submit">작성</button>
</form>
Post 로 값 받기
@PostMapping("/update")
public String update(@RequestParam("jbtitle") String jbtitle,
                      @RequestParam("jbcontent") String jbcontent,
                      @RequestParam("jbno") int jbno) {
  JPABoard post = new JPABoard();
  post.setJbtitle(jbtitle);
  post.setJbcontent(jbcontent);
  post.setJbno(jbno);
  boardService.update(post);
		
  return "redirect:/detail?no=" + jbno;
}
Service 에서 update 하기, save 는 PK 가 없으면 insert, PK 가 있으면 update 로 진행됨
public void update(JPABoard post) {
  boardRepository.save(post);
}
Board 에서 역순으로 정렬해보기
BoardService 에서 메소드 하나 생성하기
// 기존 findAll() 을 findAllByOrderByJbnoDesc() 로 변경
public List<JPABoard> boardList() {
  // return boardRepository.findAll();
  return boardRepository.findAllByOrderByJbnoDesc();
}
==> BoardRepository 에서 메소드 생성, JPA 에서 메소드 이름을 인식하여 자동 생성함
List<JPABoard> findAllByOrderByJbnoDesc();
직접 Query 써보기
@Query(value = "SELECT * FROM jpaboard j where j.jbno=?1", nativeQuery = true)
JPABoard findByJbno(int no);
==> ?1 의 뜻은 해당 물음표에 첫 번째 파라미터 값을 넣는다는 뜻
Join 걸어보기
JPA @OneToMany, @ManyToOne으로 연관관계 관리하기
안녕하세요, 오늘은 스프링을 이용하면서 자주 쓰는 JPA에 대해서 이야기해보려고 합니다. JPA는 스프링 개발을 하면서 이제 거의 필수가 된 ORM 기술입니다. @OneToMany, @ManyToOne 어노테이션은 1:N, N:1
velog.io
JPABoard 에 아래 어노테이션 추가
@ManyToOne
@JoinColumn
private JPAMember jpaMember;
하면 JPABoard 에서 JPAMember 의 PK 값을 참조

/write 의 Post 수정해보기
@PostMapping("/write")
public String write(@RequestParam Map<String, Object> map) {
  JPABoard board = new JPABoard();
  board.setJbtitle((String)map.get("jbtitle"));
  board.setJbcontent((String)map.get("jbcontent"));
		
  JPAMember member = new JPAMember();
  // 우리가 알고 있는 것은 세션에 등록된 mid 이므로, member 객체에 세팅 후 추가
  member = boardService.findByJmid("1234");
  board.setJpaMember(member);
		
  boardService.write(board);
  return "redirect:/board";
}

board 테이블의 값 확인해보기

게시글 목록에서 작성자 출력하기
==> JPABoard 객체에 JPAMember 객체가 담겨져 List 로 들어감
List<JPABoard> list = boardService.boardList();
model.addAttribute("list", list);==> 객체의 jpaMember 객체의 jmname 을 열어서 조회 가능
<td th:text="${j.jpaMember.jmname}"></td>
'Spring' 카테고리의 다른 글
| Log 찍기 (0) | 2024.07.17 | 
|---|---|
| 240315 도커 (0) | 2024.03.15 | 
| 240313 스프링 부트 (1) | 2024.03.13 | 
| 240312 스프링 부트 (0) | 2024.03.12 | 
| 240311 스프링 부트 (0) | 2024.03.11 | 
 
                  
                 
                  
                 
                  
                