Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ out/

### VS Code ###
.vscode/

/bin/
8 changes: 8 additions & 0 deletions src/main/java/nextstep/courses/domain/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import nextstep.payments.domain.Payment;

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

public abstract class Session {
protected Long id;
protected String name;
Expand All @@ -18,6 +21,11 @@ public Session(Long id, String name, Period period, Image coverImage, SessionSta
this.status = status;
this.registeredStudents = new Students();
}
public List<Long> getStudentIds() {
return registeredStudents.getStudents().stream()
.map(Student::getId)
.collect(Collectors.toList());
}

public Students getRegisteredStudent() {
return registeredStudents;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/nextstep/courses/domain/Students.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.HashSet;
import java.util.Set;
import java.util.Collections;

public class Students {
private Set<Student> students = new HashSet<>();
Expand All @@ -25,4 +26,8 @@ public boolean contains(Student student) {
public int size() {
return students.size();
}

public Set<Student> getStudents() {
return Collections.unmodifiableSet(students);
}
}
4 changes: 4 additions & 0 deletions src/main/java/nextstep/courses/domain/TuitionFee.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public boolean isSameAmount(int amount) {
return this.amount == amount;
}

public int getValue() {
return amount;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,116 @@
import nextstep.courses.domain.PaidSession;
import nextstep.courses.domain.FreeSession;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class JdbcSessionRepository {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final JdbcTemplate jdbcTemplate;

public JdbcSessionRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
}

@Transactional
public void save(Session session, Long courseId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Session이 courseId를 가지는 구조는 어떤가요?

Long imageId = null;
if (session.getCoverImage() != null) {
imageId = insertImage(session.getCoverImage());
}

String sql = "insert into session (name, type, start_date, end_date, status, capacity, tuition_fee, image_id, course_id) " +
"values (?, ?, ?, ?, ?, ?, ?, ?, ?)";

jdbcTemplate.update(sql,
session.getName(),
session.getType().name(),
session.getPeriod().getStartDate(),
session.getPeriod().getEndDate(),
session.getStatus().name(),
session instanceof PaidSession ? ((PaidSession) session).getCapacity() : null,
session instanceof PaidSession ? ((PaidSession) session).getTuitionFee() : null,
imageId,
courseId
);
SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)
.withTableName("session")
.usingGeneratedKeyColumns("id");

Map<String, Object> params = new HashMap<>();
params.put("name", session.getName());
params.put("type", session.getType().name());
params.put("start_date", session.getPeriod().getStartDate());
params.put("end_date", session.getPeriod().getEndDate());
params.put("status", session.getStatus().name());
params.put("capacity", session instanceof PaidSession ? ((PaidSession) session).getCapacity().getValue() : null);
params.put("tuition_fee", session instanceof PaidSession ? ((PaidSession) session).getTuitionFee().getValue() : null);
params.put("image_id", imageId);
params.put("course_id", courseId);

insert.execute(params);
}

@Transactional
public void registerStudent(Long sessionId, Long studentId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 동작이 틀리지는 않았는데요

Session 도메인 모델 안에 Students를 가지고 있을 필요가 없어지는 것 같아서요
앞서 리뷰드린 도메인 모델 불일치와 비슷한 맥락입니다.

Session 도메인 모델의 register 메소드를 활용하려면
레포지토리의 registerStudent 호출 없이 동작할 수 있게 만들면 좋을 것 같습니다!

session.register(...);
sessionRepository.save(session);  // session 도메인 모델 내 수강생들도 함께 저장

String sql = "insert into session_student (session_id, student_id) values (:sessionId, :studentId)";
MapSqlParameterSource params = new MapSqlParameterSource()
.addValue("sessionId", sessionId)
.addValue("studentId", studentId);
namedParameterJdbcTemplate.update(sql, params);
}

public List<Session> findAll() {
String sql = "select s.*, i.file_name, i.content_type, i.size_in_bytes, i.width, i.height " +
"from session s left join image i on s.image_id = i.id";
return jdbcTemplate.query(sql, sessionRowMapper());
List<Session> sessions = namedParameterJdbcTemplate.query(sql, sessionRowMapper());

// 각 세션에 대한 수강생 정보를 함께 조회
for (Session session : sessions) {
List<Long> studentIds = findStudentIdsBySessionId(session.getId());
for (Long studentId : studentIds) {
session.register(studentId, null);
}
}
return sessions;
}

public Session findById(Long id) {
String sql = "select s.*, i.file_name, i.content_type, i.size_in_bytes, i.width, i.height " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Transactional(readOnly = true)

검색만 하니
명시적으로 readOnly 트랜잭션을 사용하면 어떨까요?

"from session s left join image i on s.image_id = i.id where s.id = ?";
return jdbcTemplate.queryForObject(sql, sessionRowMapper(), id);
"from session s left join image i on s.image_id = i.id where s.id = :id";
Session session = namedParameterJdbcTemplate.queryForObject(sql,
new MapSqlParameterSource("id", id),
sessionRowMapper());

if (session != null) {
// 세션의 수강생 정보를 함께 조회
List<Long> studentIds = findStudentIdsBySessionId(id);
for (Long studentId : studentIds) {
session.register(studentId, null);
}
}
return session;
}

@Transactional
public void update(Session session) {
String sql = "update session set name = ?, start_date = ?, end_date = ?, status = ?, capacity = ?, tuition_fee = ? where id = ?";
jdbcTemplate.update(sql,
session.getName(),
session.getPeriod().getStartDate(),
session.getPeriod().getEndDate(),
session.getStatus().name(),
session instanceof PaidSession ? ((PaidSession) session).getCapacity() : null,
session instanceof PaidSession ? ((PaidSession) session).getTuitionFee() : null,
session.getId()
);
String sql = "update session set name = :name, start_date = :startDate, end_date = :endDate, " +
"status = :status, capacity = :capacity, tuition_fee = :tuitionFee where id = :id";

MapSqlParameterSource params = new MapSqlParameterSource()
.addValue("name", session.getName())
.addValue("startDate", session.getPeriod().getStartDate())
.addValue("endDate", session.getPeriod().getEndDate())
.addValue("status", session.getStatus().name())
.addValue("capacity", session instanceof PaidSession ? ((PaidSession) session).getCapacity().getValue() : null)
.addValue("tuitionFee", session instanceof PaidSession ? ((PaidSession) session).getTuitionFee().isSameAmount(0) ? 0 : null : null)
.addValue("id", session.getId());

namedParameterJdbcTemplate.update(sql, params);
}

@Transactional
public void deleteById(Long id) {
jdbcTemplate.update("delete from session where id = ?", id);
deleteAllStudentsBySessionId(id);
String sql = "delete from session where id = :id";
namedParameterJdbcTemplate.update(sql, new MapSqlParameterSource("id", id));
}

private Long insertImage(Image image) {
Expand All @@ -90,6 +134,18 @@ private Long insertImage(Image image) {
return insert.executeAndReturnKey(params).longValue();
}

private List<Long> findStudentIdsBySessionId(Long sessionId) {
String sql = "select student_id from session_student where session_id = :sessionId";
return namedParameterJdbcTemplate.query(sql,
new MapSqlParameterSource("sessionId", sessionId),
(rs, rowNum) -> rs.getLong("student_id"));
}

private void deleteAllStudentsBySessionId(Long sessionId) {
String sql = "delete from session_student where session_id = :sessionId";
namedParameterJdbcTemplate.update(sql, new MapSqlParameterSource("sessionId", sessionId));
}

private RowMapper<Session> sessionRowMapper() {
return (rs, rowNum) -> {
SessionStatus status = SessionStatus.valueOf(rs.getString("status"));
Expand Down

This file was deleted.

Loading