Files
sb-backend/src/main/resources/mapper/PostMapper.xml
T
ByungCheolandClaude Opus 4.8 b969ba6104 feat: 내 글/댓글 모아보기 API
- GET /board/my/posts, /board/my/comments (페이징)
- PostSummary 에 category 추가, MyCommentResponse(글 제목·카테고리 포함)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 18:25:48 +09:00

131 lines
5.9 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sb.web.board.mapper.PostMapper">
<sql id="filter">
<if test="tag != null and tag != ''">
JOIN post_tag pt ON pt.post_id = p.id
JOIN tag t ON t.id = pt.tag_id
</if>
<where>
<if test="category != null and category != ''">
AND p.category = #{category}
</if>
<if test="tag != null and tag != ''">
AND t.name = #{tag}
</if>
<if test="keyword != null and keyword != ''">
<choose>
<when test="searchType == 'content'">
AND p.content LIKE CONCAT('%', #{keyword}, '%')
</when>
<when test="searchType == 'comment'">
AND EXISTS (SELECT 1 FROM comment c
WHERE c.post_id = p.id
AND c.content LIKE CONCAT('%', #{keyword}, '%'))
</when>
<otherwise>
AND p.title LIKE CONCAT('%', #{keyword}, '%')
</otherwise>
</choose>
</if>
</where>
</sql>
<select id="findPage" resultType="com.sb.web.board.dto.PostSummary">
SELECT
p.id, p.title, p.author_id, p.author_name, p.view_count, p.blocked, p.notice, p.created_at,
m.google_picture AS author_google_picture, m.profile_image AS author_profile_image,
(SELECT COUNT(*) FROM comment c WHERE c.post_id = p.id) AS comment_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'UP') AS up_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'DOWN') AS down_count
FROM post p
LEFT JOIN member m ON m.id = p.author_id
<include refid="filter"/>
ORDER BY p.notice DESC, p.id DESC
LIMIT #{size} OFFSET #{offset}
</select>
<!-- 인기 글: 등록 #{hours}시간 이내 + 추천 #{minUp}건 이상, 추천 많은 순 #{limit}건 (상단 노출용) -->
<select id="findHotPosts" resultType="com.sb.web.board.dto.PostSummary">
SELECT
p.id, p.title, p.author_id, p.author_name, p.view_count, p.blocked, p.notice, p.created_at,
m.google_picture AS author_google_picture, m.profile_image AS author_profile_image,
(SELECT COUNT(*) FROM comment c WHERE c.post_id = p.id) AS comment_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'UP') AS up_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'DOWN') AS down_count
FROM post p
LEFT JOIN member m ON m.id = p.author_id
WHERE p.notice = 0
AND (#{category} IS NULL OR p.category = #{category})
AND p.created_at >= NOW() - INTERVAL #{hours} HOUR
AND (SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'UP') >= #{minUp}
ORDER BY (SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'UP') DESC, p.id DESC
LIMIT #{limit}
</select>
<select id="countPage" resultType="long">
SELECT COUNT(*)
FROM post p
<include refid="filter"/>
</select>
<!-- 내 글 모아보기 -->
<select id="findMyPage" resultType="com.sb.web.board.dto.PostSummary">
SELECT
p.id, p.title, p.category, p.author_id, p.author_name, p.view_count, p.blocked, p.notice, p.created_at,
m.google_picture AS author_google_picture, m.profile_image AS author_profile_image,
(SELECT COUNT(*) FROM comment c WHERE c.post_id = p.id) AS comment_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'UP') AS up_count,
(SELECT COUNT(*) FROM post_vote v WHERE v.post_id = p.id AND v.vote_type = 'DOWN') AS down_count
FROM post p
LEFT JOIN member m ON m.id = p.author_id
WHERE p.author_id = #{memberId}
ORDER BY p.id DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countMyPosts" parameterType="long" resultType="long">
SELECT COUNT(*) FROM post WHERE author_id = #{memberId}
</select>
<select id="findById" parameterType="long" resultType="com.sb.web.board.domain.Post">
SELECT p.id, p.title, p.content, p.author_id, p.author_name, p.view_count,
p.blocked, p.block_reason, p.notice, p.category, p.created_at, p.updated_at,
m.google_picture AS author_google_picture, m.profile_image AS author_profile_image
FROM post p
LEFT JOIN member m ON m.id = p.author_id
WHERE p.id = #{id}
</select>
<insert id="insert" parameterType="com.sb.web.board.domain.Post"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO post (title, content, author_id, author_name, view_count, notice, category, created_at, updated_at)
VALUES (#{title}, #{content}, #{authorId}, #{authorName}, 0, #{notice}, #{category}, NOW(), NOW())
</insert>
<update id="update" parameterType="com.sb.web.board.domain.Post">
UPDATE post
SET title = #{title}, content = #{content}
WHERE id = #{id}
</update>
<delete id="delete" parameterType="long">
DELETE FROM post WHERE id = #{id}
</delete>
<update id="increaseViewCount" parameterType="long">
UPDATE post SET view_count = view_count + 1 WHERE id = #{id}
</update>
<update id="updateBlocked">
UPDATE post SET blocked = #{blocked}, block_reason = #{blockReason} WHERE id = #{id}
</update>
<update id="updateNotice">
UPDATE post SET notice = #{notice} WHERE id = #{id}
</update>
</mapper>