https://velog.io/@52future/DataGrip
데이터베이스 IDE DataGrip 학생 인증하여 무료로 사용하기
DataGrip 이라는 데이터베이스 관리 툴을 소개합니다.JetBrains에서 제공하는 이 툴은 다양한 DBMS 와의 연동이 가능하고 .학교 이메일이 있다면 학생 인증을 통해서 무료 라이선스로 사용 가능하다는
velog.io
학생계정으로 가입하고 datagrip 사용했습니다!
그리고 처음에 vscode로 진행했는데 스프링은 intellj로 따라가는게 좋을 것 같아요.. datagrip 설치할 때 만든 학생계정으로 intellj ultimate 설치하기 !
1. 부트 프로젝트 생성 및 확인
apiserver 프로젝트를 먼저 생성하고 진행했다.
데이터베이스 설정이 되어있지 않아서 처음에 실행을 하면 오류가 난다.
따라서 apidb라는 이름으로 먼저 데이터베이스를 생성하고
CREATE USER 'apidbuser'@'localhost' IDENTIFIED BY 'apidbuser';
CREATE USER 'apidbuser'@'%' IDENTIFIED BY 'apidbuser';
GRANT ALL PRIVILEGES ON apidb.* TO 'apidbuser'@'localhost';
GRANT ALL PRIVILEGES ON apidb.* TO 'apidbuser'@'%';
SQL 스크립트를 실행한다.
- 'apidbuser'@'localhost': 이 사용자는 로컬에서만 접속할 수 있음
- 'apidbuser'@'%': 이 사용자는 원격에서 접속할 수 있도록 설정됨
- 두 사용자 모두 비밀번호는 'apidbuser'로 설정
- 'apidbuser'@'localhost' 사용자에게 apidb 데이터베이스에 대한 모든 권한을 부여
- 'apidbuser'@'%' 사용자에게도 같은 권한을 부여
datagrip으로 만들어둔 apidb 연결
SELECT now();
현재 시간을 확인해서 설정이 잘 되었는지 확인
spring.application.name=apiserver
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/apidb
spring.datasource.name=apidbuser
spring.datasource.password=apidbuser
application.properties 작성 -> 가장 기본적인 설정을 추가한 것
커넥션 풀 : 미리 만들어놓고 재사용하는 것
나는 실행이 안 돼서 main을 지정하고 실행함
spring.application.name=apiserver
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/apidb
spring.datasource.username=apidbuser
spring.datasource.password=apidbuser
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
logging.level.com.zaxxer=trace
- JDBC 드라이버 클래스와 MariaDB 데이터베이스의 URL을 지정
- 데이터베이스에 접속할 때 사용할 데이터베이스 사용자 이름과 비밀번호 지정
- Hibernate: 애플리케이션 실행 시 데이터베이스 스키마를 어떻게 처리할지 결정하는 설정
- update: 기존 테이블에 변경 사항이 있으면 이를 업데이트함
logging.level.com.zaxxer=trace
로그로 잘 설정되었는지 확인
2. 엔티티 클래스 만들기
엔티티는 클래스와 객체를 구분해서 만들어야 함
domain 패키지에 Todo 클래스 생성
package org.zerock.apiserver.domain;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@ToString
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name="tbl_todo")
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long tno;
private String title;
private String content;
private boolean complete;
private LocalDateTime dueDate;
}
JPA(Entity)로 사용되는 Todo 클래스
Todo 엔티티는 데이터베이스 테이블과 매핑되며, 각 필드는 테이블의 컬럼으로 매핑됨
실행하면 위와 같이 tbl_todo 테이블이 생성됨
업데이트를 하면 테이블이 2개가 생기기 때문에 정리를 해야 함
todo 테이블을 drop함
interface를 생성
3. 엔티티의 테스트
build.gradle에서 Lombok을 테스트 코드에서 사용할 수 있도록 설정하기 위해 아래 두 코드를 추가해야 함
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
@Test
public void testInsert() {
Todo todo = Todo.builder()
.title("Title")
.content("Content...")
.dueDate(LocalDate.of(2024, 10, 01).atStartOfDay())
.build();
Todo result = todoRepository.save(todo);
log.info(result);
}
testInsert() 테스트 메서드는 Todo 엔티티 객체를 생성하고 이를 데이터베이스에 저장한 후 저장된 결과를 로그에 출력함
@Test
public void testRead() {
Long tno = 1L;
Optional<Todo> result = todoRepository.findById(tno);
Todo todo = result.orElseThrow();
log.info(todo);
}
testRead() 메서드는 특정 tno(Primary Key)를 사용해 데이터베이스에서 Todo 엔티티를 조회함
package org.zerock.apiserver.domain;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@ToString
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name="tbl_todo")
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long tno;
private String title;
private String content;
private boolean complete;
private LocalDateTime dueDate;
public void changeTitle(String title) {
this.title = title;
}
public void changeContent(String content) {
this.content = content;
}
public void changeComplete(boolean complete) {
this.complete = complete;
}
public void changeDueDate(LocalDateTime dueDate) {
this.dueDate = dueDate;
}
}
이제 업데이트를 진행하기 위해 Todo.java에서 setter 설정을 해준다.
각 필드를 변경하기 위한 것!
@Test
public void testUpdate() {
//먼저 로딩하고 엔티티 객체를 변경 (setter
Long tno = 1L;
Optional<Todo> result = todoRepository.findById(tno);
Todo todo = result.orElseThrow();
todo.changeTitle("Update Title");
todo.changeContent("updated content");
todo.changeComplete(true);
todoRepository.save(todo);
}
먼저 select할 때 sql문이 실행되고 save할 때 다시 확인을 한다. 그리고 update문이 실행되는 것을 확인할 수 있다.
그리고 다시 read 테스트를 진행하면 업데이트가 된 것을 확인할 수 있다.
4. 목록(페이징)처리 구현
@Test
public void testPaging() {
// 페이지 번호는 0부터 시작함
Pageable pageable = PageRequest.of(0, 10, Sort.by("tno").descending());
Page<Todo> result = todoRepository.findAll(pageable);
log.info(result.getTotalElements());
log.info(result.getContent());
}
페이지 데이터를 가지고 올 때 데이터가 10개가 되지 않아서 count query를 보내지 않는다.
@Test
public void testInsert() {
for (int i = 0; i < 100; i++) {
Todo todo = Todo.builder()
.title("Title"+i)
.content("Content..."+i)
.dueDate(LocalDate.of(2024, 10, 01).atStartOfDay())
.build();
Todo result = todoRepository.save(todo);
log.info(result);
}
}
따라서 for문을 추가함
이제 위와 같이 count가 나타나는 것을 확인할 수 있음
다시 testpaging을 실행해 보면 출력이 하나 더 생기고 전체 데이터는 101건이 있는 것을 알 수 있음
5. Querydsl 설정하기
해외에서는 jooq를 많이 사용하지만 우리나라는 querydsl을 대부분 사용한다.
https://cafe.naver.com/gugucoding
구멍가게코딩단 : 네이버 카페
안녕하세요? 구멍가게 코딩단의 활동을 위한 카페입니다.
cafe.naver.com
카페 자료를 보고 gradle 코드를 수정함
compile.Jave를 실행하면 QTodo가 생성되어야 함
QueryDSL을 사용하는 경우 자동으로 생성되는 클래스
Q로 시작하는 클래스는 QueryDSL이 엔티티 클래스(Todo)에 대해 생성한 메타데이터 클래스이며, 이를 통해 타입 안전한 쿼리를 작성할 수 있음
package org.zerock.apiserver.repository.search;
import org.springframework.data.domain.Page;
import org.zerock.apiserver.domain.Todo;
public interface TodoSearch {
Page<Todo> search1();
}
TodoSearch 인터페이스 생성
동적 처리
package org.zerock.apiserver.repository.search;
import com.querydsl.jpa.JPQLQuery;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.zerock.apiserver.domain.QTodo;
import org.zerock.apiserver.domain.Todo;
@Log4j2
public class TodoSearchImpl extends QuerydslRepositorySupport implements TodoSearch {
protected TodoSearchImpl() {
super(Todo.class);
}
@Override
public Page<Todo> search1() {
log.info("search1..................");
QTodo todo = QTodo.todo;
JPQLQuery<Todo> query = from(todo);
query.where(todo.title.contains("1"));
Pageable pageable = PageRequest.of(0, 10, Sort.by("tno").descending());
this.getQuerydsl().applyPagination(pageable, query);
query.fetch(); //목록 데이터
query.fetchCount();
return null;
}
}
TodoSearchImpl.java
@Test
public void testSearch1(){
todoRepository.search1();
}
test 코드 추가 후 실행
count까지 출력되는 것을 확인
=> TodoSearchImpl 클래스는 TodoSearch 인터페이스를 구현하며, QueryDSL을 사용해 동적 쿼리를 실행함
페이징된 결과를 반환하고 있음
TodoRepositoryTests는 데이터베이스 작업을 테스트하는 메서드들을 정의하고 있는데, testSearch1()을 추가하여 검색 기능을 확인함
'Web' 카테고리의 다른 글
5. 상품 API 서버 구성하기 - 1 (0) | 2024.10.08 |
---|---|
4. 리액트와 API 서버 통신 (0) | 2024.10.06 |
3. 스프링부트와 API 서버 - 2 (0) | 2024.10.02 |
2. React-Router (0) | 2024.09.24 |
1. 개발환경 설정 (0) | 2024.09.24 |