Skip to content

Commit

Permalink
Merge pull request #1 from yudonggeun/user_service
Browse files Browse the repository at this point in the history
User service
  • Loading branch information
yudonggeun authored Sep 14, 2023
2 parents 1e4b4bb + bbe11f4 commit 30774b0
Show file tree
Hide file tree
Showing 26 changed files with 1,033 additions and 2 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
// developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
Empty file added index.adoc
Empty file.
59 changes: 59 additions & 0 deletions src/main/java/com/websocket/demo/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.websocket.demo.controller;

import com.websocket.demo.request.AddFriendRequest;
import com.websocket.demo.request.CreateUserRequest;
import com.websocket.demo.request.LoginRequest;
import com.websocket.demo.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

@PostMapping("/login")
public String loginUser(@ModelAttribute LoginRequest request, HttpServletRequest servletRequest){
if (userService.login(request)) {
servletRequest.getSession(true).setAttribute("user", request);
return "redirect:/";
}
return "login";
}

@PostMapping("/create")
public String createUser(@ModelAttribute CreateUserRequest request){
try {
if (userService.create(request)) return "redirect:/";
} catch (RuntimeException e){
return "createUser";
}
return "createUser";
}

@PostMapping("/friend")
public String newFriend(@ModelAttribute AddFriendRequest request, @SessionAttribute(name = "user", required = false) LoginRequest userInfo){
if(userService.addFriend(request, userInfo.getNickname())) return "redirect:/";
return "addFriend";
}

@GetMapping("/create")
public String createUserPage(){
return "createUser";
}

@GetMapping("/login")
public String loginPage() {
return "login";
}

@GetMapping("/friend")
public String addFriendPage() {
return "addFriend";
}
}

47 changes: 47 additions & 0 deletions src/main/java/com/websocket/demo/domain/Friend.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.websocket.demo.domain;

import com.websocket.demo.response.FriendInfo;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "FRIENDS")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Friend {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String userNickname;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "friend_nickname")
private User friend;

@Builder
private Friend(String userNickname, User friend) {
this.userNickname = userNickname;
this.friend = friend;
}

public String getUserNickname() {
return userNickname;
}

public User getFriend() {
return this.friend;
}

public FriendInfo toInfo() {
return new FriendInfo(getFriend().getNickname());
}

@Override
public String toString() {
return "Friend{" +
"id=" + id +
", userNickname='" + userNickname + '\'' +
", friend=" + friend.getNickname() +
'}';
}
}
72 changes: 72 additions & 0 deletions src/main/java/com/websocket/demo/domain/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.websocket.demo.domain;

import com.websocket.demo.request.LoginRequest;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "USERS")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {

@Id
@Column(columnDefinition = "varchar(20)")
private String nickname;
@Column(columnDefinition = "varchar(20)")
private String password;
@OneToMany(mappedBy = "friend", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Friend> friends = new ArrayList<>();

@Builder
public User(String nickname, String password) {
this.nickname = nickname;
this.password = password;
}

public void addFriends(User... friends) {
for (var friend : friends) {
this.friends.add(Friend.builder()
.userNickname(getNickname())
.friend(friend)
.build()
);
}
}

public boolean match(LoginRequest request) {
return request.getNickname().equals(nickname) &&
request.getPassword().equals(password);
}


public String getNickname() {
return nickname;
}

public String getPassword() {
return password;
}

public List<Friend> getFriends() {
return friends;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(nickname, user.nickname);
}

@Override
public int hashCode() {
return Objects.hash(nickname);
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/websocket/demo/repository/FriendRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.websocket.demo.repository;

import com.websocket.demo.domain.Friend;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface FriendRepository extends JpaRepository<Friend, Long> {

@EntityGraph(attributePaths = "friend")
List<Friend> findByUserNickname(String nickname);

@Modifying(flushAutomatically = true)
@Query("delete from Friend f where f.userNickname=:userNickname and f.friend.nickname=:friendNickname")
void deleteByUserNicknameAndFriendNickname(@Param("userNickname") String userNickname,@Param("friendNickname") String friendNickname);
}
10 changes: 10 additions & 0 deletions src/main/java/com/websocket/demo/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.websocket.demo.repository;

import com.websocket.demo.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, String> {
User findByNickname(String nickname);

boolean existsByNickname(String nickname);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.websocket.demo.request;

import lombok.Data;

@Data
public class AddFriendRequest {
private String nickname;
}
10 changes: 10 additions & 0 deletions src/main/java/com/websocket/demo/request/CreateUserRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.websocket.demo.request;

import lombok.Data;

@Data
public class CreateUserRequest {

private String nickname;
private String password;
}
9 changes: 9 additions & 0 deletions src/main/java/com/websocket/demo/request/LoginRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.websocket.demo.request;

import lombok.Data;

@Data
public class LoginRequest {
private String nickname;
private String password;
}
8 changes: 8 additions & 0 deletions src/main/java/com/websocket/demo/response/FriendInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.websocket.demo.response;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class FriendInfo {
private String nickname;
}
57 changes: 57 additions & 0 deletions src/main/java/com/websocket/demo/service/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.websocket.demo.service;

import com.websocket.demo.domain.Friend;
import com.websocket.demo.domain.User;
import com.websocket.demo.repository.FriendRepository;
import com.websocket.demo.repository.UserRepository;
import com.websocket.demo.request.AddFriendRequest;
import com.websocket.demo.request.CreateUserRequest;
import com.websocket.demo.request.LoginRequest;
import com.websocket.demo.response.FriendInfo;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;

import java.util.List;

@RequiredArgsConstructor
@Transactional
@Service
public class UserService {

private final UserRepository userRepository;
private final FriendRepository friendRepository;

public boolean login(LoginRequest request) {
User findUser = userRepository.findByNickname(request.getNickname());
return findUser != null && findUser.match(request);
}

public boolean create(CreateUserRequest request) {
if (userRepository.existsByNickname(request.getNickname())) return false;
userRepository.save(User.builder()
.nickname(request.getNickname())
.password(request.getPassword())
.build());
return true;
}

public boolean addFriend(AddFriendRequest request, String userNickname) {
User user = userRepository.findByNickname(userNickname);
User friend = userRepository.findByNickname(request.getNickname());
if (friend == null || user == null) return false;
user.addFriends(friend);
return true;
}

public List<FriendInfo> friendList(String nickname) {
User user = userRepository.findByNickname(nickname);
List<Friend> byFieldsUserId = friendRepository.findByUserNickname(user.getNickname());
return byFieldsUserId.stream().map(Friend::toInfo).toList();
}

public void removeFriendByNickname(String userNickname, String friendNickname) {
friendRepository.deleteByUserNicknameAndFriendNickname(userNickname, friendNickname);
}
}
11 changes: 11 additions & 0 deletions src/main/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true


#logging:
# level:
# org.hibernate.SQL: DEBUG
1 change: 0 additions & 1 deletion src/main/resources/application.properties

This file was deleted.

7 changes: 7 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spring:
datasource:
url: jdbc:h2:mem:testdb
h2:
console:
enabled: true
path: /db
16 changes: 16 additions & 0 deletions src/main/resources/templates/addFriend.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>친구 추가 </title>
</head>
<body>
<section>
<h2>친구 추가</h2>
</section>
<form method="post" name="login" action="/user/friend">
<p> 닉네임 <input type="text" name="nickname" placeholder="친구의 닉네임을 입력해주세요"> </p>
<p> <input type="submit" value="추가하기"></p>
</form>
</body>
</html>
17 changes: 17 additions & 0 deletions src/main/resources/templates/createUser.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>회원가입 페이지</title>
</head>
<body>
<section>
<h1>회원가입 페이지</h1>
</section>
<form method="post" name="login" action="/user/create">
<p> 닉네임 <input type="text" name="nickname" placeholder="닉네임을 입력해주세요"> </p>
<p> 비밀번호 <input type="text" name="password" placeholder="비밀번호를 입력해주세요"> </p>
<p> <input type="submit" value="회원가입"></p>
</form>
</body>
</html>
Loading

0 comments on commit 30774b0

Please sign in to comment.