국비지원 JAVA(자바) 프로그래밍(스프링부트)
devtools라이브러리
Maven Repository: binaryage » devtools (mvnrepository.com)
implementation 'org.springframework.boot:spring-boot-devtools:3.0.2' 복사붙여넣기
// ↓ 서버재실행 라이브러리, developmentOnly로 개발할 때 만 사용하게끔, 버전 정보를 뺴면 가장 최적화된 버전으로 맞춰서 잡아줌
developmentOnly 'org.springframework.boot:spring-boot-devtools'

빌드 그래들에 추가한 다음 리프레시를 꼭 해야함!
서버 재실행도 시키는 것이 좋음.
https://chrome.google.com/webstore/detail/live-reload/jcejoncdonagmfohjcdgohnmecaipidc
Live Reload
Monitors source files on a page. Reloads the page or just the changed stylesheet when source files are updated.
chrome.google.com
새로 고침 없이 자동으로 웹 재실행
lombok [응답과 요청이있는게 API , 설치해서 끝이면 라이브러리]
https://projectlombok.org/download
Download
projectlombok.org
Maven Repository: org.projectlombok » lombok » 1.18.26 (mvnrepository.com)
LOMBOK @AllArgsConstructor
@AllArgsConstructor
-> 모든 생성자 받아줌
package com.example.sb;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
//생성자 만들어주는 어노테이션 ↓
@AllArgsConstructor
// 기본 생성자 따로 안만들어도 되게끔 하는 어노테이션 ↓
@NoArgsConstructor
public class TestLombok {
private String str;
private int num;
public static void main(String[] args) {
TestLombok tl = new TestLombok();
TestLombok t2 = new TestLombok("hello",20);
tl.setStr("hi");
tl.setNum(50);
System.out.println(tl.getStr());
System.out.println(tl.getNum());
}
}
LOMBOK
Data 어노테이션
package com.example.sb;
import lombok.Data;
@Data
public class TestLombok {
private String str;
private int num;
public static void main(String[] args) {
TestLombok tl = new TestLombok();
tl.setStr("hi");
tl.setNum(50);
System.out.println(tl.getStr());
System.out.println(tl.getNum());
}
}
DB 구축
JPA 라이브러리 이용해서 테이블 만들고 이것저것작업
H2 데이터베이스 사용(실습, 테스트용)
Maven Repository: H2 (mvnrepository.com)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// ↓ 서버재실행 라이브러리, developmentOnly로 개발할 때 만 사용하게끔, 버전 정보를 뺴면 가장 최적화된 버전으로 맞춰서 잡아줌
developmentOnly 'org.springframework.boot:spring-boot-devtools'
//lombok 라이브러리
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
//H2 데이터베이스 사용(실습, 테스트용)
runtimeOnly 'com.h2database:h2'
}
application.properties
# DATABASE
spring.h2.console.enabled=true --> 접속허용
spring.h2.console.path=/h2-console --> url
spring.datasource.url=jdbc:h2:~/local --> 데이터베이스 저장경로
spring.datasource.driverClassName=org.h2.Driver --> 접속드라이버 설정
spring.datasource.username=sa --> 데이터베이스 접속하는 이름(기본값 sa)
spring.datasource.password= -> 데이터베이스 접속하는 비밀번호(기본값은 비어있음)
->
# DATABASE
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.datasource.url=jdbc:h2:d:/local -> 이렇게 고쳤음
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
Entity 엔티티
DB 테이블
단순 질의응답 게시판
테이블 구성
질문테이블 / 탑변테이블
id(질문코드) id(답변코드)
subject(제목) question(질문)
contetn(내용) content(답변내용)
create_date(작성일) create_date(작성일자)
package com.example.sb;
import java.time.LocalDate;
import java.time.LocalDateTime;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; // 질문코드
@Column(length=200) // varchar(200)
private String subject;
@Column(columnDefinition = "TEXT") //VARCHAR 문자를 저장해주는 속성을 지정해줌
private String content;
private LocalDateTime createDate;
}
테이블 만들어짐
answer테이블도 만들기
package com.example.sb;
import java.time.LocalDateTime;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; // 질문코드
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
@ManyToOne // 다대일 외래키 만들기
private Question question;
}
DAO
레포지토리 Repository
question레포지토리
answer레포지토리
여기가 스프링부스트 테스트 가능한 곳
테스트 코드는 Run AS-> junit 에서
junit 에서 테스트할때 본서버는 반드시 끄고 해야함!
위처럼 떠야 정상적인 코드
데이터베이스에서도 확인가능
(JPA레포지토리)
questionRepository = QuestionDAO (메서드 구현)
question테이블의 전체 레코드를 조회
테스트 해보기
package com.example.sb;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private QuestionRepository questionRepository;
@Test
void contextLoads() {
//테스트할 코드를 넣고 확인 가능
List<Question> list = questionRepository.findAll();
System.out.println(list.size());
for(Question q: list) {
System.out.println("제목 : "+q.getSubject());
}
}
}
특정 결과 조회하기
package com.example.sb;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private QuestionRepository questionRepository;
@Test
void contextLoads() {
//테스트할 코드를 넣고 확인 가능
Optional<Question> o = questionRepository.findById(5); // 기본키 기준으로검색
//null 값이 나올수도있으므로 유연하게 대처하기 위해 Optional 사용
Question q = null;
if(o.isPresent()){ //값이 있으면 true, 없으면 false 로 나오는 메서드
q = o.get();
System.out.println(q.getSubject());
System.out.println(q.getContent());
} else {
System.out.println("조회한 결과가 없음");
}
}
}
package com.example.sb;
import org.springframework.data.jpa.repository.JpaRepository;
//↓Question 테이블 클래스기본키 컬럼의 자료형 넣기
public interface QuestionRepository extends JpaRepository<Question, Integer> {
Question findBySubject(String sub);
Question findBySubjectAndContent(String sub, String con);
}
이런식으로 직접 메서드 만들어서
package com.example.sb;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private QuestionRepository questionRepository;
@Test
void contextLoads() {
//테스트할 코드를 넣고 확인 가능
Question q= questionRepository.findBySubjectAndContent("제목", "내용");
System.out.println(q.getId());
System.out.println(q.getCreateDate());
}
}
이런 식으로 확인 가능
findByXXXX-> 리턴 타입 알아서 정해야함
결과물이 여러개 나온다?
List<Question? findByXXXX 이런 느낌으로 만들어야함
findByIdBetween(x,y)
findByIdLessThen(x) x보다 작은거
findByIdLGreaterThen(x)
findByIdGreaterThenEqual(x) 이상
findBySubjectln(배열)
package com.example.sb;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private QuestionRepository questionRepository;
@Autowired
private AnswerRepository answerRepository;
@Test
void contextLoads() {
//테스트할 코드를 넣고 확인 가능
Optional<Question> o =questionRepository.findById(1);
Question q = o.get();
Answer a = new Answer();
a.setContent("1번 답번 내용");
a.setQuestion(q);
a.setCreateDate(LocalDateTime.now());
answerRepository.save(a);
}
}
1번질문에 답변을 추가함
package com.example.sb;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import jakarta.transaction.Transactional;
@SpringBootTest
class SpringbootApplicationTests {
@Autowired
private QuestionRepository questionRepository;
@Autowired
private AnswerRepository answerRepository;
@Transactional //테스트 코드에는 세션이 한번만에 끊겨서 세션유지가 되게끔 테스트 서버에만 이런 어노테이션을 넣음
@Test
void contextLoads() {
//테스트할 코드를 넣고 확인 가능
Optional<Question> o = questionRepository.findById(1);
Question q = o.get();
List<Answer> list= q.getAnswerList(); // list라는 컬렉션에답변이 담김
System.out.println("1번 질문의 답변 개수:"+ list.size());
for(Answer a : list) {
System.out.println("답변 내용 :" + a.getContent());
}
}
}