12. 스프링부트(블로그만들기) 다시 새로 만들어서 리팩토링하자 V3 3.1

윤주헌's avatar
Sep 11, 2024
12. 스프링부트(블로그만들기) 다시 새로 만들어서 리팩토링하자 V3 3.1

먼저 레파지토리 위에 있는 트렌잭션 다 빼자 서비스에서 하니까

완전 새로 할거다

🌟
한 것과 이제 할 것들
 
 
왜 서버 리로드를 하는건가? 저장하면 .class로 컴파일 되는데 컴파일 된거를 jar파일로(실행파일로) 패키징해야 되고 아파치 웹 서버에 배포가 되야한다(디플로이)
컴파일된 파일만 있다고 배포가 되는게 아니다.
서버 리로드 하면 디플로이가 된다! 그래서 한다

기본 틀!

1.라이브러리 세팅

aop는 없어서 체크 못함..
프로젝트 만들고
추가 설정!
notion image

2. 빌드 그레이들 가서 aop 추가

implementation 'org.springframework.boot:spring-boot-starter-aop'
오른쪽 위 코끼리 꼭 추가하기!!

3. application 컨트롤 s 컨트롤 v로 복사하고

notion image
notion image
만들기
notion image

3.2 어플리케이션 프로퍼티 가서

notion image
notion image
dev 개발 모든
active dev해서 dev가 작동한다
prod는 mysql로 바꿔야 하고
설정들을 나눠서 사용한다

3.3 데브 프로퍼티에 추가

# 1. UTF-8 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.force=true # 2. H2 spring.datasource.driver-class-name=org.h2.Driver spring.datasource.url=jdbc:h2:mem:test spring.datasource.username=sa # 3. Hibernate spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.defer-datasource-initialization=true # 4. Dummy spring.sql.init.data-locations=classpath:db/data.sql # 5. Mustache Setting spring.mustache.servlet.expose-request-attributes=true spring.mustache.servlet.expose-session-attributes=true # 6. Query Format spring.jpa.properties.hibernate.format_sql=true # 7. OpenInView spring.jpa.open-in-view=false
배포시 필요 없는 것
spring.datasource.driver-class-name=org.h2.Driver spring.datasource.url=jdbc:h2:mem:test spring.datasource.username=sa spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.defer-datasource-initialization=true spring.sql.init.data-locations=classpath:db/data.sql

3.4 prod에 추가

# 1. UTF-8 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.force=true # 2. H2 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/blogdb spring.datasource.username=root spring.datasource.password=root1234 # 3. Hibernate spring.jpa.hibernate.ddl-auto=none # 4. Mustache Setting spring.mustache.servlet.expose-request-attributes=true spring.mustache.servlet.expose-session-attributes=true # 5. OpenInView spring.jpa.open-in-view=false

4. db만들기

notion image
insert into user_tb(username, password, email, created_at) values ('ssar', '1234', 'ssar@nate.com', now()); insert into user_tb(username, password, email, created_at) values ('cos', '1234', 'cos@nate.com', now()); insert into user_tb(username, password, email, created_at) values ('love', '1234', 'love@nate.com', now()); insert into board_tb(title, content, created_at, user_id) values ('제목1', '내용1', now(), 1); insert into board_tb(title, content, created_at, user_id) values ('제목2', '내용2', now(), 1); insert into board_tb(title, content, created_at, user_id) values ('제목3', '내용3', now(), 2); insert into board_tb(title, content, created_at, user_id) values ('제목4', '내용4', now(), 2); insert into board_tb(title, content, created_at, user_id)

5. 패키지 만들기

notion image

6. 클래스 만들기

notion image
전에 만든 것 들고 오기 컨트롤c 컨트롤 v
User import 한 것 지금 User파일로 import 바꿔주기
 
지금까지 확인 해야 할 것 콘솔에서 dev 프로퍼티로 실행하고 있는지
notion image

7. 보드, 유저 리퀘스트 만들기

내용 복붙

8. 코어 만들기

notion image
복붙하고 import 수정해주기!
 
ajax도 할 거라서 일주일 정도 배워야 할 것 같음

9. UserRepository 인터페이스로 만들기

<>의 처음은 엔티티(유저로 하고) 두번째는 프라이머리키 타입
notion image
인터페이스는 new로 메모리에 추가할 수 없다
JPA레파지토리에 추상적인 것들이 다 들어가 있다
타고 타고 들어가면
notion image
notion image
notion image
em.persist 를 여기서 다 해준다
notion image
Optional은 null을 들고 있는 선물박스다
게시글 10번 줄래하면 board클래스 줄건데 없으면 null을 주거나 noResultException터트림
 
하이버네이트 기술안에 자바에서 기본적으로 함수를 쓰라고 다 만들어뒀다(CRUD로) 이게 JPA다
 
10번 달랬는데 없으면 선물박스를 준다 그 안에 null이 있을 수 있다.
이러면 오류가 안 난다. 받기는 했으니까
조금 있다가 optional 배울거다 만약 안에 내용이 없으면 throw해주면 된다

궁금해야 할 것

인터페이슨데 new할 수 없잖아 @Repositroy못하잖아? 의미 없음

동작

실행 시 임의의 클래스를 만든다
여기에 UserRepositroy를 임플리먼트 하고 전부 오버라이딩한다(재정의) 오버라이딩 된게 엄청 많다!
 
ex) em.createQuery 이런 거를 알아서 해준다 IoC에 알아서 띄워줌
count하면 return을 알아서 구현해서 만들어준다 자동생성됨!!!
즉 기본 CRUD다 있다
전체조회, 프라이머리키로 조회, 삭제, 추가(insert)
업데이트는 안 해준다. 알아서 더티체킹해라고
 
유저 네임으로 체킹하는 이런 것은 안 해줘서 우리가 만들어야 한다!

9.1 내용 적기

notion image
@Query("select u from User u where u.username=:username" ??? 추가함) User findByUsername(@Param("username") String username);

9.2 네이티브 쿼리 할 거면(복잡한 쿼리들)

notion image
package shop.mtcoding.springv3.user; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @RequiredArgsConstructor @Repository public class UserQueryRepository { private final EntityManager em; //복잡한 쿼리 메서드 만드는 클래스다 }

읽기

중요한 것은 간단한 쿼리문은 UserRepository, 복잡한 쿼리는 UserQueryRepository

10. 유저 서비스 만들기

클래스 만들면 된다
 

11. 화면 가지고 오기

템플레이트 안에 있던 파일들 복붙하기
notion image

깃 협업 PR요청

조회된 것의 이름을 이름 + PS를 붙인다(영속적)
 
notion image
notion image
notion image
프로젝트 복사됨
 
이거 누르면 계속 동기화?
notion image
푸시하고 컨트리뷰트 하면
notion image
  1. 포크로 내려받는다
  1. 코드 푸시하고 컨트리뷰트 하면 넘어감?

optional

Optional<Board>를 추가하려면 이름을 이름 + OP를 넣는다
if(boardOP.isPresent()
 
Board boardPs = boardRepositroy.findById(boardId)
.orElseThrow(() → new Exception404(”게시글이 없습니다. “));
람다식으로 집어 넣는다.!
 
readOnly = true 란
openInView 연결객체 만들어지고 응답 직전까지 살아있다 반드시 Transactional붙어 있어야 한다
외부에서 요청되면 트랜잭션 실행되고 종료될 때 세션 종료
만약 안 걸려 있다? 세션 만들어 지고 DB연결하고 나오면 바로 끝난다.
 
c → s → r → db
기본은 db세션 만들어지고 c s r db 이렇게 한번 요청되면 끝난다. 날라감
 
Transactional
세션생기고 c s r db 가도 세션 종료 안됨
db와 R사이 여러번 할 수 있음 서비스 종료 시점에 openinview false면 서비스에서 끝나고 true면 계속 살아있다.
 
JPA 인터페이스를 사용하면 Openinview를 true를 하던 false하던 안 먹힌다. 그래서 transactional붙인다.
 
리드온리 적은 트랜잭션과 그냥 트랜잭션 차이
 
차이
  1. 클래스 위에 붙이면 다 먹는데 메서드 위에 붙이면 트랜잭션만 된다
 
사과 진열대에는 사과만 배 진열대에는 배만 있다
트랜잭션 걸면 사과 쪽으로 가면 수정 삭제 이런 것 안됨
같이 가게되면 리드온리 트루가 안돼 있으면 애는
 
 
Share article

code-sudal