diff --git a/build.gradle b/build.gradle index 8d52aebc6..69211f7fb 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'dev.akkinoc.spring.boot:logback-access-spring-boot-starter:4.0.0' @@ -27,6 +27,12 @@ dependencies { testImplementation 'io.rest-assured:rest-assured:5.3.1' runtimeOnly 'com.h2database:h2' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' } test { diff --git a/script/deploy.sh b/script/deploy.sh new file mode 100644 index 000000000..6b35c7f0d --- /dev/null +++ b/script/deploy.sh @@ -0,0 +1,14 @@ +git pull code JPA4 +./gradlew clean build +PID=$(cat application.pid 2>/dev/null) + +if [ -n "$PID" ]; then + kill -15 "$PID" + sleep 5 +fi + +JAR=$(find build/libs -name "*.jar" | head -n 1) + +nohup java -jar "$JAR" > application.log 2>&1 & + +echo $! > application.pid diff --git a/script/setup.sh b/script/setup.sh new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/README.md b/src/main/README.md index 086ab29ab..d1e3b18ad 100644 --- a/src/main/README.md +++ b/src/main/README.md @@ -3,27 +3,28 @@ 안녕하세요. 세종대학교 그리디 백엔드 4기 이채현입니다. ---- -## Spring MVC 미션 3단계 - 관리자 기능 - -어드민 페이지 진입은 admin 권한이 있는 사람만 할 수 있도록 제한한다. -만약 진입 권한이 없다면 401 코드를 응답하도록 한다. --- -### 고민한 내용 🤔 +## Spring JPA Spring Core 배포 -- HandlerInterceptor에서 기본적으로 preHandle/postHandle/afterCompletion으로 나뉘어져있던데, -이번의 경우에는 admin페이지 접속만을 확인하면 되는거라서 preHandle만을 사용했습니다. -이경우에는 postHandle과 afterCompletion을 어떻게 구성하면 좋을지..? 알고 싶네요. +### 🚀 7단계 - @Configuration +JWT 관련 로직을 roomescape와 같은 계층의 auth 패키지의 클래스로 분리하고, +불필요한 DB 접근을 최소화하기. -- WebConfig 같은 경우에는, admin 페이지를 접속할때의 role만을 확인해주면 되므로 /admin/***을 사용해주었습니다. +### 🚀 8단계 - Profile과 Resource -- token 만료시간도 있어야할 것 같아서 expire_time을 이용해서,만료시간을 구현해보았습니다. 만료시간을 구현할 더 좋은 -방법이 있을지?? 궁금합니다. +schema.sql 대신 데이터베이스를 초기화 해주기 위해 실행하는 클래스를 생성. +스프링이 실행될 때 동작해야 함. +token 생성에 필요한 비밀키값을 외부 파일로 분리하기. -- token을 accessToken과 refreshToken으로 나눠서 구현해주었는데, 구현하다보니 너무 어려워서 제대로 구현된건지 잘 -모르겠습니다. +### 🚀 9단계 - 배포 스크립트 +ec2나 서버에서 배포를 할 수 있게 배포 스크립트를 작성하기. + +--- +### 고민한 내용 🤔 +1. JwtProvider를 auth package를 생성해서,JwtConfig와 JwtUtils로 분리해줬는데, 이렇게 구성하면 장점이 궁금합니다. +배포스크립트와 초기 설정의 시나리오가 어떻게 사용되는지 잘 모르겠습니다... diff --git a/src/main/java/auth/JwtConfig.java b/src/main/java/auth/JwtConfig.java new file mode 100644 index 000000000..6e26dbd56 --- /dev/null +++ b/src/main/java/auth/JwtConfig.java @@ -0,0 +1,18 @@ +package auth; + +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.security.Key; + +@Configuration +public class JwtConfig { + @Bean + public JwtUtils jwtUtils(@Value("${roomescape.auth.jwt.secret}")String secret){ + Key key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)); + return new JwtUtils(key); + } +} diff --git a/src/main/java/auth/JwtUtils.java b/src/main/java/auth/JwtUtils.java new file mode 100644 index 000000000..5f926b3cd --- /dev/null +++ b/src/main/java/auth/JwtUtils.java @@ -0,0 +1,54 @@ +package auth; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import roomescape.member.Member; + +import java.security.Key; +import java.util.Date; + + +public class JwtUtils { + private final Key secretKey; + private final long expireAccessTime = 30L * 60 * 1000; + private final long expireRefreshTime = 14L * 24 * 60 * 60 * 1000; + + public JwtUtils(Key secretKey) { + this.secretKey = secretKey; + } + + public String createAccessToken(Member member) { + return createToken(member.getId(),expireAccessTime); + } + + public String createRefreshToken(Member member) { + return createToken(member.getId(),expireRefreshTime); + } + private String createToken(Long memberId, long expireTime){ + Date now= new Date(); + + return Jwts.builder() + .setSubject(memberId.toString()) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime()+expireTime)) + .signWith(secretKey) + .compact(); + } + + public Long getMemberId(String token) { + Claims claims = parseClaims(token); + return Long.parseLong(claims.getSubject()); + } + + private Claims parseClaims(String token) { + try { + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + throw new IllegalArgumentException("유효하지 않거나 만료된 토큰입니다.", e); + } + } +} diff --git a/src/main/java/roomescape/CookieManager.java b/src/main/java/roomescape/CookieManager.java index 22b74fea8..37966006a 100644 --- a/src/main/java/roomescape/CookieManager.java +++ b/src/main/java/roomescape/CookieManager.java @@ -1,13 +1,13 @@ package roomescape; import jakarta.servlet.http.Cookie; +import org.springframework.stereotype.Component; import roomescape.exception.TokenNotFoundException; import java.util.Arrays; +@Component public class CookieManager { - - public String extractToken(Cookie[] cookies, String cookieName) { return Arrays.stream(cookies) .filter(cookie -> cookieName.equals(cookie.getName())) diff --git a/src/main/java/roomescape/JwtProvider.java b/src/main/java/roomescape/JwtProvider.java deleted file mode 100644 index d91bce7af..000000000 --- a/src/main/java/roomescape/JwtProvider.java +++ /dev/null @@ -1,60 +0,0 @@ -package roomescape; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.security.Keys; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import roomescape.member.Member; - -import java.nio.charset.StandardCharsets; -import java.security.Key; -import java.util.Date; - -@Component -public class JwtProvider { - - private final Key secretKey; - private final int expireAccessTime=30*60*1000; - private final long expireRefreshTime=14L*24*60*60*1000; - - public JwtProvider(@Value("${roomescape.auth.jwt.secret}") String secretKeyString) { - this.secretKey = Keys.hmacShaKeyFor(secretKeyString.getBytes(StandardCharsets.UTF_8)); - } - - public String createAccessToken(Member member) { - return Jwts.builder() - .setSubject(member.getId().toString()) - .claim("name", member.getName()) - .claim("role", member.getRole()) - .setExpiration(new Date(System.currentTimeMillis()+expireAccessTime)) - .signWith(secretKey) - .compact(); - } - - public String createRefreshToken(Member member){ - return Jwts.builder() - .setSubject(member.getId().toString()) - .setIssuedAt(new Date()) - .setExpiration(new Date(System.currentTimeMillis()+expireRefreshTime)) - .signWith(secretKey) - .compact(); - } - - public Long getMemberId(String token) { - Claims claims = parseClaims(token); - return Long.parseLong(claims.getSubject()); - } - - private Claims parseClaims(String token) { - try { - return Jwts.parserBuilder() - .setSigningKey(secretKey) - .build() - .parseClaimsJws(token) - .getBody(); - } catch (Exception e) { - throw new IllegalArgumentException("유효하지 않거나 만료된 토큰입니다.", e); - } - } -} diff --git a/src/main/java/roomescape/RoomescapeApplication.java b/src/main/java/roomescape/RoomescapeApplication.java index 2ca0f743f..17b054847 100644 --- a/src/main/java/roomescape/RoomescapeApplication.java +++ b/src/main/java/roomescape/RoomescapeApplication.java @@ -3,7 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@SpringBootApplication +@SpringBootApplication(scanBasePackages={"roomescape","auth"}) public class RoomescapeApplication { public static void main(String[] args) { SpringApplication.run(RoomescapeApplication.class, args); diff --git a/src/main/java/roomescape/dataLoader/DataLoader.java b/src/main/java/roomescape/dataLoader/DataLoader.java new file mode 100644 index 000000000..e312a19e4 --- /dev/null +++ b/src/main/java/roomescape/dataLoader/DataLoader.java @@ -0,0 +1,41 @@ +package roomescape.dataLoader; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import roomescape.member.Member; +import roomescape.member.MemberRepository; + + +@Component +public class DataLoader implements CommandLineRunner { + + @Autowired + private MemberRepository memberRepository; + + public DataLoader(MemberRepository memberRepository) { + this.memberRepository = memberRepository; + } + + @Override + public void run(String ...args){ + if(memberRepository.count()>0){ + return; + } + + Member admin= Member.builder() + .name("어드민") + .email("admin@email.com") + .password("password") + .role("ADMIN").build(); + + Member brown= Member.builder() + .name("브라운") + .email("brown@email.com") + .password("password") + .role("USER").build(); + + memberRepository.save(admin); + memberRepository.save(brown); + } +} diff --git a/src/main/java/roomescape/dataLoader/TestDataLoader.java b/src/main/java/roomescape/dataLoader/TestDataLoader.java new file mode 100644 index 000000000..8aef2d66f --- /dev/null +++ b/src/main/java/roomescape/dataLoader/TestDataLoader.java @@ -0,0 +1,109 @@ +package roomescape.dataLoader; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import roomescape.member.Member; +import roomescape.member.MemberRepository; +import roomescape.reservation.Reservation; +import roomescape.reservation.ReservationRepository; +import roomescape.theme.Theme; +import roomescape.theme.ThemeRepository; +import roomescape.time.Time; +import roomescape.time.TimeRepository; + +@Component +public class TestDataLoader implements CommandLineRunner { + + @Autowired + private final ThemeRepository themeRepository; + private final TimeRepository timeRepository; + private final ReservationRepository reservationRepository; + private final MemberRepository memberRepository; + + public TestDataLoader(ThemeRepository themeRepository, TimeRepository timeRepository, + ReservationRepository reservationRepository, MemberRepository memberRepository) { + this.themeRepository = themeRepository; + this.timeRepository = timeRepository; + this.reservationRepository = reservationRepository; + this.memberRepository = memberRepository; + } + + @Override + public void run(String... args) { + Member admin = memberRepository.findByName("ADMIN") + .orElseThrow(); + Member brown = memberRepository.findByName("브라운") + .orElseThrow(); + if (themeRepository.count() > 0) { + return; + } + Theme theme1 = Theme.builder() + .name("테마1") + .description("테마1입니다.") + .build(); + Theme theme2 = Theme.builder() + .name("테마2") + .description("테마2입니다.") + .build(); + Theme theme3 = Theme.builder() + .name("테마3") + .description("테마3입니다.") + .build(); + + themeRepository.save(theme1); + themeRepository.save(theme2); + themeRepository.save(theme3); + + if (timeRepository.count() > 0) { + return; + } + Time time1 = Time.builder() + .value("10:00") + .build(); + Time time2 = Time.builder() + .value("12:00") + .build(); + Time time3 = Time.builder() + .value("14:00") + .build(); + Time time4 = Time.builder() + .value("16:00") + .build(); + Time time5 = Time.builder() + .value("18:00") + .build(); + Time time6 = Time.builder() + .value("20:00") + .build(); + timeRepository.save(time1); + timeRepository.save(time2); + timeRepository.save(time3); + timeRepository.save(time4); + timeRepository.save(time5); + timeRepository.save(time6); + + reservationRepository.save( + Reservation.builder() + .member(admin) + .date("2024-03-01") + .time(time1) + .theme(theme1) + .build()); + reservationRepository.save( + Reservation.builder() + .member(admin) + .date("2024-03-01") + .time(time2) + .theme(theme2) + .build()); + reservationRepository.save( + Reservation.builder() + .member(brown) + .date("2024-03-01") + .time(time3) + .theme(theme3) + .build()); + } +} diff --git a/src/main/java/roomescape/login/LoginController.java b/src/main/java/roomescape/login/LoginController.java index f3e46d0e7..a74be64a5 100644 --- a/src/main/java/roomescape/login/LoginController.java +++ b/src/main/java/roomescape/login/LoginController.java @@ -1,5 +1,6 @@ package roomescape.login; +import auth.JwtUtils; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -10,18 +11,17 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import roomescape.CookieManager; -import roomescape.JwtProvider; import roomescape.member.Member; import roomescape.member.MemberResponse; @RestController public class LoginController { private final LoginService loginService; - private final JwtProvider jwtProvider; + private final JwtUtils jwtUtils; private final CookieManager cookieManager; - public LoginController(LoginService loginService, JwtProvider jwtProvider, CookieManager cookieManager) { - this.jwtProvider = jwtProvider; + public LoginController(LoginService loginService, JwtUtils jwtUtils, CookieManager cookieManager) { + this.jwtUtils = jwtUtils; this.loginService = loginService; this.cookieManager = cookieManager; } @@ -30,8 +30,8 @@ public LoginController(LoginService loginService, JwtProvider jwtProvider, Cooki public ResponseEntity login(@RequestBody LoginRequest loginRequest, HttpServletResponse httpresponse) { Member member = loginService.login(loginRequest.email(), loginRequest.password()); - String accessToken = jwtProvider.createAccessToken(member); - String refreshToken = jwtProvider.createRefreshToken(member); + String accessToken = jwtUtils.createAccessToken(member); + String refreshToken = jwtUtils.createRefreshToken(member); Cookie accessCookie = new Cookie("accessToken", accessToken); Cookie refreshCookie = new Cookie("refreshToken", refreshToken); @@ -55,11 +55,11 @@ public ResponseEntity refresh(HttpServletRequest request, HttpServletRespo } String refreshToken = cookieManager.extractToken(cookies, "refreshToken"); - Long memberId = jwtProvider.getMemberId(refreshToken); + Long memberId = jwtUtils.getMemberId(refreshToken); Member member = loginService.findById(memberId); - String accessToken = jwtProvider.createAccessToken(member); + String accessToken = jwtUtils.createAccessToken(member); Cookie cookie = new Cookie("accessToken", accessToken); cookie.setHttpOnly(true); @@ -71,7 +71,7 @@ public ResponseEntity refresh(HttpServletRequest request, HttpServletRespo @GetMapping("/login/check") public ResponseEntity checkLogin(LoginMember loginMember) { - Long memberId = loginMember.id(); + Long memberId = loginMember.getId(); MemberResponse memberResponse = loginService.checkLogin(memberId); return ResponseEntity.ok(memberResponse); } diff --git a/src/main/java/roomescape/login/LoginInterceptor.java b/src/main/java/roomescape/login/LoginInterceptor.java index 0c431b54c..5107a401d 100644 --- a/src/main/java/roomescape/login/LoginInterceptor.java +++ b/src/main/java/roomescape/login/LoginInterceptor.java @@ -1,39 +1,48 @@ package roomescape.login; +import auth.JwtUtils; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import roomescape.CookieManager; -import roomescape.JwtProvider; import roomescape.member.Member; -import roomescape.member.MemberDao; +import roomescape.member.MemberRepository; @Component public class LoginInterceptor implements HandlerInterceptor { - private final JwtProvider jwtProvider; - private final MemberDao memberDao; + private final JwtUtils jwtUtils; + private final MemberRepository memberRepository; private final CookieManager cookieManager; - public LoginInterceptor(JwtProvider jwtProvider, MemberDao memberDao, CookieManager cookieManager) { - this.jwtProvider = jwtProvider; - this.memberDao = memberDao; + public LoginInterceptor(JwtUtils jwtUtils, MemberRepository memberRepository, CookieManager cookieManager) { + this.jwtUtils = jwtUtils; + this.memberRepository = memberRepository; this.cookieManager = cookieManager; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - Cookie[] cookies = request.getCookies(); + Cookie[] cookies = getCookies(request); - String token = cookieManager.extractToken(cookies, "accessToken"); - Long memberId = jwtProvider.getMemberId(token); - Member member = memberDao.findById(memberId); - if (member == null || !member.getRole().equals("ADMIN")) { + String token = cookieManager.extractToken(cookies,"accessToken"); + Long memberId = jwtUtils.getMemberId(token); + Member member = memberRepository.findById(memberId) + .orElseThrow(); + if (!member.getRole().equals("ADMIN")) { response.setStatus(401); return false; } return true; } + + private Cookie[] getCookies(HttpServletRequest httpServletRequest) { + Cookie[] cookies = httpServletRequest.getCookies(); + if (cookies == null) { + throw new IllegalStateException("cookie is not exist"); + } + return cookies; + } } diff --git a/src/main/java/roomescape/login/LoginMember.java b/src/main/java/roomescape/login/LoginMember.java index 63b947ac9..58c102752 100644 --- a/src/main/java/roomescape/login/LoginMember.java +++ b/src/main/java/roomescape/login/LoginMember.java @@ -1,9 +1,22 @@ package roomescape.login; -public record LoginMember( - Long id, - String name, - String email, - String role -) { +import lombok.Getter; + + +@Getter +public class LoginMember { + private final Long id; + private final String name; + private final String email; + private final String password; + private final String role; + + public LoginMember(Long id, String name, String email, String password, String role) { + this.id = id; + this.name = name; + this.email = email; + this.password = password; + this.role = role; + } + } diff --git a/src/main/java/roomescape/login/LoginMemberArgumentResolver.java b/src/main/java/roomescape/login/LoginMemberArgumentResolver.java index 5d4909850..f9014344a 100644 --- a/src/main/java/roomescape/login/LoginMemberArgumentResolver.java +++ b/src/main/java/roomescape/login/LoginMemberArgumentResolver.java @@ -1,5 +1,6 @@ package roomescape.login; +import auth.JwtUtils; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; @@ -9,18 +10,17 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import roomescape.CookieManager; -import roomescape.JwtProvider; import roomescape.member.Member; -import roomescape.member.MemberDao; +import roomescape.member.MemberRepository; @Component public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver { - private final MemberDao memberDao; - private final JwtProvider jwtProvider; + private final MemberRepository memberRepository; + private final JwtUtils jwtUtils; private final CookieManager cookieManager; - public LoginMemberArgumentResolver(JwtProvider jwtProvider, MemberDao memberDao,CookieManager cookieManager) { - this.memberDao = memberDao; - this.jwtProvider = jwtProvider; + public LoginMemberArgumentResolver(JwtUtils jwtUtils, MemberRepository memberRepository, CookieManager cookieManager) { + this.memberRepository = memberRepository; + this.jwtUtils = jwtUtils; this.cookieManager=cookieManager; } @@ -36,11 +36,12 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m String token = cookieManager.extractToken(cookies,"accessToken"); - Long memberId = jwtProvider.getMemberId(token); + Long memberId = jwtUtils.getMemberId(token); - Member member = memberDao.findById(memberId); + Member member = memberRepository.findById(memberId) + .orElseThrow(); - return new LoginMember(member.getId(), member.getName(), member.getEmail(), member.getRole()); + return new LoginMember(memberId, member.getName(), member.getEmail(), member.getPassword(),member.getRole()); } private HttpServletRequest getRequest(NativeWebRequest nativeWebRequest) { @@ -58,5 +59,4 @@ private Cookie[] getCookies(HttpServletRequest httpServletRequest) { } return cookies; } - } diff --git a/src/main/java/roomescape/login/LoginService.java b/src/main/java/roomescape/login/LoginService.java index 6085212f4..90343fa09 100644 --- a/src/main/java/roomescape/login/LoginService.java +++ b/src/main/java/roomescape/login/LoginService.java @@ -2,36 +2,34 @@ import org.springframework.stereotype.Service; import roomescape.member.Member; -import roomescape.member.MemberDao; +import roomescape.member.MemberRepository; import roomescape.member.MemberResponse; @Service public class LoginService { - private final MemberDao memberDao; + private final MemberRepository memberRepository; - public LoginService(MemberDao memberDao) { - this.memberDao = memberDao; + public LoginService(MemberRepository memberRepository) { + this.memberRepository = memberRepository; } public Member login(String email, String password) { - Member member = memberDao.findByEmailAndPassword(email, password); - if (member == null) { - throw new RuntimeException("Invalid email or password"); - } + Member member = memberRepository.findByEmailAndPassword(email, password) + .orElseThrow(); + return member; } public MemberResponse checkLogin(Long memberId) { - Member member = memberDao.findById(memberId); - if (member == null) { - throw new RuntimeException("Invalid email or password"); - } + Member member = memberRepository.findById(memberId) + .orElseThrow(); return new MemberResponse(member.getId(), member.getName(), member.getEmail()); } public Member findById(Long id) { - Member member = memberDao.findById(id); + Member member = memberRepository.findById(id) + .orElseThrow(); return member; } diff --git a/src/main/java/roomescape/member/Member.java b/src/main/java/roomescape/member/Member.java index 903aaa9b0..44387d634 100644 --- a/src/main/java/roomescape/member/Member.java +++ b/src/main/java/roomescape/member/Member.java @@ -1,43 +1,36 @@ package roomescape.member; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +@Getter public class Member { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + private String name; + + @Column(unique = true) private String email; + private String password; private String role; - public Member(Long id, String name, String email, String role) { - this.id = id; - this.name = name; - this.email = email; - this.role = role; - } - + @Builder public Member(String name, String email, String password, String role) { this.name = name; this.email = email; this.password = password; this.role = role; } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getEmail() { - return email; - } - - public String getPassword() { - return password; - } - - public String getRole() { - return role; - } } diff --git a/src/main/java/roomescape/member/MemberController.java b/src/main/java/roomescape/member/MemberController.java index fe009d062..513923746 100644 --- a/src/main/java/roomescape/member/MemberController.java +++ b/src/main/java/roomescape/member/MemberController.java @@ -11,7 +11,7 @@ @RestController public class MemberController { - private MemberService memberService; + private final MemberService memberService; public MemberController(MemberService memberService) { this.memberService = memberService; @@ -20,7 +20,7 @@ public MemberController(MemberService memberService) { @PostMapping("/members") public ResponseEntity createMember(@RequestBody MemberRequest memberRequest) { MemberResponse member = memberService.createMember(memberRequest); - return ResponseEntity.created(URI.create("/members/" + member.getId())).body(member); + return ResponseEntity.created(URI.create("/members/" + member.id())).body(member); } @PostMapping("/logout") diff --git a/src/main/java/roomescape/member/MemberDao.java b/src/main/java/roomescape/member/MemberDao.java deleted file mode 100644 index db0b9c68c..000000000 --- a/src/main/java/roomescape/member/MemberDao.java +++ /dev/null @@ -1,68 +0,0 @@ -package roomescape.member; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; - -@Repository -public class MemberDao { - private JdbcTemplate jdbcTemplate; - - public MemberDao(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - public Member save(Member member) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(connection -> { - var ps = connection.prepareStatement("INSERT INTO member(name, email, password, role) VALUES (?, ?, ?, ?)", new String[]{"id"}); - ps.setString(1, member.getName()); - ps.setString(2, member.getEmail()); - ps.setString(3, member.getPassword()); - ps.setString(4, member.getRole()); - return ps; - }, keyHolder); - - return new Member(keyHolder.getKey().longValue(), member.getName(), member.getEmail(), "USER"); - } - - public Member findByEmailAndPassword(String email, String password) { - return jdbcTemplate.queryForObject( - "SELECT id, name, email, role FROM member WHERE email = ? AND password = ?", - (rs, rowNum) -> new Member( - rs.getLong("id"), - rs.getString("name"), - rs.getString("email"), - rs.getString("role") - ), - email, password - ); - } - - public Member findByName(String name) { - return jdbcTemplate.queryForObject( - "SELECT id, name, email, role FROM member WHERE name = ?", - (rs, rowNum) -> new Member( - rs.getLong("id"), - rs.getString("name"), - rs.getString("email"), - rs.getString("role") - ), - name - ); - } - - public Member findById(Long id) { - return jdbcTemplate.queryForObject( - "SELECT id, name, email, role From member WHERE id = ?", - (rs, rowNum) -> new Member( - rs.getLong("id"), - rs.getString("name"), - rs.getString("email"), - rs.getString("role") - ), - id - ); - } -} diff --git a/src/main/java/roomescape/member/MemberRepository.java b/src/main/java/roomescape/member/MemberRepository.java new file mode 100644 index 000000000..01322100c --- /dev/null +++ b/src/main/java/roomescape/member/MemberRepository.java @@ -0,0 +1,14 @@ +package roomescape.member; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface MemberRepository extends JpaRepository { + + Optional findByEmailAndPassword(String email, String password); + + Optional findByName(String name); +} diff --git a/src/main/java/roomescape/member/MemberRequest.java b/src/main/java/roomescape/member/MemberRequest.java index cafb79f14..d32583825 100644 --- a/src/main/java/roomescape/member/MemberRequest.java +++ b/src/main/java/roomescape/member/MemberRequest.java @@ -1,19 +1,8 @@ package roomescape.member; -public class MemberRequest { - private String name; - private String email; - private String password; - - public String getName() { - return name; - } - - public String getEmail() { - return email; - } - - public String getPassword() { - return password; - } +public record MemberRequest( + String name, + String email, + String password +) { } diff --git a/src/main/java/roomescape/member/MemberResponse.java b/src/main/java/roomescape/member/MemberResponse.java index b9fa3b97a..f2408ba3e 100644 --- a/src/main/java/roomescape/member/MemberResponse.java +++ b/src/main/java/roomescape/member/MemberResponse.java @@ -1,25 +1,8 @@ package roomescape.member; -public class MemberResponse { - private Long id; - private String name; - private String email; - - public MemberResponse(Long id, String name, String email) { - this.id = id; - this.name = name; - this.email = email; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getEmail() { - return email; - } +public record MemberResponse( + Long id, + String name, + String email +) { } diff --git a/src/main/java/roomescape/member/MemberService.java b/src/main/java/roomescape/member/MemberService.java index ccaa8cba5..6109bfce7 100644 --- a/src/main/java/roomescape/member/MemberService.java +++ b/src/main/java/roomescape/member/MemberService.java @@ -4,14 +4,20 @@ @Service public class MemberService { - private MemberDao memberDao; + private final MemberRepository memberRepository; - public MemberService(MemberDao memberDao) { - this.memberDao = memberDao; + public MemberService(MemberRepository memberRepository) { + this.memberRepository = memberRepository; } public MemberResponse createMember(MemberRequest memberRequest) { - Member member = memberDao.save(new Member(memberRequest.getName(), memberRequest.getEmail(), memberRequest.getPassword(), "USER")); + Member member = Member.builder() + .name(memberRequest.name()) + .email(memberRequest.email()) + .password(memberRequest.password()) + .role("USER") + .build(); + memberRepository.save(member); return new MemberResponse(member.getId(), member.getName(), member.getEmail()); } } diff --git a/src/main/java/roomescape/reservation/Reservation.java b/src/main/java/roomescape/reservation/Reservation.java index 83a7edf1b..7b61680af 100644 --- a/src/main/java/roomescape/reservation/Reservation.java +++ b/src/main/java/roomescape/reservation/Reservation.java @@ -1,51 +1,45 @@ package roomescape.reservation; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import roomescape.member.Member; import roomescape.theme.Theme; import roomescape.time.Time; +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +@Getter public class Reservation { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String date; + + @ManyToOne + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne + @JoinColumn(name = "time_id") private Time time; + @ManyToOne + @JoinColumn(name = "theme_id") private Theme theme; - public Reservation(Long id, String name, String date, Time time, Theme theme) { - this.id = id; - this.name = name; - this.date = date; - this.time = time; - this.theme = theme; - } - - public Reservation(String name, String date, Time time, Theme theme) { - this.name = name; + @Builder + public Reservation(Member member, String date, Time time, Theme theme) { + this.member = member; this.date = date; this.time = time; this.theme = theme; } - - public Reservation() { - - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getDate() { - return date; - } - - public Time getTime() { - return time; - } - - public Theme getTheme() { - return theme; - } } diff --git a/src/main/java/roomescape/reservation/ReservationController.java b/src/main/java/roomescape/reservation/ReservationController.java index 95de7ccb5..b8942072f 100644 --- a/src/main/java/roomescape/reservation/ReservationController.java +++ b/src/main/java/roomescape/reservation/ReservationController.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import roomescape.login.LoginMember; +import roomescape.reservation.dto.MyReservationResponse; import java.net.URI; import java.util.List; @@ -29,14 +30,14 @@ public List list() { @PostMapping("/reservations") public ResponseEntity create(@RequestBody ReservationRequest reservationRequest, LoginMember loginMember) { if ( - reservationRequest.getDate() == null - || reservationRequest.getTheme() == null - || reservationRequest.getTime() == null) { + reservationRequest.date() == null + || reservationRequest.theme() == null + || reservationRequest.time() == null) { return ResponseEntity.badRequest().build(); } ReservationResponse reservation = reservationService.save(reservationRequest, loginMember); - return ResponseEntity.created(URI.create("/reservations/" + reservation.getId())).body(reservation); + return ResponseEntity.created(URI.create("/reservations/" + reservation.id())).body(reservation); } @DeleteMapping("/reservations/{id}") @@ -44,4 +45,9 @@ public ResponseEntity delete(@PathVariable Long id) { reservationService.deleteById(id); return ResponseEntity.noContent().build(); } + + @GetMapping("/reservations-mine") + public List reservationMine(LoginMember member) { + return reservationService.findMyReservations(member); + } } diff --git a/src/main/java/roomescape/reservation/ReservationDao.java b/src/main/java/roomescape/reservation/ReservationDao.java deleted file mode 100644 index b029b348c..000000000 --- a/src/main/java/roomescape/reservation/ReservationDao.java +++ /dev/null @@ -1,127 +0,0 @@ -package roomescape.reservation; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; -import roomescape.theme.Theme; -import roomescape.time.Time; - -import java.sql.PreparedStatement; -import java.util.List; - -@Repository -public class ReservationDao { - - private final JdbcTemplate jdbcTemplate; - - public ReservationDao(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - public List findAll() { - return jdbcTemplate.query( - "SELECT r.id AS reservation_id, r.name as reservation_name, r.date as reservation_date, " + - "t.id AS theme_id, t.name AS theme_name, t.description AS theme_description, " + - "ti.id AS time_id, ti.time_value AS time_value " + - "FROM reservation r " + - "JOIN theme t ON r.theme_id = t.id " + - "JOIN time ti ON r.time_id = ti.id", - - (rs, rowNum) -> new Reservation( - rs.getLong("reservation_id"), - rs.getString("reservation_name"), - rs.getString("reservation_date"), - new Time( - rs.getLong("time_id"), - rs.getString("time_value") - ), - new Theme( - rs.getLong("theme_id"), - rs.getString("theme_name"), - rs.getString("theme_description") - ))); - } - - public Reservation save(ReservationRequest reservationRequest, String name) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(connection -> { - PreparedStatement ps = connection.prepareStatement("INSERT INTO reservation(date, name, theme_id, time_id) VALUES (?, ?, ?, ?)", new String[]{"id"}); - ps.setString(1, reservationRequest.getDate()); - ps.setString(2, name); - ps.setLong(3, reservationRequest.getTheme()); - ps.setLong(4, reservationRequest.getTime()); - return ps; - }, keyHolder); - - Time time = jdbcTemplate.queryForObject("SELECT * FROM time WHERE id = ?", - (rs, rowNum) -> new Time(rs.getLong("id"), rs.getString("time_value")), - reservationRequest.getTime()); - - Theme theme = jdbcTemplate.queryForObject("SELECT * FROM theme WHERE id = ?", - (rs, rowNum) -> new Theme(rs.getLong("id"), rs.getString("name"), rs.getString("description")), - reservationRequest.getTheme()); - - return new Reservation( - keyHolder.getKey().longValue(), - name, - reservationRequest.getDate(), - time, - theme - ); - } - - public void deleteById(Long id) { - jdbcTemplate.update("DELETE FROM reservation WHERE id = ?", id); - } - - public List findReservationsByDateAndTheme(String date, Long themeId) { - return jdbcTemplate.query( - "SELECT r.id AS reservation_id, r.name as reservation_name, r.date as reservation_date, " + - "t.id AS theme_id, t.name AS theme_name, t.description AS theme_description, " + - "ti.id AS time_id, ti.time_value AS time_value " + - "FROM reservation r " + - "JOIN theme t ON r.theme_id = t.id " + - "JOIN time ti ON r.time_id = ti.id" + - "WHERE r.date = ? AND r.theme_id = ?", - new Object[]{date, themeId}, - (rs, rowNum) -> new Reservation( - rs.getLong("reservation_id"), - rs.getString("reservation_name"), - rs.getString("reservation_date"), - new Time( - rs.getLong("time_id"), - rs.getString("time_value") - ), - new Theme( - rs.getLong("theme_id"), - rs.getString("theme_name"), - rs.getString("theme_description") - ))); - } - - public List findByDateAndThemeId(String date, Long themeId) { - return jdbcTemplate.query( - "SELECT r.id AS reservation_id, r.name as reservation_name, r.date as reservation_date, " + - "t.id AS theme_id, t.name AS theme_name, t.description AS theme_description, " + - "ti.id AS time_id, ti.time_value AS time_value " + - "FROM reservation r " + - "JOIN theme t ON r.theme_id = t.id " + - "JOIN time ti ON r.time_id = ti.id " + - "WHERE r.date = ? AND r.theme_id = ?", - new Object[]{date, themeId}, - (rs, rowNum) -> new Reservation( - rs.getLong("reservation_id"), - rs.getString("reservation_name"), - rs.getString("reservation_date"), - new Time( - rs.getLong("time_id"), - rs.getString("time_value") - ), - new Theme( - rs.getLong("theme_id"), - rs.getString("theme_name"), - rs.getString("theme_description") - ))); - } -} diff --git a/src/main/java/roomescape/reservation/ReservationRepository.java b/src/main/java/roomescape/reservation/ReservationRepository.java new file mode 100644 index 000000000..d8383df50 --- /dev/null +++ b/src/main/java/roomescape/reservation/ReservationRepository.java @@ -0,0 +1,13 @@ +package roomescape.reservation; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ReservationRepository extends JpaRepository { + List findByDateAndThemeId(String date, Long themeId); + List findByMemberId(Long memberId); +} + diff --git a/src/main/java/roomescape/reservation/ReservationRequest.java b/src/main/java/roomescape/reservation/ReservationRequest.java index 19f441246..a377da524 100644 --- a/src/main/java/roomescape/reservation/ReservationRequest.java +++ b/src/main/java/roomescape/reservation/ReservationRequest.java @@ -1,24 +1,9 @@ package roomescape.reservation; -public class ReservationRequest { - private String name; - private String date; - private Long theme; - private Long time; - - public String getName() { - return name; - } - - public String getDate() { - return date; - } - - public Long getTheme() { - return theme; - } - - public Long getTime() { - return time; - } +public record ReservationRequest( + String name, + String date, + Long theme, + Long time +){ } diff --git a/src/main/java/roomescape/reservation/ReservationResponse.java b/src/main/java/roomescape/reservation/ReservationResponse.java index 41360a363..cdfc7c541 100644 --- a/src/main/java/roomescape/reservation/ReservationResponse.java +++ b/src/main/java/roomescape/reservation/ReservationResponse.java @@ -1,37 +1,9 @@ package roomescape.reservation; -public class ReservationResponse { - private Long id; - private String name; - private String theme; - private String date; - private String time; - - public ReservationResponse(Long id, String name, String theme, String date, String time) { - this.id = id; - this.name = name; - this.theme = theme; - this.date = date; - this.time = time; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getTheme() { - return theme; - } - - public String getDate() { - return date; - } - - public String getTime() { - return time; - } +public record ReservationResponse( + String name, + Long id, + String theme, + String date, + String time) { } diff --git a/src/main/java/roomescape/reservation/ReservationService.java b/src/main/java/roomescape/reservation/ReservationService.java index c392496dc..1ae612bf2 100644 --- a/src/main/java/roomescape/reservation/ReservationService.java +++ b/src/main/java/roomescape/reservation/ReservationService.java @@ -2,33 +2,96 @@ import org.springframework.stereotype.Service; import roomescape.login.LoginMember; +import roomescape.member.Member; +import roomescape.member.MemberRepository; +import roomescape.reservation.dto.MyReservationResponse; +import roomescape.theme.Theme; +import roomescape.theme.ThemeRepository; +import roomescape.time.Time; +import roomescape.time.TimeRepository; +import roomescape.waiting.Waiting; +import roomescape.waiting.WaitingRepository; +import java.util.ArrayList; import java.util.List; @Service public class ReservationService { - private ReservationDao reservationDao; + private final ReservationRepository reservationRepository; + private final ThemeRepository themeRepository; + private final TimeRepository timeRepository; + private final MemberRepository memberRepository; + private final WaitingRepository waitingRepository; - public ReservationService(ReservationDao reservationDao) { - this.reservationDao = reservationDao; + public ReservationService(ReservationRepository reservationRepository, ThemeRepository themeRepository, TimeRepository timeRepository, MemberRepository memberRepository, WaitingRepository waitingRepository) { + this.reservationRepository = reservationRepository; + this.themeRepository = themeRepository; + this.timeRepository = timeRepository; + this.memberRepository = memberRepository; + this.waitingRepository = waitingRepository; } public ReservationResponse save(ReservationRequest reservationRequest, LoginMember loginMember) { - String name = reservationRequest.getName(); + String name = reservationRequest.name(); if (name == null) { - name = loginMember.name(); + name = loginMember.getName(); } - Reservation reservation = reservationDao.save(reservationRequest, name); - return new ReservationResponse(reservation.getId(), reservation.getName(), reservation.getTheme().getName(), reservation.getDate(), reservation.getTime().getValue()); + Theme theme = themeRepository.findById(reservationRequest.theme()) + .orElseThrow(); + Time time = timeRepository.findById(reservationRequest.time()) + .orElseThrow(); + Member member = memberRepository.findByName(name) + .orElseThrow(); + Reservation reservation = Reservation.builder(). + member(member) + .date(reservationRequest.date()) + .time(time) + .theme(theme) + .build(); + reservationRepository.save(reservation); + return new ReservationResponse( + reservation.getMember().getName(), + reservation.getId(), + reservation.getTheme().getName(), + reservation.getDate(), + reservation.getTime().getTimeValue()); } public void deleteById(Long id) { - reservationDao.deleteById(id); + reservationRepository.deleteById(id); } public List findAll() { - return reservationDao.findAll().stream() - .map(it -> new ReservationResponse(it.getId(), it.getName(), it.getTheme().getName(), it.getDate(), it.getTime().getValue())) + return reservationRepository.findAll().stream() + .map(it -> new ReservationResponse(it.getMember().getName(), it.getId(), it.getTheme().getName(), it.getDate(), it.getTime().getTimeValue())) .toList(); } + + public List findMyReservations(LoginMember member) { + List result = new ArrayList<>(); + reservationRepository.findByMemberId(member.getId()) + .forEach(reservation -> + result.add(new MyReservationResponse( + reservation.getId(), + reservation.getTheme().getName(), + reservation.getDate(), + reservation.getTime().getTimeValue(), + "예약" + )) + ); + + waitingRepository.findWaitingsWithRankByMemberId(member.getId()) + .forEach(waitingWithRank ->{ + Waiting waiting = waitingWithRank.waiting(); + + result.add(new MyReservationResponse( + waiting.getId(), + waiting.getTheme().getName(), + waiting.getDate(), + waiting.getTime().getTimeValue(), + (waitingWithRank.rank()+1+"번째 예약대기") + )); + }); + return result; + } } diff --git a/src/main/java/roomescape/reservation/dto/MyReservationResponse.java b/src/main/java/roomescape/reservation/dto/MyReservationResponse.java new file mode 100644 index 000000000..35136057c --- /dev/null +++ b/src/main/java/roomescape/reservation/dto/MyReservationResponse.java @@ -0,0 +1,5 @@ +package roomescape.reservation.dto; + +public record MyReservationResponse(Long id, String theme, String date, String time, String status) { +} + diff --git a/src/main/java/roomescape/theme/Theme.java b/src/main/java/roomescape/theme/Theme.java index 430a6239c..33930f897 100644 --- a/src/main/java/roomescape/theme/Theme.java +++ b/src/main/java/roomescape/theme/Theme.java @@ -1,13 +1,26 @@ package roomescape.theme; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; + +@Entity +@Getter public class Theme { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; + public Theme() { } + @Builder public Theme(Long id, String name, String description) { this.id = id; this.name = name; @@ -19,15 +32,4 @@ public Theme(String name, String description) { this.description = description; } - public Long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } } diff --git a/src/main/java/roomescape/theme/ThemeController.java b/src/main/java/roomescape/theme/ThemeController.java index 03bca41a6..4286a0f69 100644 --- a/src/main/java/roomescape/theme/ThemeController.java +++ b/src/main/java/roomescape/theme/ThemeController.java @@ -13,26 +13,27 @@ @RestController public class ThemeController { - private ThemeDao themeDao; + private final ThemeService themeService; - public ThemeController(ThemeDao themeDao) { - this.themeDao = themeDao; + public ThemeController(ThemeService themeService) { + this.themeService = themeService; } @PostMapping("/themes") public ResponseEntity createTheme(@RequestBody Theme theme) { - Theme newTheme = themeDao.save(theme); + Theme newTheme = themeService.create(theme); return ResponseEntity.created(URI.create("/themes/" + newTheme.getId())).body(newTheme); } @GetMapping("/themes") public ResponseEntity> list() { - return ResponseEntity.ok(themeDao.findAll()); + + return ResponseEntity.ok(themeService.findAll()); } @DeleteMapping("/themes/{id}") public ResponseEntity deleteTheme(@PathVariable Long id) { - themeDao.deleteById(id); + themeService.delete(id); return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/roomescape/theme/ThemeDao.java b/src/main/java/roomescape/theme/ThemeDao.java deleted file mode 100644 index 945341d8d..000000000 --- a/src/main/java/roomescape/theme/ThemeDao.java +++ /dev/null @@ -1,41 +0,0 @@ -package roomescape.theme; - -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public class ThemeDao { - private JdbcTemplate jdbcTemplate; - - public ThemeDao(JdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - public List findAll() { - return jdbcTemplate.query("SELECT * FROM theme where deleted = false", (rs, rowNum) -> new Theme( - rs.getLong("id"), - rs.getString("name"), - rs.getString("description") - )); - } - - public Theme save(Theme theme) { - KeyHolder keyHolder = new GeneratedKeyHolder(); - jdbcTemplate.update(connection -> { - var ps = connection.prepareStatement("INSERT INTO theme(name, description) VALUES (?, ?)", new String[]{"id"}); - ps.setString(1, theme.getName()); - ps.setString(2, theme.getDescription()); - return ps; - }, keyHolder); - - return new Theme(keyHolder.getKey().longValue(), theme.getName(), theme.getDescription()); - } - - public void deleteById(Long id) { - jdbcTemplate.update("UPDATE theme SET deleted = true WHERE id = ?", id); - } -} diff --git a/src/main/java/roomescape/theme/ThemeRepository.java b/src/main/java/roomescape/theme/ThemeRepository.java new file mode 100644 index 000000000..304cb0ef1 --- /dev/null +++ b/src/main/java/roomescape/theme/ThemeRepository.java @@ -0,0 +1,8 @@ +package roomescape.theme; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ThemeRepository extends JpaRepository { +} diff --git a/src/main/java/roomescape/theme/ThemeService.java b/src/main/java/roomescape/theme/ThemeService.java new file mode 100644 index 000000000..991c1aac8 --- /dev/null +++ b/src/main/java/roomescape/theme/ThemeService.java @@ -0,0 +1,28 @@ +package roomescape.theme; + +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class ThemeService { + private final ThemeRepository themeRepository; + + public ThemeService(ThemeRepository themeRepository){ + this.themeRepository=themeRepository; + } + + public Theme create(Theme theme){ + return themeRepository.save(theme); + } + + public void delete(Long id){ + themeRepository.deleteById(id); + } + + public List findAll(){ + return themeRepository.findAll(); + } + +} + diff --git a/src/main/java/roomescape/time/Time.java b/src/main/java/roomescape/time/Time.java index 008ed93cf..0e8decf1a 100644 --- a/src/main/java/roomescape/time/Time.java +++ b/src/main/java/roomescape/time/Time.java @@ -1,27 +1,31 @@ package roomescape.time; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; + +@Entity +@Getter public class Time { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String value; + private String timeValue; + @Builder public Time(Long id, String value) { this.id = id; - this.value = value; + this.timeValue = value; } public Time(String value) { - this.value = value; + this.timeValue = value; } public Time() { } - - public Long getId() { - return id; - } - - public String getValue() { - return value; - } } diff --git a/src/main/java/roomescape/time/TimeController.java b/src/main/java/roomescape/time/TimeController.java index 2343114d1..3850c6773 100644 --- a/src/main/java/roomescape/time/TimeController.java +++ b/src/main/java/roomescape/time/TimeController.java @@ -14,7 +14,7 @@ @RestController public class TimeController { - private TimeService timeService; + private final TimeService timeService; public TimeController(TimeService timeService) { this.timeService = timeService; @@ -27,7 +27,7 @@ public List