Spring/Spring framework

[JPA] boot3 데이터 DB 입출력

원2 2021. 8. 6. 12:23
728x90
반응형

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods

JPA keyword는 여기서 찾자!

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io


프로젝트 구성

 


application.properties에 Mysql 값 설정

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jpadb?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=1234

#ddl : Data Definition Language : 데이터 정의 -> create 
#아래 코드는 JPA 코드 자동생성이라서 한번 생성시키고 주석처리
#spring.jpa.hibernate.ddl-auto=create

spring.jpa.hibernate.ddl-auto=update
#DDL 생성시 DB 고유의 기능을 사용
spring.jpa.generate-ddl=false
#실행시 Console에 SQL문 출력
spring.jpa.show-sql=true
spring.jpa.database=mysql
#mysql 상세지정
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Board
추가 내용 @ToString(exclude = "변수") 하면 해당 변수는  ToString이 안먹히고 값이 도출되지 않음, 또한 ToString 어노테이션을 하지 않으면 객체의 값이 아니라 주솟값이 출력된다.

package com.bit.domain;

import java.sql.Timestamp;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
//	JPA에 필요한 어노테이션 Entity는 JPA가 관리한다는 개념, Table은 Entity와 매핑할 테이블을 설정
@Entity
@Table(name = "tbl_boards")
public class Board {
	
//	Id는 프로퍼티가 테이블의 Pk 역할을 한다는것을 나타낸다.
//	GeneratedValue는 주키(KEY)의 값을 위한 자동 생성 전략을 명시, db의 IDENTITY 컬럼을 이용한다.
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long bno;
	private String title;
	private String writer;
	private String content;
	
//	CreationTimestamp 는 [INSERT 쿼리가 발생할 때], 시간을 값으로 채워서 쿼리를 생성
	@CreationTimestamp
	private Timestamp regdate;

//	UpdateTimestamp 는 [UPDATE 쿼리가 발생할 때], 시간을 값으로 채워서 쿼리를 생성
	@UpdateTimestamp
	private Timestamp updatedate;
	
	
}

BoardRepository.java (interface)

package com.bit.persistence;

import java.util.Collection;
import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.bit.domain.Board;

public interface BoardRepository extends CrudRepository<Board, Long> {

//	findBy ~ : select where 절
// 	title 조건으로 검색
//	ID같은 경우는 PK라서 다른 방식으로 출력하지만 타이틀은 PK가 아니라서 List 형식으로 출력해야한다.
	
	public List<Board> findByTitle(String title);
	
	public Collection<Board> findByWriter(String writer);
	
	public List<Board> findByContent(String writer);
//	public List<Board> findByContent(String content);
	
//	title에 '7'이 들어가 있는 레코드 검색
	public List<Board> findByTitleContaining(String title);
	
//	content에 '9 채우기' 로 끝나는 레코드 검색
	public List<Board> findByContentEndingWith(String content);
	
//	writer에 '7'로 끝나는 레코드 검색
	public List<Board> findByWriterEndingWith(String title);
	
//	title에서 '제목...2' 시작하는 레코드 검색
	public List<Board> findByTitleStartingWith(String title);
}

두개의 Keyword도 잘 먹힌다.

BoardRepository2.java (interface)
수정된 버젼

package com.bit.persistence;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.bit.domain.Board;

public interface BoardRepository2 extends CrudRepository<Board, Long>{

//	title과 writer : or 조건
	public List<Board> findByTitleOrWriter(String title, String writer);
	
//	title과 content : and 조건
	public List<Board> findByTitleAndContent(String title, String content);
	
//	bno between 10 and 20
	public List<Board> findByBnoBetween(Long bno, Long bno1);
	
//	bno > 50
	public List<Board> findByBnoAfter(Long bno);
	
//	bno <= 100
	public List<Board> findByBnoLessThanEqual(Long bno);
	
//	or&like : title like '%제목...6%' or content like '%내용...6 채우기%'
	public List<Board> findByTitleOrContent (String title, String content);
	
//	like&and :title like '%제목...6%' and bno >10
	public List<Board> findByTitleAndBnoGreaterThan (String title, Long bno);
	
//	>&desc : bno > 150 order by bno desc
	public List<Board> findByBnoAfterOrderByBnoDesc (Long bno);
}
package com.bit.persistence;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.bit.domain.Board;

public interface BoardRepository2 extends CrudRepository<Board, Long>{

//	title과 writer : or 조건
	public List<Board> findByTitleOrWriter(String title, String writer);
	
//	title과 content : and 조건
	public List<Board> findByTitleAndContent(String title, String content);
	
//	bno between 10 and 20
	public List<Board> findByBnoBetween(Long bno, Long bno1);
	
//	bno > 50
	public List<Board> findByBnoAfter(Long bno);
	
//	bno <= 100
	public List<Board> findByBnoLessThanEqual(Long bno);
	
//	or&like : title like '%제목...6%' or content like '%내용...6 채우기%'
	public List<Board> findByTitleContainingOrContentContaining (String title, String content);
	
//	like&and :title like '%제목...6%' and bno >10
	public List<Board> findByTitleContainingAndBnoGreaterThan (String title, Long bno);
	
//	>&desc : bno > 150 order by bno desc
	public List<Board> findByBnoGreaterThanOrderByBnoDesc (Long bno);
}

BoardRepository.java와 연결

BoardRepositoryTests

 

package com.bit;

import java.util.Collection;
import java.util.List;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.bit.domain.Board;
import com.bit.persistence.BoardRepository;

//확장을 선언적으로 등록하는데 사용. 뒤에 ()는 스프링을 사용해서 고정
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class BoardRepositoryTests {

//	주입
	@Autowired
	BoardRepository repo;
	
//	@Test는 JUnit 사용하기위함 테스트용
	
	@Test
	public void testCreate ()  {
		System.out.println("테이블 생성");
	}
	
//	JpaRepository의 save()는 단순히 새 엔터티를 추가하는 메소드가 아니다.
//	save()는 업데이트를 위한 용도로도 사용될 수 있다.
//	더비 data 200개 입력
	@Test
	public void testInsert200() {
		for(int i = 0; i < 200; i++) {
			Board board = new Board();
			board.setTitle("제목 ..."+ i);
			board.setContent("내용..."+ i +"채우기");
			board.setWriter("user0" + (i%10)); // user00 user01... user09 반복
			repo.save(board);
		}
	}
	
	@Test
	public void testByTitle() {
//		before 버전
		List<Board> results = repo.findByTitle("제목 ...177");
		for(int i = 0; i < results.size(); i++) {
			Board board = results.get(i);
			System.out.println(board);
		}
		System.out.println("----------------------");
		for (Board board : results) {
			System.out.println(board);
		}
		System.out.println("람다 방식1----------------------");
		results.forEach(board->System.out.println(board));
	}
	
	@Test
	public void testWriter() {
		Collection<Board> results = repo.findByWriter("user00");
		results.forEach(board->System.out.println(board));
		System.out.println("-------------------------------");
		repo.findByWriter("user00").forEach(board->System.out.println(board));
	}
	@Test
	public void testContent() {
		repo.findByContent("내용...0채우기").forEach(board->System.out.println(board));
	}
	
//	Containing : like %7%
	@Test
	public void testByTitleContaining() {
		repo.findByTitleContaining("7").forEach(board->System.out.println(board));
	}
	
//	EndingWith : like '%9% 채우기'
	@Test
	public void testByContentEndingWith() {
		repo.findByContentEndingWith("9채우기").forEach(board->System.out.println(board));
	}
	
//	7로 끝나는 
	@Test
	public void testByWriterEndingWith() {
		repo.findByWriterEndingWith("7").forEach(board->System.out.println(board));
	}
	
//	StartingWith : like '제목...2%'로 시작하는
	@Test
	public void testByTitleStartingWith() {
		repo.findByTitleStartingWith("제목 ...2").forEach(board->System.out.println(board));
	}
	

}

BoardRepository2.java (interface) 와 연결

BoardRepositoryTests2
BoardRepositoryTests2 확대한 사진
수정된 버젼

두개의 Keyword도 잘 먹힌다.

package com.bit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.bit.persistence.BoardRepository2;

//확장을 선언적으로 등록하는데 사용. 뒤에 ()는 스프링을 사용해서 고정
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class BoardRepositoryTests2 {

//	주입
	@Autowired
	BoardRepository2 repo;

//	Hibernate: select board0_.bno as bno1_0_, board0_.content as content2_0_, board0_.regdate as regdate3_0_, board0_.title as title4_0_, board0_.updatedate as updateda5_0_, board0_.writer as writer6_0_ from tbl_boards board0_ where board0_.title=? or board0_.writer=?
//	이 쿼리문이 아래 메소드로 대체  쿼리의 _ 표시는 알리아스
	@Test
	public void testByTitleOrWriter() {
		repo.findByTitleOrWriter("제목 ...167", "user07").forEach(board -> System.out.println(board));
	}

	@Test
	public void testByTitleAndContent() {
		repo.findByTitleAndContent("제목 ...195", "내용...195채우기").forEach(board -> System.out.println(board));
	}

//	람다식2
	@Test
	public void testByBneBetween() {
		repo.findByBnoBetween(10L, 20L).forEach(System.out::println);
	}

	@Test
	public void testByBnoAfter() {
		repo.findByBnoAfter(50L).forEach(System.out::println);
	}

	@Test
	public void testByBnoLessThanEqual() {
		repo.findByBnoLessThanEqual(100L).forEach(System.out::println);
	}

//	or&like : title like '%제목...6%' or content like '%내용...6 채우기%'
	@Test
	public void testByTitleOrContent() {
		repo.findByTitleOrContent("제목 ...6", "내용...6채우기").forEach(System.out::println);
	}

//	like&and :title like '%제목...6%' and bno >10
	@Test
	public void testByTitleAndBnoGreaterThan() {
		repo.findByTitleAndBnoGreaterThan("제목 ...6", 10L).forEach(System.out::println);
	}
	
//	>&desc : bno > 150 order by bno desc
	@Test
	public void testByBnoAfterOrderByBnoDesc() {
		repo.findByBnoAfterOrderByBnoDesc(150L).forEach(System.out::println);
	}
}
package com.bit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.bit.persistence.BoardRepository2;

//확장을 선언적으로 등록하는데 사용. 뒤에 ()는 스프링을 사용해서 고정
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class BoardRepositoryTests2 {

//	주입
	@Autowired
	BoardRepository2 repo;

//	Hibernate: select board0_.bno as bno1_0_, board0_.content as content2_0_, board0_.regdate as regdate3_0_, board0_.title as title4_0_, board0_.updatedate as updateda5_0_, board0_.writer as writer6_0_ from tbl_boards board0_ where board0_.title=? or board0_.writer=?
//	이 쿼리문이 아래 메소드로 대체  쿼리의 _ 표시는 알리아스
	@Test
	public void testByTitleOrWriter() {
		repo.findByTitleOrWriter("제목 ...167", "user07").forEach(board -> System.out.println(board));
	}

	@Test
	public void testByTitleAndContent() {
		repo.findByTitleAndContent("제목 ...195", "내용...195채우기").forEach(board -> System.out.println(board));
	}

//	람다식2
	@Test
	public void testByBneBetween() {
		repo.findByBnoBetween(10L, 20L).forEach(System.out::println);
	}

	@Test
	public void testByBnoAfter() {
		repo.findByBnoAfter(50L).forEach(System.out::println);
	}

	@Test
	public void testByBnoLessThanEqual() {
		repo.findByBnoLessThanEqual(100L).forEach(System.out::println);
	}

//	or&like : title like '%제목...6%' or content like '%내용...6 채우기%'
	@Test
	public void testByTitleContainingOrContentContaining() {
		repo.findByTitleContainingOrContentContaining("제목 ...6", "내용...6채우기").forEach(System.out::println);
	}

//	like&and :title like '%제목...6%' and bno >10
	@Test
	public void testByTitleContainingAndBnoGreaterThan() {
		repo.findByTitleContainingAndBnoGreaterThan("제목 ...6", 10L).forEach(System.out::println);
	}
	
//	>&desc : bno > 150 order by bno desc
	@Test
	public void testByBnoGreaterThanOrderByBnoDesc() {
		repo.findByBnoGreaterThanOrderByBnoDesc(150L).forEach(System.out::println);
	}
}

결과

Console 창에 잘 나온다ㅎㅎ Hibernate는 쿼리
데이터는 200개 넣는 메소드로 넣어뒀다.

728x90
반응형

'Spring > Spring framework' 카테고리의 다른 글

JPA  (0) 2021.08.09
boot04 회원게시판  (0) 2021.08.09
[JPA] boot3 데이터 DB 입출력  (0) 2021.08.09
환경오류  (0) 2021.08.06
Entity  (0) 2021.08.05
@Id @GeneratedValue  (0) 2021.08.05