Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# 2022 Java Spring Cafe

2022년도 마스터즈 멤버스 백엔드 스프링 카페 프로젝트

## 스프링 카페 3단계 - DB에 저장하기

### 프로그래밍 요구사항

- [x] H2 데이터베이스 연동
- [x] H2 데이터베이스 의존성을 추가하고 연동한다.
- [x] ORM은 사용하지 않는다.
- [x] Spring JDBC를 사용한다.
- [x] DB 저장 및 조회에 필요한 SQL은 직접 작성한다.

- [x] 게시글 데이터 저장하기
- [x] Article 클래스를 DB 테이블에 저장할 수 있게 구현한다.
- Article 테이블이 적절한 PK를 가지도록 구현한다.

- [x] 게시글 목록 구현하기
- [x] 전체 게시글 목록 데이터를 DB에서 조회하도록 구현한다.

- [x] 게시글 상세보기 구현하기
- [x] 게시글의 세부 내용을 DB에서 가져오도록 구현한다.

- [x] 사용자 정보 DB에 저장
- [x] 회원가입을 통해 등록한 사용자 정보를 DB에 저장한다.

- [x] 배포
- [x] Heroku로 배포를 진행하고 README에 배포 URL을 기술한다.
- https://donggi-spring-cafe.herokuapp.com/



6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.h2database:h2'
}

test {
useJUnitPlatform()
}

jar {
enabled = false
}
2 changes: 0 additions & 2 deletions src/main/java/com/kakao/cafe/controller/HomeController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.kakao.cafe.domain.Article;
import com.kakao.cafe.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -14,7 +13,6 @@ public class HomeController {

private final ArticleService articleService;

@Autowired
public HomeController(ArticleService articleService) {
this.articleService = articleService;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@

import com.kakao.cafe.domain.Article;
import com.kakao.cafe.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/articles")
public class ArticleController {

private final ArticleService articleService;

@Autowired
public ArticleController(ArticleService articleService) {
this.articleService = articleService;
}
Expand All @@ -34,17 +30,10 @@ public String saveArticleForm(ArticleForm form) {
return "redirect:/";
}

@GetMapping
public String articles(Model model) {
List<Article> articles = articleService.findArticles();
model.addAttribute("articles", articles);
return "home";
}

@GetMapping("/{id}")
public String article(@PathVariable Integer id, Model model) {
public String article(@PathVariable int id, Model model) {
Article article = articleService.findArticle(id);
model.addAttribute("article", article);
return "/articles/article";
return "articles/article";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import com.kakao.cafe.domain.Article;

public class ArticleForm {
private String title;

private String title;
private String text;
private int id;

public static Article toEntity(ArticleForm form) {
return new Article(form.getTitle(), form.getText());
public Article toEntity() {
return new Article(title, text);
}

public String getTitle() {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/kakao/cafe/controller/user/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.kakao.cafe.domain.User;
import com.kakao.cafe.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

Expand All @@ -15,15 +17,13 @@ public class UserController {

private final UserService userService;

@Autowired

public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/signup")
public String createForm() {
return "/user/form";
return "user/form";
}

@PostMapping("/signup")
Expand All @@ -44,6 +44,6 @@ public String list(Model model) {
public String profile(@PathVariable String name, Model model) {
User user = userService.findUser(name);
model.addAttribute("user", user);
return "/user/profile";
return "user/profile";
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/kakao/cafe/domain/Article.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
public class Article {

private int id;
private String title;
private String text;
private final String title;
private final String text;

public Article(String title, String text) {
this.title = title;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/kakao/cafe/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ public class User {
private String email;
private String password;

public User(String name, String email, String password) {
public User(String name, String email) {
this.name = name;
this.email = email;
}

public User(String name, String email, String password) {
this(name, email);
this.password = password;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import java.util.List;
import java.util.Optional;

public interface CafeRepository<T, V> {
public interface Repository<T, V> {

void save(T t);
T save(T t);

Optional<T> findByName(V name);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.kakao.cafe.repository.article;

import com.kakao.cafe.domain.Article;
import com.kakao.cafe.repository.Repository;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Primary
@org.springframework.stereotype.Repository
public class JdbcArticleRepository implements Repository<Article, Integer> {

private final JdbcTemplate jdbcTemplate;

public JdbcArticleRepository(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}

@Override
public Article save(Article article) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("article").usingGeneratedKeyColumns("id");

Map<String, Object> parameters = new HashMap<>();
parameters.put("title", article.getTitle());
parameters.put("text", article.getText());

Number key = jdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters));
return new Article(key.intValue(), article.getTitle(), article.getText());
}

@Override
public Optional<Article> findByName(Integer id) {
List<Article> result = jdbcTemplate.query("select title, text from article where id = ?", articleRowMapper(), id);
return result.stream().findAny();
}

@Override
public List<Article> findAll() {
return jdbcTemplate.query("select title, text from article", articleRowMapper());
}

private RowMapper<Article> articleRowMapper() {
return (rs, rowNum) -> new Article(rs.getInt("id"), rs.getString("title"), rs.getString("text"));
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
package com.kakao.cafe.repository.article;

import com.kakao.cafe.domain.Article;
import com.kakao.cafe.repository.CafeRepository;
import org.springframework.stereotype.Repository;
import com.kakao.cafe.repository.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;

@Repository
public class MemoryArticleRepository implements CafeRepository<Article, Integer> {
@org.springframework.stereotype.Repository
public class MemoryArticleRepository implements Repository<Article, Integer> {

private List<Article> articles = new CopyOnWriteArrayList<>();
private final List<Article> articles = new CopyOnWriteArrayList<>();

@Override
public void save(Article article) {
Article articleWithId = new Article (articles.size() + 1, article.getTitle(), article.getText());
public Article save(Article article) {
Article articleWithId = new Article(articles.size() + 1, article.getTitle(), article.getText());
articles.add(articleWithId);
return articleWithId;
}

@Override
public Optional<Article> findByName(Integer id) {
return articles.stream()
.filter(article -> article.getId() == id)
.findAny();
return Optional.ofNullable(articles.get(id));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.kakao.cafe.repository.user;

import com.kakao.cafe.domain.User;
import com.kakao.cafe.repository.Repository;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Primary
@org.springframework.stereotype.Repository
public class JdbcUserRepository implements Repository<User, String> {

private final JdbcTemplate jdbcTemplate;

public JdbcUserRepository(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}

@Override
public User save(User user) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("user");

Map<String, Object> parameters = new HashMap<>();
parameters.put("name", user.getName());
parameters.put("email", user.getEmail());
jdbcInsert.execute(parameters);

return new User(user.getName(), user.getEmail());
}

@Override
public Optional<User> findByName(String name) {
List<User> result = jdbcTemplate.query("select name, email from user where name = ?", userRowMapper(), name);
return result.stream().findAny();
}

@Override
public List<User> findAll() {
return jdbcTemplate.query("select name, email from user", userRowMapper());
}

private RowMapper<User> userRowMapper() {
return (rs, rowNum) -> new User(rs.getString("name"), rs.getString("email"));
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package com.kakao.cafe.repository.user;

import com.kakao.cafe.domain.User;
import com.kakao.cafe.repository.CafeRepository;
import org.springframework.stereotype.Repository;
import com.kakao.cafe.repository.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;

@Repository
public class MemoryUserRepository implements CafeRepository<User, String> {
@org.springframework.stereotype.Repository
public class MemoryUserRepository implements Repository<User, String> {

private List<User> store = new CopyOnWriteArrayList<>();
private final List<User> store = new CopyOnWriteArrayList<>();

@Override
public void save(User user) {
public User save(User user) {
store.add(user);
return user;
}

@Override
Expand Down
Loading