[Java/servlet POJ] 친구 추천 / 영상 추천 기능 구현

이혜윤·2024년 4월 15일

JAVA

목록 보기
8/9

수정/추가 사항

📌 1. Favorite Service

boolean isFavorite(String userId, int videoId)

  • 해당 user가 특정 video를 찜하고 있는지 여부를 반환
  • favorites 테이블에서 select

Map<Integer, Boolean> getFavoritesStatus(String userId, List<Video> videos)

  • 특정 user가 찜한 모든 비디오를 반환
  • favorites 테이블 내에서 select
@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;
    }

📌 2. Follow Service

List<User> recommendUsers(String userId)

1) 특정 user (userId에 해당하는 user)가 팔로우하는 모든 user를 추출
2) 추출된 user들이 팔로우하는 다른 user들 중, 특정 user가 아직 follow하지 않은 user만 List에 넣어서 반환
3) 친구 추천 기능에서 활용
4) BFS 사용

@Override
	public List<User> recommendUsers(String userId) {
		
		Map<String, Set<String>> usersGraph = new HashMap<>();
	    List<User> recommendedUsers = new ArrayList<>();

	    try (Connection conn = util.getConnection();
	         PreparedStatement pstmt = conn.prepareStatement("SELECT followingId, followerId FROM follows");
	         ResultSet rs = pstmt.executeQuery()) {

	        while (rs.next()) {
	            String followingId = rs.getString("followingId");
	            String followerId = rs.getString("followerId");

	            // 각 followingId에 대해 followerId를 추가
	            usersGraph.computeIfAbsent(followingId, k -> new HashSet<>()).add(followerId);
	        }
	    } catch (SQLException e) {
	        e.printStackTrace();
	    }
	    
	    // BFS를 위한 큐와 방문한 사용자를 추적하기 위한 세트
	    Queue<String> queue = new LinkedList<>();
	    Set<String> visited = new HashSet<>();

	    // 시작 사용자를 큐와 방문한 세트에 추가
	    queue.offer(userId);
	    visited.add(userId);

	    // 첫 번째 레벨(직접적인 친구)을 건너뛰고 두 번째 레벨(친구의 친구)을 찾기 위한 변수
	    int currentLevel = 0;
	    
	    while (!queue.isEmpty()) {
	        int levelSize = queue.size();
	        
	        // 현재 레벨의 모든 노드(사용자)에 대해 처리
	        for (int i = 0; i < levelSize; i++) {
	            String currentUserId = queue.poll();
	            
	            // 현재 사용자와 연결된 모든 사용자(팔로우하는 사용자)에 대해 반복
	            for (String nextUserId : usersGraph.getOrDefault(currentUserId, Collections.emptySet())) {
	                if (!visited.contains(nextUserId)) {
	                    visited.add(nextUserId);
	                    queue.offer(nextUserId);
	                    
	                    // 첫 번째 레벨을 건너뛰고 두 번째 레벨에서 사용자를 추천 리스트에 추가
	                    if (currentLevel == 1) {
	                    	try {
	                            // UserDao의 getUserById 메서드를 호출하여 사용자 정보를 조회합니다.
	                            User user = userDao.getUserById(nextUserId);
	                            if (user != null) {
	                                recommendedUsers.add(user);
	                            }
	                        } catch (SQLException e) {
	                            e.printStackTrace();
	                        }
	                    }
	                }
	            }
	        }
	        
	        currentLevel++;
	        if (currentLevel == 2) break; // 두 번째 레벨의 사용자를 모두 찾은 후 루프 종료
	    }
	    
	    return recommendedUsers;
	}    

📌 3. View

💡 mypage 中 친구 추천 view

		<h2>이런 친구는 어떠신가요?</h2>
		<table>
			<tr>
				<th>ID</th>
				<th>Name</th>
				<th></th>
			</tr>
			<%
			List<User> recommendedUsers = (List<User>) request.getAttribute("recommendedUsers");
			if (recommendedUsers != null && !recommendedUsers.isEmpty()) {
				for (User recommendedUser : recommendedUsers) {
			%>
			<tr>
				<td><%=recommendedUser.getUserId()%></td>
				<td><%=recommendedUser.getUsername()%></td>
				<td><a
					href="main?action=mypage&userId=<%=recommendedUser.getUserId()%>">
						<button class="button">보러가기</button>
				</a></td>
			</tr>
			<%
			}
			} else {
			%>
			<tr>
				<td colspan="3">추천할 사용자가 없습니다.</td>
			</tr>
			<%
			}
			%>
		</table>

💡 mypage 中 영상 추천 view

<h2>이런 영상은 어떠신가요?</h2>
		<div class="video-container">
			<%
			List<Video> recommendVideos = (List<Video>) request.getAttribute("recommendVideos");
			if (recommendVideos != null && !recommendVideos.isEmpty()) {
				for (Video recommendVideo : recommendVideos) {
			%>
			<div class="video-list">
				<div class="video">
					<iframe
						src="https://www.youtube.com/embed/<%=recommendVideo.getYoutubeId()%>?enablejsapi=1"
						frameborder="0" allowfullscreen></iframe>
				</div>
				<div class="video-info">
					<div class="title"><%=recommendVideo.getTitle()%></div>
				</div>
			</div>
			<%
			}
			} else {
			%>
			<li>추천할 사용자가 없습니다.</li>
			<%
			}
			%>
		</div>

profile
구르미 누나

0개의 댓글