Spring_boot/Project

[Spring] JPA로 블로그하고 데이터를 액세스 하기

달의요정루나 2022. 8. 7. 19:42

https://julian5383.tistory.com/93

 

[Spring] MVC를 이용해 블로그 만들기

프로젝트를 생성합니다. Spring Boot DevTools, Lombok, Thymeleaf, Spring Web이 선택됩니다. Overview 옆에 있는 Dependencies로 들어갑니다. javax.validation를 추가한다. - src/main/java 코딩문 1. co..

julian5383.tistory.com

다음 게시물에서 이어집니다.

새로운 dependency를 추가한다.

Spring Data JPA와 MySQL Driver를 추가한다.

pom.xml으로 들어가서 Dependencies에 새로운 것을 추가한다.(org.hibernate.validator)

applocation.properties에 새로운 구문을 추가한다.

spring.thymeleaf.cache = false
spring.thymeleaf.prefix = classpath:/templates
spring.datasource.initialization-mode = always
spring.datasource.data = classpath:/sql/spring-boot-mysql.sql

server.port = 8080

spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost/jpa_ex?characterEncoding=utf8&serverTimezone=Asia/Seoul
spring.datasource.username = root
spring.datasource.password = root

spring.jpa.properties.hibernate.hbm2ddl.auto = update

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=TRUE

여기서 아래쪽에 3번 줄에 있는 spring.jpa.properties.hibernate.hbm2ddl.auto는 update로 되어 있어야 한다.

create로 되어있으면 삽입되어 있던 sql구문들이 초기화 된다.

Database Development로 들어가 데이터베이스를 연결시킨다.

src/main/resources/sql에 sql파일을 추가한다.(맨 아래쪽 깃허브에 첨부)

sql분을 하나씩 드래그해서 실행할 수 있고(Execute Selected Text) 전부다 실행해도 된다.(Execute All)

그러면 각 테이블에 데이터가 들어갈 것이다.

모델에 있는 코드문을 수정한다.

package com.aaa.blog.model;

import java.util.Collection;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotEmpty;

import org.hibernate.validator.constraints.Length;
import org.springframework.format.annotation.DateTimeFormat;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Post {

	@Id
	@Column(name="POST_ID")
	private Long id;
	
	@Column(nullable = false)
	@Length(min=5, max=30, message="**최소 5글자 이상 30글자 이하로 입력해주세요")
	@NotEmpty(message="**제목을 입력하세요")
	private String title;
	
	@Lob
	private String body;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = false, updatable = false)
	@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
	private Date createdDate;
	
	@ManyToOne
	@JoinColumn(name="USER_ID", referencedColumnName = "USER_ID", nullable = false)
	private User user;
	
	@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
	private Collection<Tag> tags;
}

Post.java

package com.aaa.blog.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotEmpty;

import org.springframework.format.annotation.DateTimeFormat;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Tag {

	@Id
	@Column(name="TAG_ID")
	private Long id;
	
	@Column
	@NotEmpty(message="**입력해주세요")
	private String body;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable = false, updatable = false)
	@DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss")
	private Date createdDate;
	
	@ManyToOne
	@JoinColumn(name="POST_ID", referencedColumnName = "POST_ID", nullable = false)
	private Post post;
	
	@ManyToOne
	@JoinColumn(name="USER_ID", referencedColumnName = "USER_ID", nullable = false)
	private User user;
}

Tag.java

package com.aaa.blog.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;

import org.hibernate.validator.constraints.Length;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name="BlogUser")
public class User {
	
	@Id
	@Column(name="USER_ID", nullable = false, unique = true)
	private Long id;
	
	@Column(unique = true, nullable = false)
	@Length(min=2, max=30, message="**아이디는 2자 이상 30자 이하입니다.")
	@NotEmpty(message="**계정명을 입력해주세요")
	private String username;
	
	@Column(nullable = false)
	@Length(min=5, message = "**암호를 5글자 이상으로 입력하세요")
	@NotEmpty(message="**암호를 입력하세요")
	@JsonIgnore
	private String password;
	
	@Column
	@Email(message = "**유효한 이메일 계정을 입력해주세요")
	@NotEmpty(message="**이메일 계정을 입력하세요")
	private String email;
	
	@Column
	@NotEmpty(message = "**이름을 입력하세요")
	private String fullname;
	
	@Column
	private UserRole role;
}

User.java

새로운 게시물도 만든다.

package com.aaa.blog.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

import com.aaa.blog.model.Post;
import com.aaa.blog.model.User;

public interface PostJpaRepository extends JpaRepository<Post, Long> {

	Page<Post> findByUserOrderById(User user, Pageable pageable);
	Page<Post> findAllByOrderById(Pageable pageable);
}

PostJpaRepository.java

package com.aaa.blog.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.aaa.blog.model.Tag;

public interface TagJpaRepository extends JpaRepository<Tag, Long> {

}

TagJpaRepository.java

package com.aaa.blog.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;

import com.aaa.blog.model.User;

public interface UserJpaRepository extends JpaRepository<User, Long> {

	Optional<User> findByEmail(@Param("email") String email);
	Optional<User> findByUsername(@Param("username") String username);
}

UserJpaRepository.java

package com.aaa.blog.service;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import com.aaa.blog.model.Post;
import com.aaa.blog.repository.PostJpaRepository;

@Service
@Primary
public class PostServiceJpaImpl implements PostService {

	@Autowired
	private PostJpaRepository postJpaRepository;
	
	@Override
	public List<Post> findAllOrderedById() {
		// TODO Auto-generated method stub
		return this.postJpaRepository.findAll().stream().sorted(Comparator.comparing(Post::getId)).collect(Collectors.toList());
	}

	@Override
	public List<Post> findAllOrderedById(int page) {
		// TODO Auto-generated method stub
		return this.postJpaRepository.findAll().stream().sorted(Comparator.comparing(Post::getId)).limit(page).collect(Collectors.toList());
	}

	@Override
	public Optional<Post> findById(Long id) {
		// TODO Auto-generated method stub
		return this.postJpaRepository.findById(id);
	}

	@Override
	public Post create(Post post) {
		// TODO Auto-generated method stub
		return this.postJpaRepository.saveAndFlush(post);
	}

	@Override
	public Post edit(Post post) {
		// TODO Auto-generated method stub
		return this.postJpaRepository.saveAndFlush(post);
	}

	@Override
	public void deleteById(Long id) {
		// TODO Auto-generated method stub
		this.postJpaRepository.deleteById(id);
	}

}

PostServiceJpaImpl.java

package com.aaa.blog.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import com.aaa.blog.model.Tag;
import com.aaa.blog.repository.TagJpaRepository;

@Service
@Primary
public class TagServiceJpaImpl implements TagService {

	@Autowired
	private TagJpaRepository tagJpaRepository;
	
	@Override
	public Tag save(Tag tag) {
		// TODO Auto-generated method stub
		return this.tagJpaRepository.saveAndFlush(tag);
	}

	@Override
	public List<Tag> getTags() {
		// TODO Auto-generated method stub
		return this.tagJpaRepository.findAll();
	}

}

TagServiceJpaImpl.java

package com.aaa.blog.service;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

import org.springframework.beans.factory.annotation.Autowired;

import com.aaa.blog.model.User;
import com.aaa.blog.repository.UserJpaRepository;

public class UserServiceJpaImpl implements UserService {
	
	@Autowired
	private UserJpaRepository userJpaRepository;

	@Override
	public List<User> findAll() {
		// TODO Auto-generated method stub
		return this.userJpaRepository.findAll();
	}

	@Override
	public Optional<User> findById(Long id) {
		// TODO Auto-generated method stub
		return this.userJpaRepository.findById(id);
	}

	@Override
	public Optional<User> findByUsername(String username) {
		// TODO Auto-generated method stub
		return this.userJpaRepository.findByUsername(username);
	}

	@Override
	public Optional<User> findByEmail(String email) {
		// TODO Auto-generated method stub
		return this.userJpaRepository.findByEmail(email);
	}

	@Override
	public User register(User user) {
		// TODO Auto-generated method stub
		user.setId(this.userJpaRepository.findAll().stream().map(User::getId).max(Comparator.naturalOrder()).orElse(Long.MIN_VALUE));
		return this.userJpaRepository.save(user);
	}

	@Override
	public boolean authenticate(String username, String password) {
		// TODO Auto-generated method stub
		Predicate<User> loginFilter = u->u.getUsername().equals(username) && u.getPassword().equals(password);
		return this.userJpaRepository.findAll().stream().filter(loginFilter).findAny().isPresent();
	}

}

UserServiceJpaImpl.java

 

최종결과

 

https://github.com/Julian-Hwang/spring_boot_project/tree/main/Spring-Blog-Jpa

 

GitHub - Julian-Hwang/spring_boot_project

Contribute to Julian-Hwang/spring_boot_project development by creating an account on GitHub.

github.com