연관관계 설정
board 테이블에 user_id 컬럼 생성 후 user 테이블의 외래키로 설정
Board.java
package com.toy.board.domain;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
@Data
public class Board {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Size(min=2, max=30, message = "제목은 2자이상 30자 이하입니다.")
private String title;
private String content;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
list.html
<tr th:each="board : ${boards}">
<td th:text="${board.id}">Mark</td>
<td><a th:text="${board.title}" th:href="@{/board/form(id=${board.id})}">Otto</a></td>
<td th:text="${board.user.username}">홍길동</td>
</tr>
작성자가 홍길도 대신 username이 나오도록 코드 추가
하지만 새로운 글을 쓰면 작성자 이름이 체크 되지 않는다
BoardService.java
package com.toy.board.service;
import com.toy.board.domain.Board;
import com.toy.board.domain.User;
import com.toy.board.reopsitory.BoardRepository;
import com.toy.board.reopsitory.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BoardService {
@Autowired
private BoardRepository boardRepository;
@Autowired
private UserRepository userRepository;
public Board save(String username, Board board) {
User user = userRepository.findByUsername(username);
board.setUser(user);
return boardRepository.save(board);
}
}
UserRepository.java
package com.toy.board.reopsitory;
import com.toy.board.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}
BoardController.java
package com.toy.board.web;
import com.toy.board.domain.Board;
import com.toy.board.reopsitory.BoardRepository;
import com.toy.board.service.BoardService;
import com.toy.board.validator.BoardValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
private BoardRepository boardRepository;
@Autowired
private BoardService boardService;
@Autowired
private BoardValidator boardValidator;
@GetMapping("/list")
public String list(Model model, @PageableDefault(size=2) Pageable pageable,
@RequestParam(required = false, defaultValue = "") String searchText) {
// Page<Board> boards = boardRepository.findAll(pageable);
Page<Board> boards = boardRepository.findByTitleContainingOrContentContaining(searchText, searchText, pageable);
int startPage = Math.max(1, boards.getPageable().getPageNumber() - 4);
int endPage = Math.min(boards.getTotalPages(), boards.getPageable().getPageNumber() + 4);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("boards", boards);
return "/board/list";
}
@GetMapping("/form")
public String form(Model model, @RequestParam(required = false) Long id) {
if (id == null) {
model.addAttribute("board", new Board());
} else {
Optional<Board> board = boardRepository.findById(id);
model.addAttribute("board", board);
}
return "/board/form";
}
@PostMapping("/form")
public String postForm(@Valid Board board, BindingResult bindingResult, Authentication authentication) {
boardValidator.validate(board, bindingResult);
if (bindingResult.hasErrors()) {
return "board/form";
}
String username = authentication.getName();
// boardRepository.save(board);
boardService.save(username, board);
return "redirect:/board/list";
}
}
User 조회 기능 추가
UserApiController.java
package com.toy.board.web;
import com.toy.board.domain.User;
import com.toy.board.reopsitory.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
class UserApiController {
@Autowired
private UserRepository userRepository;
@GetMapping("/users")
List<User> all() {
return userRepository.findAll();
}
@PostMapping("/users")
User newUser(@RequestBody User newUser) {
return userRepository.save(newUser);
}
// Single item
@GetMapping("/user/{id}")
User one(@PathVariable Long id) {
return userRepository.findById(id).orElse(null);
}
@PutMapping("/users/{id}")
User replaceUser(@RequestBody User user, @PathVariable Long id) {
return userRepository.findById(id)
.map(User -> {
// User.setTitle(user.getTitle());
// User.setContent(user.getContent());
return userRepository.save(User);
})
.orElseGet(() -> {
user.setId(id);
return userRepository.save(user);
});
}
@DeleteMapping("/users/{id}")
void deleteUser(@PathVariable Long id) {
userRepository.deleteById(id);
}
}
User.java
package com.toy.board.domain;
import com.fasterxml.jackson.annotation.JacksonAnnotation;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private Boolean enabled;
@ManyToMany
@JoinTable(
name = "user_role",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private List<Role> roles = new ArrayList<>();
@OneToMany(mappedBy = "user")
private List<Board> boards = new ArrayList<>();
}
하지만 조회 시 무한호출이 발생 jsonignore 사용
Role.java
package com.toy.board.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@Entity
public class Role{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "roles")
@JsonIgnore
private List<User> users = new ArrayList<>();
}
Board.java
package com.toy.board.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Entity
@Data
public class Board {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Size(min=2, max=30, message = "제목은 2자이상 30자 이하입니다.")
private String title;
private String content;
@ManyToOne
@JoinColumn(name = "user_id")
@JsonIgnore
private User user;
}
PostMap으로 확인
user_id 로 user 조회 및 변경
UserApiController.java
package com.toy.board.web;
import com.toy.board.domain.Board;
import com.toy.board.domain.User;
import com.toy.board.reopsitory.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
class UserApiController {
@Autowired
private UserRepository userRepository;
@GetMapping("/users")
List<User> all() {
return userRepository.findAll();
}
@PostMapping("/users")
User newUser(@RequestBody User newUser) {
return userRepository.save(newUser);
}
// Single item
@GetMapping("/users/{id}")
User one(@PathVariable Long id) {
return userRepository.findById(id).orElse(null);
}
@PutMapping("/users/{id}")
User replaceUser(@RequestBody User newUser, @PathVariable Long id) {
return userRepository.findById(id)
.map(user -> {
// User.setTitle(user.getTitle());
// User.setContent(user.getContent());
// user.setBoards(newUser.getBoards());
user.getBoards().clear();
user.getBoards().addAll(newUser.getBoards());
for (Board board : user.getBoards()) {
board.setUser(user);
}
user.setBoards(newUser.getBoards());
return userRepository.save(user);
})
.orElseGet(() -> {
newUser.setId(id);
return userRepository.save(newUser);
});
}
@DeleteMapping("/users/{id}")
void deleteUser(@PathVariable Long id) {
userRepository.deleteById(id);
}
}
user_id 를 가진 board 코드 추가
user.setBoards(newUser.getBoards());
for (Board board : user.getBoards()) {
board.setUser(user);
}
user.setBoards(newUser.getBoards());
WebSecurityConfig.java
package com.toy.board.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Autowired
private DataSource dataSource;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests((requests) -> requests
.antMatchers("/", "/account/register", "/css/**", "/api/**").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/account/login")
.permitAll()
)
.logout((logout) -> logout.permitAll());
return http.build();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username, password, enabled "
+ "from user "
+ "where username = ?")
.authoritiesByUsernameQuery("select u.username, r.name "
+ "from user_role ur inner join user u on ur.user_id = u.id "
+ "inner join role r on ur.role_id = r.id "
+ "where username = ?");
}
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
.csrf().disable() 코드 추가,
api 로 접근 시 허가 추가 코드 : .antMatchers("/", "/account/register", "/css/**", "/api/**").permitAll()
Get 호출
Put 호출
delete 호출
'JPA' 카테고리의 다른 글
JPA - 권한에 맞는 화면 구성 및 API 호출 (0) | 2022.09.13 |
---|---|
JPA - Jpa로 조회방법(FetchType) 설정하기 (0) | 2022.09.12 |
JPA - 다대다 관계 한계 극복 (0) | 2022.09.11 |
JPA - Spring Security를 이용한 로그인 처리 (0) | 2022.09.10 |
JPA - Jpa를 이용한 페이지 처리 및 검색 (0) | 2022.09.09 |