목록Spring/기초 (14)
Hansel

일반적으로 트랜잭션 적용이 필요한 메서드 및 클래스에는 위와 같이 @Transactional 애노테이션을 붙여 사용했다. 데이터베이스에서 트랜잭션이 무엇을 의미하는지는 알았지만 저 애노테이션이 어떤 역할을 하는지 왜 필요한지에 대해서는 잘 알지 못했다. 위와 같은 애노테이션을 선언적 트랜잭션 관리 방법이라 한다. 선언적 트랜잭션 관리(Declarative Transaction Management) 간단히 @Transactional을 추가해 매우 편리하게 트랜잭션을 적용하는 것을 선언적 트랜잭션 관리라 한다. 이름 그대로 해당 로직에 트랜잭션을 적용하겠다 라고 어딘가에 선언하기만 하면 트랜잭션이 적용되는 방식이다. 이게 어떤 식으로 동작하는지는 스프링 AOP를 학습해야하는데 아직은 학습하지 않았기 때문에 ..

메인 화면에는 추천수가 높은 게시글만 몇개 보여주고 나머지 전체 게시글은 따로 보여주는 방식이 나을거같아서 그 방향으로 틀었다. Post의 경우 추천수를 변경해야 하기 때문에 Post 클래스에 해당 로직을 작성했고 Service를 통해 호출하도록 했다. public List findBySuggestion(){ return em.createQuery("select p from Post p order by p.suggestion desc",Post.class) .setFirstResult(0) .setMaxResults(5) .getResultList(); } 컨트롤러의 경우 어떤 글의 추천수가 올라가는지를 알아야 하기 때문에 id를 매개변수로 받아온다. 로직은 매우 간단하다. 몇줄 안된다. 메인화면에선 추..

이번엔 게시글을 작성할 수 있게 해야한다. 게시글을 작성하면서 그 게시글의 유저 또한 현재 로그인한 유저가 될 수 있도록 해줘야 한다. Post 또한 폼을 통한 생성이 필요하기 때문에 PostDto 클래스도 함께 작성한다. 유저를 생성했던 방식과 비슷하게 Post 폼 또한 각 필드의 내용이 PostDto에 담겨 Service의 submit을 호출한다. submit을 해서 바로 post 객체를 persist 하기 전에 게시글의 작성자가 누구인지를 명시해야 한다. 따라서 @AuthenticationPrincipal 을 통해 현재 로그인한 유저의 정보를 가져오는데 해당 어노테이션은 Username, Password, authorities 정도만 가져와서 더욱 더 상세한 유저의 정보가 필요하다면 다른 방법이 필..

앞서 말했듯이 이런식으로 하면 로그인이라 볼 수 없다. 따라서 로그인 기능을 갖출 수 있도록 다시 작성했다. https://hooongs.tistory.com/233 [Spring Boot] 간단한 로그인 기능 구현 - Spring Security Spring Security를 사용하여 간단하게 회원가입과 로그인 및 로그아웃 기능을 구현해보겠습니다. Django에서 auth와 같은 기능과 유사하다고 생각이 들었습니다. 그럼 이제 간단한 설명과 함께 코드를 hooongs.tistory.com 로그인 기능은 위 게시글을 많이 참고했다. Spring Security를 이용하면 정말 간단하게 로그인 기능을 구현할 수 있다. 자세한 내용은 위 티스토리 게시글과 주석을 확인하자. UserDto는 html에서 for..

jpa 기초와 스프링 부트 기초를 공부하고 뭐라도 우선 만들어보고 심화 과정으로 넘어가야겠다는 생각이 들었다. 딱히 아이디어도 없고 그래서 대충 로그인과 글 작성할 수 있는 게시판이나 만들어보자 해서 시작해봤다. 기본적인 도메인은 이런식으로 잡고 이거에 맞춰 만들면 되지 않을까 싶었지만 막상 하다보니 queryDsl과 jpa 심화 과정이 꽤나 절실하게 느껴졌다. 따라서 게시글과 비슷한 매커니즘을 갖는 댓글과 상속 구조를 갖는 카테고리는 생략하기로 했다. 처음엔 user를 이런 식을 짜서 하면 될거라 생각했는데 이러면 로그인 기능이 없다. 그래서 저러한 설계는 다 버리고 로그인 기능을 가질 수 있도록 다시 작성했다. 게시글은 대충 이렇게 잡았다. 작성자와 글 제목, 글 본문, 그리고 추천수와 작성일을 필드..

변경 감지와 병합 두 메서드를 보면 우선 setter를 남발하고 있다. updateItem 메서드 내부의 laptop 객체는 id(pk)가 있으니 리포지토리에서 else문을 타게 될것이다. 그럼 merge를 호출하게 되는데 이것의 문제점이 무엇인지 알아보자. 1. merge(병합) merge 방식은 파라미터로 넘겨 받은 데이터로 기존의 데이터를 바꿔치기 한다. 병합을 사용하면 모든 속성이 변경되기 때문에 병합 시 null이면 기존에 값이 있어도 null로 바뀐다 2. 변경 감지(dirty checking) 엔티티가 영속 상태면 값이 변경 되었을때 commit 시점에 db에 반영한다. one.changeValues() 등의 메서드를 만들어서 setter를 대체해야한다. 결론 변경감지는 원하는 속성만 변경할..

앞선 글과 같이 상품에 대해서도 Controller를 작성한다. laptopForm은 등록 아이템에 따라 다른 폼을 보낼 수 있도록 동적으로 해보는 도전이 필요해 보인다. 조회를 위한 html도 함께 작성한다. 결과 정상적으로 DB에 등록되는지 확인해야 한다. OrderController 폼을 받고 보내는 것은 이전에 봤던 방식과 똑같다. @RequestParam만 잘 이해하면 된다. @RequestParam 간단한 파라미터 요청 방식이다. 넘어오는 매개변수의 name 값을 적어서 거기에 필요한 값을 value로 받는다. URL 과 같이 보면 이해가 쉽다. @RequestParam은 required 옵션을 같이 쓰는데 기본값은 true다. 따라서 false가 아닐 때 받아온 data가 없다면 400 에러..

Thymeleaf 의 include 방식 https://www.thymeleaf.org/doc/articles/layouts.html Thymeleaf Page Layouts - Thymeleaf Summary In this article, we described many ways of achieving the same: layouts. You can build layouts using Thymeleaf Standard Layout System that is based on include-style approach. You also have powerful Layout Dialect, that uses decorator pattern for wor www.thymeleaf.org 각 태그마다 th:rep..

Order 엔티티 개발 @Entity @Getter @Setter @Table(name = "ORDERS") @NoArgsConstructor(access = AccessLevel.PROTECTED) //생성자 차단 public class Order { @Id @GeneratedValue @Column(name = "ORDER_ID") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "MEMBER_ID") //join하는 FK의 이름을 적어준다. 연관관계의 주인 private Member member; @OneToMany(mappedBy = "order",cascade = CascadeType.ALL) private List ..

Repository 객체를 작성했다면 그 객체에 알맞게 작성, 조회, 수정, 삭제 등을 하는 계층이 필요하다. 이러한 것들을 위한 로직이 모여있는 계층이 Repository이다. 위 리포지토리에선 엔티티매니저를 이용해 객체를 persist 하고 찾는 로직이 작성되어 있다. @PersistenceContext 는 스프링 컨테이너에 등록된 빈을 찾아 주입해준다. 최신 스프링 부트에선 @Autowired로도 가능하다고 한다. 그 아래 findByName 메서드는 매개변수로 name을 받는다. name이 일치한 member를 찾아 반환해주는 쿼리문이 담겨있는데 파라미터가 필요한 쿼리문의 경우 사진과 같이 작성을 해줘야 한다. 필드명 =: 매개변수 그 후 바로 getResultList를 호출해 받아오는게 아니라 ..