연관관계 설정

 

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 호출

 

복사했습니다!