📌 1. 개요
📌 2. DB 설계

🔑 : PK, 🔒 : FK
CREATE TABLE IF NOT EXISTS users (
userId VARCHAR(20) PRIMARY KEY,
password VARCHAR(20) NOT NULL,
username VARCHAR(20) NOT NULL,
email VARCHAR(100) NOT NULL
);
CREATE TABLE IF NOT EXISTS reviews (
reviewId INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
videoId INT NOT NULL,
content VARCHAR(200) NOT NULL,
userId VARCHAR(20) NOT NULL,
FOREIGN KEY (userId) REFERENCES users(userId) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS videos (
videoId INT PRIMARY KEY NOT NULL,
title VARCHAR(100) NOT NULL,
fitPartName VARCHAR(100) NOT NULL,
youtubeId VARCHAR(100) NOT NULL,
channelName VARCHAR(100) NOT NULL,
viewCnt INT NOT NULL
);
CREATE TABLE IF NOT EXISTS follows (
followId INT PRIMARY KEY NOT NULL,
followingId VARCHAR(20) NOT NULL,
followerId VARCHAR(20) NOT NULL,
FOREIGN KEY (followingId) REFERENCES users(userId),
FOREIGN KEY (followerId) REFERENCES users(userId)
);
CREATE TABLE IF NOT EXISTS favorites (
favoriteId INT PRIMARY KEY NOT NULL,
videoId INT NOT NULL,
userId VARCHAR(20) NOT NULL,
FOREIGN KEY (videoId) REFERENCES videos(videoId) ON DELETE CASCADE,
FOREIGN KEY (userId) REFERENCES users(userId) ON DELETE CASCADE
);
📌 3. Model (DTO)
💬 주의 : AUTO_INCREMENT field 라고 하더라도 DTO에서 constructor 생성 시 포함시킨다.
public class User {
private String userId;
private String password;
private String username;
private String email;
// constructor, getter, setter 생략
public class Video {
private int videoId;
private String youtubeId;
private String channelName;
private int viewCnt;
private String fitPartName;
private String title;
// constructor, getter, setter 생략
public class Review {
private int reviewId;
private int videoId;
private String content;
private String userId;
// constructor, getter, setter 생략
public class Favorite {
private int favoriteId;
private int videoId;
private String userId;
// constructor, getter, setter 생략
public class Follow {
private int followId;
private String followingId;
private String followerId;
// constructor, getter, setter 생략
📌 4. Service (DAO)
boolean registUser(User user)
User getUserById(String id)
public class UserDaoImpl implements UserDao {
private static UserDaoImpl instance;
private final DBUtil util = DBUtil.getInstance();
private UserDaoImpl() {}
public static UserDaoImpl getInstance() {
if (instance == null) {
instance = new UserDaoImpl();
}
return instance;
}
@Override
public boolean registUser(User user) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
boolean success = false;
try {
conn = util.getConnection();
// 이미 존재하는 ID인지 확인하는 쿼리
String checkIdSql = "SELECT userId FROM users WHERE userId = ?";
pstmt = conn.prepareStatement(checkIdSql);
pstmt.setString(1, user.getUserId());
rs = pstmt.executeQuery();
// 이미 존재하는 ID라면 가입 실패
if (rs.next()) {
throw new SQLException("이미 사용 중인 아이디입니다.");
}
// 이미 존재하는 사용자명인지 확인하는 쿼리
String checkUsernameSql = "SELECT username FROM users WHERE username = ?";
pstmt = conn.prepareStatement(checkUsernameSql);
pstmt.setString(1, user.getUsername());
rs = pstmt.executeQuery();
// 이미 존재하는 사용자명이라면 가입 실패
if (rs.next()) {
throw new SQLException("이미 사용 중인 사용자명입니다.");
}
// 이미 존재하는 이메일인지 확인하는 쿼리
String checkEmailSql = "SELECT email FROM users WHERE email = ?";
pstmt = conn.prepareStatement(checkEmailSql);
pstmt.setString(1, user.getEmail());
rs = pstmt.executeQuery();
// 이미 존재하는 이메일이라면 가입 실패
if (rs.next()) {
throw new SQLException("이미 사용 중인 이메일 주소입니다.");
}
String sql = "INSERT INTO users (userId, password, username, email) VALUES (?, ?, ?, ?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, user.getUserId());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getUsername());
pstmt.setString(4, user.getEmail());
int rowsAffected = pstmt.executeUpdate();
if (rowsAffected > 0) {
success = true;
}
} catch (SQLException e) {
throw e;
} finally {
DBUtil.close(conn, pstmt, rs);
}
return success;
}
@Override
public User getUserById(String id) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
User user = null;
try {
conn = util.getConnection();
String sql = "SELECT * FROM users WHERE userId = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if (rs.next()) {
user = new User();
user.setUserId(rs.getString("userId"));
user.setPassword(rs.getString("password"));
user.setUsername(rs.getString("username"));
user.setEmail(rs.getString("email"));
}
else {
throw new SQLException("존재하지 않는 아이디입니다.");
}
} catch (SQLException e) {
throw e;
} finally {
DBUtil.close(conn, pstmt, rs);
}
return user;
}
}
List<Review> selectAllReviewsByVideoId(int videoId)
특정 영상에 대한 모든 리뷰 조회
Review selectReviewById(int id)
reviewId를 WHERE절 조건으로 사용해 특정 리뷰 조회
void insertReview(Review review)
새로운 리뷰 작성 시 호출
void updateReview(Review review)
review content 수정 시 호출
void deleteReview(int id)
reviewID를 WHERE 절 조건으로 사용해 특정 리뷰 삭제
public class ReviewDaoImpl implements ReviewDao {
private static ReviewDaoImpl instance;
private final DBUtil util = DBUtil.getInstance();
private ReviewDaoImpl() {
}
public static ReviewDaoImpl getInstance() {
if (instance == null) {
instance = new ReviewDaoImpl();
}
return instance;
}
@Override
public List<Review> selectAllReviewsByVideoId(int videoId) {
List<Review> reviews = new ArrayList<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM reviews WHERE videoId = ?")) {
pstmt.setInt(1, videoId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Review review = new Review();
review.setReviewId(rs.getInt("reviewId"));
review.setVideoId(rs.getInt("videoId"));
review.setContent(rs.getString("content"));
review.setUserId(rs.getString("userId"));
reviews.add(review);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return reviews;
}
@Override
public Review selectReviewById(int id) {
Review review = null;
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM reviews WHERE reviewId = ?")) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
review = new Review();
review.setReviewId(rs.getInt("reviewId"));
review.setVideoId(rs.getInt("videoId"));
review.setContent(rs.getString("content"));
review.setUserId(rs.getString("userId"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return review;
}
@Override
public void insertReview(Review review) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO reviews (reviewId, videoId, content, userId) VALUES (?, ?, ?, ?)")) {
pstmt.setInt(1, review.getReviewId());
pstmt.setInt(2, review.getVideoId());
pstmt.setString(3, review.getContent());
pstmt.setString(4, review.getUserId());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void updateReview(Review review) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("UPDATE reviews SET content = ? WHERE reviewId = ?")) {
pstmt.setString(1, review.getContent());
pstmt.setInt(2, review.getReviewId());
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void deleteReview(int id) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("DELETE FROM reviews WHERE reviewId = ?")) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
void addVideoList(List<Video> videoList)
새로운 video 삽입 시 호출 ( 사용자가 하는 게 아니고 서버 내에서)
List<Video> selectInterestViewFitVideo()
조회수가 높은 순으로 영상 조회 시 호출
List<Video> selectPartFitVideo(String part) 부위 별 운동 영상 조회시 호출
WHERE 절 조건으로 fitPartName 사용
List<Video> getAllVideos()
모든 영상 조회
public class MainDaoImpl implements MainDao {
private static final DBUtil util = DBUtil.getInstance();
private static MainDaoImpl instance;
private static List<Video> list;
private static UserDao userDao = UserDaoImpl.getInstance();
private MainDaoImpl() {
System.out.println("created.");
list = new ArrayList<Video>();
list.add(new Video(1, "gMaB-fG4u4g", "ThankyouBUBU", 10, "전신", "전신 다이어트 최고의 운동 [칼소폭 찐 핵핵매운맛]"));
list.add(new Video(2, "swRNeYw1JkY", "ThankyouBUBU", 12, "전신", "하루 15분! 전신 칼로리 불태우는 다이어트 운동"));
list.add(new Video(3, "54tTYO-vU2E", "ThankyouBUBU", 20, "상체", "상체 다이어트 최고의 운동 BEST [팔뚝살/겨드랑이살/등살/가슴어깨라인]"));
list.add(new Video(4, "QqqZH3j_vH0", "ThankyouBUBU", 2, "상체", "상체비만 다이어트 최고의 운동 [상체 핵매운맛]"));
list.add(new Video(5, "tzN6ypk6Sps", "김강민", 17, "하체", "하체운동이 중요한 이유? 이것만 보고 따라하자 ! [하체운동 교과서]"));
list.add(new Video(6, "u5OgcZdNbMo", "GYM종국", 120, "하체", "저는 하체 식주의자 입니다"));
list.add(new Video(7, "PjGcOP-TQPE", "ThankyouBUBU", 1, "복부", "11자복근 복부 최고의 운동 [복근 핵매운맛]"));
list.add(new Video(8, "7TLk7pscICk", "SomiFit", 0, "복부", "(Sub)누워서하는 5분 복부운동!! 효과보장! (매일 2주만 해보세요!)"));
addVideoList(list);
}
public static MainDao getInstance() {
if (instance == null)
instance = new MainDaoImpl();
return instance;
}
public void addVideoList(List<Video> videoList) {
System.out.println("add video list");
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO videos (videoId, youtubeId, channelName, viewCnt, fitPartName, title) VALUES (?, ?, ?, ?, ?, ?)")) {
for (Video video : videoList) {
pstmt.setInt(1, video.getVideoId());
pstmt.setString(2, video.getYoutubeId());
pstmt.setString(3, video.getChannelName());
pstmt.setInt(4, video.getViewCnt());
pstmt.setString(5, video.getFitPartName());
pstmt.setString(6, video.getTitle());
pstmt.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public List<Video> selectInterestViewFitVideo() {
List<Video> videoList = new ArrayList<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM videos ORDER BY viewCnt DESC")) {
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Video video = new Video();
video.setVideoId(rs.getInt("videoId"));
video.setYoutubeId(rs.getString("youtubeId"));
video.setChannelName(rs.getString("channelName"));
video.setViewCnt(rs.getInt("viewCnt"));
video.setFitPartName(rs.getString("fitPartName"));
video.setTitle(rs.getString("title"));
videoList.add(video);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return videoList;
}
@Override
public List<Video> selectPartFitVideo(String part) {
List<Video> videoList = new ArrayList<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM videos WHERE fitPartName = ?")) {
pstmt.setString(1, part);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Video video = new Video();
video.setVideoId(rs.getInt("videoId"));
video.setYoutubeId(rs.getString("youtubeId"));
video.setChannelName(rs.getString("channelName"));
video.setViewCnt(rs.getInt("viewCnt"));
video.setFitPartName(rs.getString("fitPartName"));
video.setTitle(rs.getString("title"));
videoList.add(video);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return videoList;
}
@Override
public List<Video> getAllVideos() {
List<Video> videoList = new ArrayList<>();
try (Connection conn = util.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM videos")) {
while (rs.next()) {
Video video = new Video();
video.setVideoId(rs.getInt("videoId"));
video.setYoutubeId(rs.getString("youtubeId"));
video.setChannelName(rs.getString("channelName"));
video.setViewCnt(rs.getInt("viewCnt"));
video.setFitPartName(rs.getString("fitPartName"));
video.setTitle(rs.getString("title"));
videoList.add(video);
}
} catch (SQLException e) {
e.printStackTrace();
}
return videoList;
}
void follow(String followingId, String followerId)
void void unfollow(String followingId, String followerId)
boolean isFollowing(String followingId, String followerId)
List<User> getFollowers(String userId)
List<User> getFollowings(String userId)
public class FollowDaoImpl implements FollowDao {
private static FollowDaoImpl instance;
private UserDao userDao = UserDaoImpl.getInstance();
private final DBUtil util = DBUtil.getInstance();
private FollowDaoImpl() {}
public static FollowDaoImpl getInstance() {
if (instance == null) {
instance = new FollowDaoImpl();
}
return instance;
}
@Override
public void follow(String followingId, String followerId) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO follows (followingId, followerId) VALUES (?, ?)")) {
pstmt.setString(1, followingId);
pstmt.setString(2, followerId);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void unfollow(String followingId, String followerId) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"DELETE FROM follows WHERE followingId = ? AND followerId = ?")) {
pstmt.setString(1, followingId);
pstmt.setString(2, followerId);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public boolean isFollowing(String followingId, String followerId) {
boolean followingFlag = false;
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM follows WHERE followingId = ? AND followerId = ?")) {
pstmt.setString(1, followingId);
pstmt.setString(2, followerId);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
followingFlag = true; // 팔로우 중인 경우 true로 설정
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return followingFlag;
}
@Override
public List<User> getFollowers(String userId) { // 해당 id'를' '팔로우하는' 사람 목록
List<User> followers = new ArrayList<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM users WHERE userId IN (SELECT followingId FROM follows WHERE followerId = ?)")) {
pstmt.setString(1, userId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
User follower = new User();
follower.setUserId(rs.getString("userId"));
follower.setPassword(rs.getString("password"));
follower.setUsername(rs.getString("username"));
follower.setEmail(rs.getString("email"));
followers.add(follower);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return followers;
}
@Override
public List<User> getFollowings(String userId) { // 해당 id'가' '팔로우하는' 사람 목록
List<User> followings = new ArrayList<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement(
"SELECT * FROM users WHERE userId IN (SELECT followerId FROM follows WHERE followingId = ?)")) {
pstmt.setString(1, userId);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
User following = new User();
following.setUserId(rs.getString("userId"));
following.setPassword(rs.getString("password"));
following.setUsername(rs.getString("username"));
following.setEmail(rs.getString("email"));
followings.add(following);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return followings;
}
void favorite(String userId, int videoId)
void unfavorite(String userId, int videoId)
public class FavoriteDaoImpl implements FavoriteDao {
private static FavoriteDaoImpl instance;
private final DBUtil util = DBUtil.getInstance();
private FavoriteDaoImpl() {
}
public static FavoriteDaoImpl getInstance() {
if (instance == null) {
System.out.println("favoriteDao created.");
instance = new FavoriteDaoImpl();
}
return instance;
}
@Override
public void favorite(String userId, int videoId) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn
.prepareStatement("INSERT INTO favorites (videoId, userId) VALUES (?,?)")) {
pstmt.setInt(1, videoId);
pstmt.setString(2, userId);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void unfavorite(String userId, int videoId) {
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn
.prepareStatement("DELETE FROM favorites WHERE userId= ? AND videoId=?")) {
pstmt.setString(1, userId);
pstmt.setInt(2, videoId);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public boolean isFavorite(String userId, int videoId) {
boolean favoriteFlag = false;
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn
.prepareStatement("SELECT * FROM favorites WHERE userId=? AND videoId=?")) {
pstmt.setString(1, userId);
pstmt.setInt(2, videoId);
try(ResultSet rs = pstmt.executeQuery()) {
if(rs.next()) favoriteFlag = true;
}
} catch (SQLException e) {
e.printStackTrace();
}
return favoriteFlag;
}
public Map<Integer, Boolean> getFavoritesStatus(String userId, List<Video> videos) {
Map<Integer, Boolean> favoriteStatusMap = new HashMap<>();
try (Connection conn = util.getConnection();
PreparedStatement pstmt = conn.prepareStatement("SELECT videoId FROM favorites WHERE userId=? AND videoId=?")) {
for (Video video : videos) {
pstmt.setString(1, userId);
pstmt.setInt(2, video.getVideoId());
try (ResultSet rs = pstmt.executeQuery()) {
favoriteStatusMap.put(video.getVideoId(), rs.next()); // 찜 여부를 Map에 저장
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return favoriteStatusMap;
}
}
📌 5. Controller
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
switch (action) {
case "home": // 홈으로
showHome(request, response);
break;
case "list": // 영상 목록
doList(request, response);
break;
case "reviewList": // 각 영상 당 리뷰 목록
doReviewList(request, response);
break;
case "addReviewForm": // 리뷰 작성 요청
showAddReviewForm(request, response);
break;
case "addReview": // 리뷰 추가 요청
addReview(request, response);
break;
case "updateReviewForm": // 리뷰 수정 작성 요청
showUpdateReviewForm(request, response);
break;
case "updateReview": // 리뷰 수정 반영 요청
updateReview(request, response);
break;
case "deleteReview": // 리뷰 삭제 요청
deleteReview(request, response);
break;
case "registForm": // 회원가입 폼 요청 시
showRegistForm(request, response);
break;
case "regist": // 회원가입 요청 시
doRegist(request, response);
break;
case "loginForm": // 로그인 폼 요청 시
showLoginForm(request, response);
break;
case "login": // 로그인 요청 시
doLogin(request, response);
break;
case "logout": // 로그아웃 요청 시
doLogout(request, response);
break;
case "mypage":
showMyPage(request, response);
break;
case "follow":
followUser(request, response);
break;
case "unfollow":
unfollowUser(request, response);
break;
// 이하 구현 코드 생략
📌 6. DB 설정
추후 myBatis 로 대체 예정
package com.ssafy.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Mysql DB 연결 객체를 제공해주고, 사용했던 자원을 해제하는 기능을 제공하는 클래스입니다.
*
*/
public class DBUtil {
// DB와 연결하기위해 필요한 DB의 URL
private final String url = "jdbc:mysql://127.0.0.1:3306/mydb?serverTimezone=UTC";
// DB의 USER 이름
private final String username = "사용자ID";
// 위 USER의 PASSWORD
private final String password = "사용자PW";
// Mysql 드라이버 클래스 이름
private final String drivername = "com.mysql.cj.jdbc.Driver";
private static DBUtil instance = new DBUtil();
private DBUtil() {
System.out.println("db util created");
try {
Class.forName(drivername);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static DBUtil getInstance() {
return instance;
}
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
// 자원 해제
public static void close(Connection conn, PreparedStatement pstmt) {
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (pstmt != null)
pstmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Q. DBListener를 이 프로젝트에서 왜 사용했나요?
A.
package com.ssafy.listener;
import com.ssafy.dao.FavoriteDao;
import com.ssafy.dao.FavoriteDaoImpl;
import com.ssafy.dao.FollowDao;
import com.ssafy.dao.FollowDaoImpl;
import com.ssafy.dao.MainDao;
import com.ssafy.dao.MainDaoImpl;
import com.ssafy.dao.ReviewDao;
import com.ssafy.dao.ReviewDaoImpl;
import com.ssafy.dao.UserDao;
import com.ssafy.dao.UserDaoImpl;
import com.ssafy.util.DBUtil;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
@WebListener
public class DBListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// DAO 인스턴스 생성
MainDao mainDao = MainDaoImpl.getInstance();
ReviewDao reviewDao = ReviewDaoImpl.getInstance();
UserDao userDao = UserDaoImpl.getInstance();
FollowDao followDao = FollowDaoImpl.getInstance();
FavoriteDao favoriteDao = FavoriteDaoImpl.getInstance();
// 서블릿 컨텍스트에 DAO 인스턴스 저장
sce.getServletContext().setAttribute("mainDao", mainDao);
sce.getServletContext().setAttribute("reviewDao", reviewDao);
sce.getServletContext().setAttribute("userDao", userDao);
sce.getServletContext().setAttribute("followDao", followDao);
sce.getServletContext().setAttribute("favoriteDao", favoriteDao);
}
}
📌 7. View (jsp)
<ul>
<%
List<User> followings = (List<User>) request.getAttribute("followings");
if (followings != null && !followings.isEmpty()) {
for (User following : followings) {
%>
<li>팔로잉 ID: <%=following.getUserId()%> / NAME: <%=following.getUsername()%></li>
<%
}
} else {
%>
<li>팔로우한 사람이 없습니다.</li>
<%
}
%>
</ul>
<%
if (loginUser != null && !loginUser.getUserId().equals(user.getUserId())) {
if ((Boolean) request.getAttribute("isFollowing")) {
%>
<form action="main" method="post">
<input type="hidden" name="action" value="unfollow"> <input
type="hidden" name="userIdToUnfollow" value="<%=user.getUserId()%>">
<button class="button" type="submit">팔로우 취소</button>
</form>
<%
} else {
%>
<form action="main" method="post">
<input type="hidden" name="action" value="follow"> <input
type="hidden" name="userIdToFollow" value="<%=user.getUserId()%>">
<button class="button" type="submit">팔로우</button>
</form>
<%
}
}
%>

<c:forEach items="${reviews}" var="review">
<tr>
<td>${review.reviewId}</td>
<td>${review.content}</td>
<td>
<!-- 작성자 정보로 이동하는 링크 -->
<c:choose>
<c:when test="${sessionScope.user.userId eq review.userId}">
<a href="main?action=mypage&userId=${review.userId}" class="btn">내 정보</a>
</c:when>
<c:otherwise>
<a href="main?action=mypage&userId=${review.userId}" class="btn">작성자 정보</a>
</c:otherwise>
</c:choose>
</td>
<td>
<!-- 작성자와 현재 로그인한 사용자가 같은 경우에만 수정 버튼을 표시 -->
<c:if test="${sessionScope.user.userId eq review.userId}">
<a href="main?action=updateReviewForm&reviewId=${review.reviewId}" class="btn">수정</a>
</c:if>
</td>
<td>
<!-- 작성자와 현재 로그인한 사용자가 같은 경우에만 삭제 버튼을 표시 -->
<c:if test="${sessionScope.user.userId eq review.userId}">
<a href="main?action=deleteReview&reviewId=${review.reviewId}" class="btn">삭제</a>
</c:if>
</td>
</tr>
</c:forEach>
📌 8. 개선 방향