Migrate to MyBatis with proper Controller→Service→Mapper layering
- Add MyBatis Spring Boot Starter with XML mappers and domain classes - Create 9 mapper interfaces + XML: Restaurant, Video, Channel, Review, User, Stats, DaemonConfig, Search, Vector - Create 10 domain classes with Lombok: Restaurant, VideoSummary, VideoDetail, VideoRestaurantLink, Channel, Review, UserInfo, DaemonConfig, SiteVisitStats, VectorSearchResult - Create 7 new service classes: RestaurantService, VideoService, ChannelService, ReviewService, UserService, StatsService, DaemonConfigService - Refactor all controllers to be thin (HTTP + auth only), delegating business logic to services - Refactor SearchService, PipelineService, DaemonScheduler, AuthService, YouTubeService to use mappers/services instead of JDBC/repositories - Add Jackson SNAKE_CASE property naming for consistent API responses - Add ClobTypeHandler for Oracle CLOB→String in MyBatis - Add IdGenerator utility for centralized UUID generation - Delete old repository/ package (6 files), JdbcConfig, LowerCaseKeyAdvice - VectorService retains JDBC for Oracle VECTOR type support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.tasteby.mapper.UserMapper">
|
||||
|
||||
<resultMap id="userResultMap" type="com.tasteby.domain.UserInfo">
|
||||
<id property="id" column="id"/>
|
||||
<result property="email" column="email"/>
|
||||
<result property="nickname" column="nickname"/>
|
||||
<result property="avatarUrl" column="avatar_url"/>
|
||||
<result property="isAdmin" column="is_admin" javaType="boolean"/>
|
||||
<result property="provider" column="provider"/>
|
||||
<result property="createdAt" column="created_at"/>
|
||||
<result property="favoriteCount" column="favorite_count"/>
|
||||
<result property="reviewCount" column="review_count"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="findByProviderAndProviderId" resultMap="userResultMap">
|
||||
SELECT id, email, nickname, avatar_url, is_admin, provider, created_at
|
||||
FROM tasteby_users
|
||||
WHERE provider = #{provider} AND provider_id = #{providerId}
|
||||
</select>
|
||||
|
||||
<update id="updateLastLogin">
|
||||
UPDATE tasteby_users SET last_login_at = SYSTIMESTAMP WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<insert id="insert">
|
||||
INSERT INTO tasteby_users (id, provider, provider_id, email, nickname, avatar_url)
|
||||
VALUES (#{id}, #{provider}, #{providerId}, #{email}, #{nickname}, #{avatarUrl})
|
||||
</insert>
|
||||
|
||||
<select id="findById" resultMap="userResultMap">
|
||||
SELECT id, email, nickname, avatar_url, is_admin, provider, created_at
|
||||
FROM tasteby_users
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findAllWithCounts" resultMap="userResultMap">
|
||||
SELECT u.id, u.email, u.nickname, u.avatar_url, u.provider, u.created_at,
|
||||
NVL(fav.cnt, 0) AS favorite_count,
|
||||
NVL(rev.cnt, 0) AS review_count
|
||||
FROM tasteby_users u
|
||||
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM user_favorites GROUP BY user_id) fav ON fav.user_id = u.id
|
||||
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM user_reviews GROUP BY user_id) rev ON rev.user_id = u.id
|
||||
ORDER BY u.created_at DESC
|
||||
OFFSET #{offset} ROWS FETCH NEXT #{limit} ROWS ONLY
|
||||
</select>
|
||||
|
||||
<select id="countAll" resultType="int">
|
||||
SELECT COUNT(*) FROM tasteby_users
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user