Compare commits

..

No commits in common. "a55081530830af51d34342d527717ba0202c66af" and "e3656d20ec508985efca82e6ac5d5922d000da0b" have entirely different histories.

41 changed files with 1 additions and 1917 deletions

View File

@ -39,7 +39,6 @@ dependencies {
implementation 'org.hibernate.validator:hibernate-validator:6.0.13.Final'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'com.vladsch.flexmark:flexmark-all:0.64.8'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

View File

@ -1,9 +0,0 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.Message;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface MessageMapper {
int insert(Message message);
}

View File

@ -1,14 +0,0 @@
package com.example.copykamanotes.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface NoteLikeMapper {
List<Integer> findUserLikedNoteIds(
@Param("userId") Long userId,
@Param("noteIds") List<Integer> noteIds
);
}

View File

@ -1,14 +0,0 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.dto.note.NoteQueryParams;
import com.example.copykamanotes.model.entity.Note;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface NoteMapper {
int countNotes(NoteQueryParams noteQueryParams);
List<Note> findByQueryParam(NoteQueryParams noteQueryParams, int pageSize, int offset);
}

View File

@ -1,11 +0,0 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.Question;
import org.apache.ibatis.annotations.Mapper;
import java.util.Map;
@Mapper
public interface QuestionMapper {
Map<Integer, Question> getQuestionMapByIds(Integer[] questionIds);
}

View File

@ -1,40 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
/**
* @ClassName Category
* @Description 分类实体类
* @Author Tong
* @LastChangeDate 2024-12-16 19:53
* @Version v1.0
*/
@Data
public class Category {
/*
* 分类ID主键
*/
private Integer categoryId;
/*
* 分类名称
*/
private String name;
/*
* 上级分类ID
* 为0时表示当前分类是一级分类
*/
private Integer parentCategoryId;
/*
* 创建时间
*/
private Date createdAt;
/*
* 更新时间
*/
private Date updatedAt;
}

View File

@ -1,40 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
/**
* 收藏夹实体类
*/
@Data
public class Collection {
/*
* 收藏夹ID主键
*/
private Integer collectionId;
/*
* 收藏夹名称
*/
private String name;
/*
* 收藏夹描述
*/
private String description;
/*
* 收藏夹创建者ID
*/
private Long creatorId;
/*
* 创建时间
*/
private Date createdAt;
/*
* 更新时间
*/
private Date updatedAt;
}

View File

@ -1,35 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
/**
* @ClassName CollectionNote
* @Description 收藏夹-笔记关联实体类
* @Author Tong
* @LastChangeDate 2024-12-16 20:11
* @Version v1.0
*/
@Data
public class CollectionNote {
/*
* 收藏夹ID联合主键
*/
private Integer collectionId;
/*
* 笔记ID联合主键
*/
private Integer noteId;
/*
* 创建时间
*/
private Date createdAt;
/*
* 更新时间
*/
private Date updatedAt;
}

View File

@ -1,56 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 评论实体类
*/
@Data
public class Comment {
/**
* 评论ID
*/
private Integer commentId;
/**
* 笔记ID
*/
private Integer noteId;
/**
* 作者ID
*/
private Long authorId;
/**
* 父评论ID
*/
private Integer parentId;
/**
* 评论内容
*/
private String content;
/**
* 点赞数
*/
private Integer likeCount;
/**
* 回复数
*/
private Integer replyCount;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}

View File

@ -1,31 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 评论点赞实体类
*/
@Data
public class CommentLike {
/**
* 评论点赞ID
*/
private Integer commentLikeId;
/**
* 评论ID
*/
private Integer commentId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建时间
*/
private LocalDateTime createdAt;
}

View File

@ -1,55 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 消息实体类
*/
@Data
public class Message {
/**
* 消息ID
*/
private Integer messageId;
/**
* 接收者ID
*/
private Long receiverId;
/**
* 发送者ID
*/
private Long senderId;
/**
* 消息类型
*/
private String type;
/**
* 目标ID
*/
private Integer targetId;
/**
* 消息内容
*/
private String content;
/**
* 是否已读
*/
private Boolean isRead;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
}

View File

@ -1,30 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 笔记收藏实体类
*/
@Data
public class NoteCollect {
/**
* 收藏ID
*/
private Integer collectId;
/**
* 笔记ID
*/
private Integer noteId;
/**
* 用户ID
*/
private Long userId;
/**
* 创建时间
*/
private LocalDateTime createdAt;
}

View File

@ -1,16 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
@Data
public class NoteComment {
private Integer id;
private Integer noteId;
private Long userId;
private String content;
private Date createdAt;
private Date updatedAt;
private Boolean isDeleted;
}

View File

@ -1,34 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
/**
* @ClassName NoteLike
* @Description 笔记点赞关联实体类
* @Author Tong
* @LastChangeDate 2024-12-16 20:04
* @Version v1.0
*/
@Data
public class NoteLike {
/*
* 笔记ID联合主键
*/
private Integer noteId;
/*
* 点赞用户ID联合主键
*/
private Long userId;
/*
* 创建时间
*/
private Date createdAt;
/*
* 更新时间
*/
private Date updatedAt;
}

View File

@ -1,57 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @ClassName Question
* @Description 问题实体类
* @Author Tong
* @LastChangeDate 2024-12-16 19:56
* @Version v1.0
*/
@Data
public class Question {
/*
* 问题ID主键
*/
private Integer questionId;
/*
* 问题所属分类ID
*/
private Integer categoryId;
/*
* 问题标题
*/
private String title;
/*
* 问题难度
* 1=简单2=中等3=困难
*/
private Integer difficulty;
/*
* 题目考点
*/
private String examPoint;
/*
* 浏览量
*/
private Integer viewCount;
/*
* 创建时间
*/
private LocalDateTime createdAt;
/*
* 更新时间
*/
private LocalDateTime updatedAt;
}

View File

@ -1,4 +0,0 @@
package com.example.copykamanotes.model.entity;
public class QuestionList {
}

View File

@ -1,40 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.util.Date;
/**
* @ClassName QuestionListItem
* @Description 题单-题目关联实体类
* @Author Tong
* @LastChangeDate 2024-12-16 20:15
* @Version v1.0
*/
@Data
public class QuestionListItem {
/*
* 题单ID联合主键
*/
private Integer questionListId;
/*
* 题目ID联合主键
*/
private Integer questionId;
/*
* 题单内题目的顺序从1开始
*/
private Integer rank;
/*
* 创建时间
*/
private Date createdAt;
/*
* 更新时间
*/
private Date updatedAt;
}

View File

@ -1,52 +0,0 @@
package com.example.copykamanotes.model.entity;
import lombok.Data;
import java.time.LocalDate;
/**
* 统计信息实体包含登录注册笔记等统计数据
*/
@Data
public class Statistic {
/**
* 主键 ID
*/
private Integer id;
/**
* 当天登录次数
*/
private Integer loginCount;
/**
* 当天注册人数
*/
private Integer registerCount;
/**
* 累计注册总人数
*/
private Integer totalRegisterCount;
/**
* 当天笔记数量
*/
private Integer noteCount;
/**
* 当天提交的笔记数量
*/
private Integer submitNoteCount;
/**
* 累计笔记总数量
*/
private Integer totalNoteCount;
/**
* 统计日期
*/
private LocalDate date;
}

View File

@ -4,7 +4,6 @@ import lombok.Data;
import java.time.LocalDateTime;
@Data
public class NoteVO {
private Integer noteId;

View File

@ -1,8 +1,4 @@
package com.example.copykamanotes.service;
import java.util.List;
import java.util.Set;
public interface NoteLikeService {
Set<Integer> findUserLikedNoteIds(Long userId, List<Integer> noteIds);
}

View File

@ -1,18 +1,15 @@
package com.example.copykamanotes.service;
import com.example.copykamanotes.mapper.NoteMapper;
import com.example.copykamanotes.model.base.ApiResponse;
import com.example.copykamanotes.model.base.EmptyVO;
import com.example.copykamanotes.model.dto.note.*;
import com.example.copykamanotes.model.vo.note.CreateNoteVO;
import com.example.copykamanotes.model.vo.note.DownloadNoteVO;
import com.example.copykamanotes.model.vo.note.NoteVO;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public interface NoteService {
ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams);
ApiResponse<CreateNoteVO> createNote(CreateNoteRequest createNoteRequest);

View File

@ -1,10 +1,4 @@
package com.example.copykamanotes.service;
import com.example.copykamanotes.model.entity.Question;
import java.util.List;
import java.util.Map;
public interface QuestionService {
Map<Integer, Question> getQuestionMapByIds(List<Integer> questionIds);
}

View File

@ -1,23 +0,0 @@
package com.example.copykamanotes.service.impl;
import com.example.copykamanotes.mapper.NoteLikeMapper;
import com.example.copykamanotes.service.NoteLikeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
@RequiredArgsConstructor
public class NoteLikeServiceImpl implements NoteLikeService {
private final NoteLikeMapper noteLikeMapper;
@Override
public Set<Integer> findUserLikedNoteIds(Long userId, List<Integer> noteIds) {
List<Integer> likedIds = noteLikeMapper.findUserLikedNoteIds(userId, noteIds);
return new HashSet<>(likedIds);
}
}

View File

@ -1,125 +1,21 @@
package com.example.copykamanotes.service.impl;
import com.example.copykamanotes.mapper.NoteMapper;
import com.example.copykamanotes.model.base.ApiResponse;
import com.example.copykamanotes.model.base.EmptyVO;
import com.example.copykamanotes.model.base.Pagination;
import com.example.copykamanotes.model.dto.note.*;
import com.example.copykamanotes.model.entity.Note;
import com.example.copykamanotes.model.entity.Question;
import com.example.copykamanotes.model.entity.User;
import com.example.copykamanotes.model.vo.note.CreateNoteVO;
import com.example.copykamanotes.model.vo.note.DownloadNoteVO;
import com.example.copykamanotes.model.vo.note.NoteVO;
import com.example.copykamanotes.scope.RequestScopeData;
import com.example.copykamanotes.service.NoteLikeService;
import com.example.copykamanotes.service.NoteService;
import com.example.copykamanotes.service.QuestionService;
import com.example.copykamanotes.service.UserService;
import com.example.copykamanotes.utils.ApiResponseUtil;
import com.example.copykamanotes.utils.MarkdownUtil;
import com.example.copykamanotes.utils.PaginationUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Service
public class NoteServiceImpl implements NoteService {
@Autowired
private NoteMapper noteMapper;
@Autowired
private UserService userService;
@Autowired
private QuestionService questionService;
@Autowired
private NoteLikeService noteLikeService;
@Autowired
private RequestScopeData requestScopeData;
@Override
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
int offset = PaginationUtil.calculateOffset(noteQueryParams.getPage(), noteQueryParams.getPageSize());
int total = noteMapper.countNotes(noteQueryParams);
Pagination pagination = new Pagination(noteQueryParams.getPage(), noteQueryParams.getPageSize(), total);
List<Note> notes = noteMapper.findByQueryParam(noteQueryParams, noteQueryParams.getPageSize(), offset);
List<Integer> questionIds = notes.stream().map(Note::getQuestionId).distinct().toList();
List<Long> authorIds = notes.stream().map(Note::getAuthorId).distinct().toList();
List<Integer> noteIds = notes.stream().map(Note::getNoteId).toList();
Map<Long, User> userMapByIds = userService.getUserMapByIds(authorIds);
Map<Integer, Question> questionMapByIds = questionService.getQuestionMapByIds(questionIds);
Set<Integer> userLikedNoteIds;
Set<Integer> userCollectedNoteIds;
if (requestScopeData.isLogin() && requestScopeData.getUserId() != null) {
Long currentUserId = requestScopeData.getUserId();
userLikedNoteIds = noteLikeService.findUserLikedNoteIds(currentUserId, noteIds);
userCollectedNoteIds = noteLikeService.findUserLikedNoteIds(currentUserId, noteIds);
} else {
userLikedNoteIds = Collections.emptySet();
userCollectedNoteIds = Collections.emptySet();
}
try {
List<NoteVO> noteVOs = notes.stream().map(note -> {
NoteVO noteVO = new NoteVO();
BeanUtils.copyProperties(note, noteVO);
User author = userMapByIds.get(note.getAuthorId());
if (author != null) {
NoteVO.SimpleAuthorVO authorVO = new NoteVO.SimpleAuthorVO();
BeanUtils.copyProperties(author, authorVO);
noteVO.setAuthor(authorVO);
}
Question question = questionMapByIds.get(note.getQuestionId());
if (question != null) {
NoteVO.SimpleQuestionVO questionVO = new NoteVO.SimpleQuestionVO();
BeanUtils.copyProperties(question, questionVO);
noteVO.setQuestion(questionVO);
}
NoteVO.UserActionsVO userActionsVO = new NoteVO.UserActionsVO();
if (userLikedNoteIds != null && userLikedNoteIds.contains(note.getNoteId())) {
userActionsVO.setIsLiked(true);
}
if (userCollectedNoteIds != null && userCollectedNoteIds.contains(note.getNoteId())) {
userActionsVO.setIsCollected(true);
}
if (MarkdownUtil.needCollapsed(note.getContent())) {
noteVO.setNeedCollapsed(true);
noteVO.setDisplayContent(MarkdownUtil.extractIntroduction(note.getContent()));
} else {
noteVO.setNeedCollapsed(false);
}
noteVO.setUserActions(userActionsVO);
return noteVO;
}).toList();
return ApiResponseUtil.success("获取笔记列表成功", noteVOs, pagination);
} catch (Exception e) {
return ApiResponseUtil.error("获取笔记列表失败");
}
return null;
}
@Override

View File

@ -1,15 +0,0 @@
package com.example.copykamanotes.service.impl;
import com.example.copykamanotes.model.entity.Question;
import com.example.copykamanotes.service.QuestionService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class QuestionServiceImpl implements QuestionService {
public Map<Integer, Question> getQuestionMapByIds(List<Integer> questionIds) {
return null;
}
}

View File

@ -1,80 +0,0 @@
package com.example.copykamanotes.utils;
import com.vladsch.flexmark.ast.Heading;
import com.vladsch.flexmark.ast.Image;
import com.vladsch.flexmark.ast.Paragraph;
import com.vladsch.flexmark.ast.Text;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Document;
import com.vladsch.flexmark.util.ast.Node;
import java.util.ArrayList;
import java.util.List;
public class MarkdownAST {
private final Document markdownAST;
private final String markdownText;
public MarkdownAST( String markdownText) {
this.markdownText = markdownText;
Parser parser = Parser.builder().build();
this.markdownAST = parser.parse(markdownText);
}
public String extractIntroduction(int maxChars) {
StringBuilder introText = new StringBuilder();
for (Node node : markdownAST.getChildren()) {
if (node instanceof Heading || node instanceof Paragraph) {
String renderedText = getNoteText(node);
int remainingChars = maxChars - introText.length();
introText.append(renderedText, 0, Math.min(remainingChars, renderedText.length()));
if (introText.length() >= maxChars) {
break;
}
}
}
return introText.toString().trim() + "...";
}
public List<String> extractImages() {
List<String> images = new ArrayList<>();
for (Node node : markdownAST.getChildren()) {
if (node instanceof Image imageNode) {
images.add(((Image) node).getUrl().toString());
}
}
return images;
}
public boolean shouldCollapse(int maxChars) {
return hasImages() || markdownText.length() > maxChars;
}
public String getCollapseMarkdown() {
String introText = extractIntroduction(150);
return introText + "...";
}
private String getNoteText(Node node) {
StringBuilder text = new StringBuilder();
if (node instanceof Text) {
text.append(((Text) node).getChars());
}
for (Node child : node.getChildren()) {
text.append(getNoteText(child));
}
return text.toString();
}
private boolean hasImages() {
return !extractImages().isEmpty();
}
}

View File

@ -1,13 +0,0 @@
package com.example.copykamanotes.utils;
public class MarkdownUtil {
public static boolean needCollapsed(String markdown) {
MarkdownAST ast = new MarkdownAST(markdown);
return ast.shouldCollapse(250);
}
public static String extractIntroduction(String markdown) {
MarkdownAST ast = new MarkdownAST(markdown);
return ast.extractIntroduction(250);
}
}

View File

@ -1,84 +0,0 @@
<?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.example.copykamanotes.mapper.CategoryMapper">
<insert id="insert" useGeneratedKeys="true" keyProperty="categoryId"
parameterType="com.example.copykamanotes.model.entity.Category">
INSERT INTO category (name, parent_category_id)
VALUES (#{name}, #{parentCategoryId})
</insert>
<insert id="insertBatch" parameterType="com.example.copykamanotes.model.entity.Category">
<if test="categories != null and categories.size > 0">
INSERT INTO category (name, parent_category_id)
VALUES
<foreach collection="categories" item="category" separator=",">
(#{category.name}, #{category.parentCategoryId})
</foreach>
</if>
<if test="categories == null or categories.size == 0">
SELECT 0
</if>
</insert>
<select id="categoryList" resultType="com.example.copykamanotes.model.entity.Category">
SELECT *
FROM category
</select>
<select id="findById" resultType="com.example.copykamanotes.model.entity.Category">
SELECT *
FROM category
WHERE category_id = #{parentCategoryId}
</select>
<select id="findByIdBatch" resultType="com.example.copykamanotes.model.entity.Category">
<if test="categoryIds != null and categoryIds.size > 0">
SELECT * FROM category
WHERE category_id IN
<foreach collection="categoryIds" item="categoryId" open="(" separator="," close=")">
#{categoryId}
</foreach>
</if>
<if test="categoryIds == null or categoryIds.size == 0">
SELECT * FROM category WHERE 1 = 0
</if>
</select>
<select id="findByIdOrParentId" resultType="com.example.copykamanotes.model.entity.Category">
SELECT *
FROM category
WHERE category_id = #{categoryId}
OR parent_category_id = #{categoryId}
</select>
<delete id="deleteById">
DELETE
FROM category
WHERE category_id = #{categoryId}
</delete>
<delete id="deleteByIdBatch">
<if test="categoryIds != null and categoryIds.size > 0">
DELETE
FROM category
WHERE category_id IN
<foreach collection="categoryIds" item="categoryId" open="(" separator="," close=")">
#{categoryId}
</foreach>
</if>
<if test="categoryIds == null or categoryIds.size == 0">
DELETE FROM category WHERE 1 = 0
</if>
</delete>
<update id="update" parameterType="com.example.copykamanotes.model.entity.Category">
UPDATE category
<set>
<if test="name != null">
name = #{name},
</if>
</set>
WHERE category_id = #{categoryId}
</update>
</mapper>

View File

@ -1,49 +0,0 @@
<?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.example.copykamanotes.mapper.CollectionMapper">
<select id="findById" resultType="com.example.copykamanotes.model.entity.Collection">
SELECT *
FROM collection
WHERE collection_id = #{collectionId}
</select>
<select id="findByCreatorId" resultType="com.example.copykamanotes.model.entity.Collection">
SELECT *
FROM collection
WHERE creator_id = #{creatorId}
</select>
<select id="findByIdAndCreatorId" resultType="com.example.copykamanotes.model.entity.Collection">
SELECT *
FROM collection
WHERE collection_id = #{collectionId}
AND creator_id = #{creatorId}
</select>
<select id="countByCreatorIdAndNoteId" resultType="java.lang.Integer">
SELECT COUNT(note_id)
FROM collection_note cn
LEFT JOIN collection c ON cn.collection_id = c.collection_id
WHERE creator_id = #{creatorId}
AND note_id = #{noteId}
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="collectionId">
INSERT INTO collection (name, description, creator_id)
VALUES (#{name}, #{description}, #{creatorId})
</insert>
<update id="update">
UPDATE collection
SET name = #{name},
description = #{description}
WHERE collection_id = #{collectionId}
</update>
<delete id="deleteById">
DELETE
FROM collection
WHERE collection_id = #{collectionId}
</delete>
</mapper>

View File

@ -1,55 +0,0 @@
<?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.example.copykamanotes.mapper.CollectionNoteMapper">
<select id="findUserCollectedNoteIds" resultType="integer">
<if test="noteIds != null and noteIds.size > 0">
SELECT note_id
FROM collection_note
WHERE collection_id IN (
SELECT collection_id
FROM collection
WHERE creator_id = #{userId}
)
AND note_id IN
<foreach collection="noteIds" item="noteId" open="(" separator="," close=")">
#{noteId}
</foreach>
</if>
<if test="noteIds == null or noteIds.size == 0">
SELECT note_id FROM collection_note WHERE 1 = 0
</if>
</select>
<select id="filterCollectionIdsByNoteId" resultType="integer">
SELECT collection_id
FROM collection_note
WHERE note_id = #{noteId}
<if test="collectionIds != null and collectionIds.size > 0">
AND collection_id IN
<foreach collection="collectionIds" item="collectionId" open="(" separator="," close=")">
#{collectionId}
</foreach>
</if>
<if test="collectionIds == null or collectionIds.size == 0">
AND 1 = 0
</if>
</select>
<insert id="insert">
INSERT INTO collection_note (collection_id, note_id)
VALUES (#{collectionId}, #{noteId})
</insert>
<delete id="deleteByCollectionId">
DELETE
FROM collection_note
WHERE collection_id = #{collectionId}
</delete>
<delete id="deleteByCollectionIdAndNoteId">
DELETE
FROM collection_note
WHERE collection_id = #{collectionId}
AND note_id = #{noteId}
</delete>
</mapper>

View File

@ -1,36 +0,0 @@
<?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.example.copykamanotes.mapper.CommentLikeMapper">
<!-- 评论点赞结果映射 -->
<resultMap id="commentLikeMap" type="com.example.copykamanotes.model.entity.CommentLike">
<id property="commentLikeId" column="comment_like_id"/>
<result property="commentId" column="comment_id"/>
<result property="userId" column="user_id"/>
<result property="createdAt" column="created_at"/>
</resultMap>
<!-- 插入评论点赞 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="commentLikeId">
INSERT INTO comment_like (
comment_id, user_id, created_at
) VALUES (
#{commentId}, #{userId}, #{createdAt}
)
</insert>
<!-- 删除评论点赞 -->
<delete id="delete">
DELETE FROM comment_like
WHERE comment_id = #{commentId} AND user_id = #{userId}
</delete>
<!-- 查询用户点赞的评论ID列表 -->
<select id="findUserLikedCommentIds" resultType="integer">
SELECT DISTINCT comment_id FROM comment_like
WHERE user_id = #{userId}
AND comment_id IN
<foreach collection="commentIds" item="commentId" open="(" separator="," close=")">
#{commentId}
</foreach>
</select>
</mapper>

View File

@ -1,95 +0,0 @@
<?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.example.copykamanotes.mapper.CommentMapper">
<!-- 评论结果映射 -->
<resultMap id="commentMap" type="com.example.copykamanotes.model.entity.Comment">
<id property="commentId" column="comment_id"/>
<result property="noteId" column="note_id"/>
<result property="authorId" column="author_id"/>
<result property="parentId" column="parent_id"/>
<result property="content" column="content"/>
<result property="likeCount" column="like_count"/>
<result property="replyCount" column="reply_count"/>
<result property="createdAt" column="created_at"/>
<result property="updatedAt" column="updated_at"/>
</resultMap>
<!-- 插入评论 -->
<insert id="insert" useGeneratedKeys="true" keyProperty="commentId">
INSERT INTO comment (
note_id, author_id, parent_id, content,
like_count, reply_count, created_at, updated_at
) VALUES (
#{noteId}, #{authorId}, #{parentId}, #{content},
#{likeCount}, #{replyCount}, #{createdAt}, #{updatedAt}
)
</insert>
<!-- 更新评论 -->
<update id="update">
UPDATE comment
<set>
<if test="content != null">content = #{content},</if>
<if test="likeCount != null">like_count = #{likeCount},</if>
<if test="replyCount != null">reply_count = #{replyCount},</if>
updated_at = CURRENT_TIMESTAMP
</set>
WHERE comment_id = #{commentId}
</update>
<!-- 删除评论 -->
<delete id="deleteById">
DELETE FROM comment WHERE comment_id = #{commentId}
</delete>
<!-- 根据ID查询评论 -->
<select id="findById" resultMap="commentMap">
SELECT * FROM comment WHERE comment_id = #{commentId}
</select>
<!-- 查询评论列表 -->
<select id="findByQueryParam" resultMap="commentMap">
SELECT * FROM comment
<where>
<if test="params.noteId != null">AND note_id = #{params.noteId}</if>
<if test="params.parentId != null">AND parent_id = #{params.parentId}</if>
<if test="params.authorId != null">AND author_id = #{params.authorId}</if>
</where>
ORDER BY created_at DESC
LIMIT #{pageSize} OFFSET #{offset}
</select>
<!-- 统计评论数量 -->
<select id="countByQueryParam" resultType="int">
SELECT COUNT(*) FROM comment
<where>
<if test="params.noteId != null">AND note_id = #{params.noteId}</if>
<if test="params.parentId != null">AND parent_id = #{params.parentId}</if>
<if test="params.authorId != null">AND author_id = #{params.authorId}</if>
</where>
</select>
<!-- 增加评论点赞数 -->
<update id="incrementLikeCount">
UPDATE comment SET like_count = like_count + 1
WHERE comment_id = #{commentId}
</update>
<!-- 减少评论点赞数 -->
<update id="decrementLikeCount">
UPDATE comment SET like_count = like_count - 1
WHERE comment_id = #{commentId} AND like_count > 0
</update>
<!-- 增加评论回复数 -->
<update id="incrementReplyCount">
UPDATE comment SET reply_count = reply_count + 1
WHERE comment_id = #{commentId}
</update>
<!-- 减少评论回复数 -->
<update id="decrementReplyCount">
UPDATE comment SET reply_count = reply_count - 1
WHERE comment_id = #{commentId} AND reply_count > 0
</update>
</mapper>

View File

@ -1,110 +0,0 @@
<?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.example.copykamanotes.mapper.MessageMapper">
<resultMap id="BaseResultMap" type="com.example.copykamanotes.model.entity.Message">
<id column="message_id" property="messageId"/>
<result column="receiver_id" property="receiverId"/>
<result column="sender_id" property="senderId"/>
<result column="type" property="type"/>
<result column="target_id" property="targetId"/>
<result column="content" property="content"/>
<result column="is_read" property="isRead"/>
<result column="created_at" property="createdAt"/>
<result column="updated_at" property="updatedAt"/>
</resultMap>
<sql id="Base_Column_List">
message_id, receiver_id, sender_id, type, target_id, content, is_read, created_at, updated_at
</sql>
<insert id="insert" parameterType="com.example.copykamanotes.model.entity.Message" useGeneratedKeys="true" keyProperty="messageId">
INSERT INTO message (
receiver_id, sender_id, type, target_id, content, is_read, created_at, updated_at
) VALUES (
#{receiverId}, #{senderId}, #{type}, #{targetId}, #{content}, #{isRead}, #{createdAt}, #{updatedAt}
)
</insert>
<select id="selectByParams" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM message
<where>
receiver_id = #{userId}
<if test="params.type != null">
AND type = #{params.type}
</if>
<if test="params.isRead != null">
AND is_read = #{params.isRead}
</if>
<if test="params.startTime != null">
AND created_at >= #{params.startTime}
</if>
<if test="params.endTime != null">
AND created_at &lt;= #{params.endTime}
</if>
</where>
ORDER BY ${params.sortField} ${params.sortOrder}
LIMIT #{params.pageSize}
OFFSET #{offset}
</select>
<select id="countByParams" resultType="int">
SELECT COUNT(*)
FROM message
<where>
receiver_id = #{userId}
<if test="params.type != null">
AND type = #{params.type}
</if>
<if test="params.isRead != null">
AND is_read = #{params.isRead}
</if>
<if test="params.startTime != null">
AND created_at >= #{params.startTime}
</if>
<if test="params.endTime != null">
AND created_at &lt;= #{params.endTime}
</if>
</where>
</select>
<update id="markAsRead">
UPDATE message
SET is_read = true,
updated_at = NOW()
WHERE message_id = #{messageId}
AND receiver_id = #{userId}
</update>
<update id="markAllAsRead">
UPDATE message
SET is_read = true,
updated_at = NOW()
WHERE receiver_id = #{userId}
AND is_read = false
</update>
<delete id="deleteMessage">
DELETE FROM message
WHERE message_id = #{messageId}
AND receiver_id = #{userId}
</delete>
<select id="countUnread" resultType="int">
SELECT COUNT(*)
FROM message
WHERE receiver_id = #{userId}
AND is_read = false
</select>
<select id="countUnreadByType" resultType="com.example.copykamanotes.model.vo.message.UnreadCountByType">
SELECT
type,
COUNT(*) as count
FROM message
WHERE receiver_id = #{userId}
AND is_read = false
GROUP BY type
</select>
</mapper>

View File

@ -1,41 +0,0 @@
<?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.example.copykamanotes.mapper.NoteCollectMapper">
<!-- 收藏结果映射 -->
<resultMap id="BaseResultMap" type="com.example.copykamanotes.model.entity.NoteCollect">
<id column="collect_id" property="collectId"/>
<result column="note_id" property="noteId"/>
<result column="user_id" property="userId"/>
<result column="created_at" property="createdAt"/>
</resultMap>
<!-- 插入收藏记录 -->
<insert id="insert" parameterType="com.example.copykamanotes.model.entity.NoteCollect" useGeneratedKeys="true" keyProperty="collectId">
INSERT INTO note_collect (note_id, user_id)
VALUES (#{noteId}, #{userId})
</insert>
<!-- 删除收藏记录 -->
<delete id="delete">
DELETE FROM note_collect
WHERE note_id = #{noteId}
AND user_id = #{userId}
</delete>
<!-- 根据用户ID和笔记ID查询收藏记录 -->
<select id="findByNoteIdAndUserId" resultMap="BaseResultMap">
SELECT *
FROM note_collect
WHERE note_id = #{noteId}
AND user_id = #{userId}
LIMIT 1
</select>
<!-- 查询用户收藏的笔记ID列表 -->
<select id="findNoteIdsByUserId" resultType="java.lang.Integer">
SELECT note_id
FROM note_collect
WHERE user_id = #{userId}
ORDER BY created_at DESC
</select>
</mapper>

View File

@ -1,47 +0,0 @@
<?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.example.copykamanotes.mapper.NoteCommentMapper">
<resultMap id="BaseResultMap" type="com.example.copykamanotes.model.entity.NoteComment">
<id column="id" property="id" />
<result column="note_id" property="noteId" />
<result column="user_id" property="userId" />
<result column="content" property="content" />
<result column="created_at" property="createdAt" />
<result column="updated_at" property="updatedAt" />
<result column="is_deleted" property="isDeleted" />
</resultMap>
<sql id="Base_Column_List">
id, note_id, user_id, content, created_at, updated_at, is_deleted
</sql>
<insert id="insert" parameterType="com.example.copykamanotes.model.entity.NoteComment" useGeneratedKeys="true" keyProperty="id">
INSERT INTO note_comment (
note_id, user_id, content, created_at, updated_at, is_deleted
) VALUES (
#{noteId}, #{userId}, #{content}, #{createdAt}, #{updatedAt}, #{isDeleted}
)
</insert>
<update id="update" parameterType="com.example.copykamanotes.model.entity.NoteComment">
UPDATE note_comment
SET updated_at = #{updatedAt},
is_deleted = #{isDeleted}
WHERE id = #{id}
</update>
<select id="findById" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM note_comment
WHERE id = #{id}
</select>
<select id="findByNoteId" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM note_comment
WHERE note_id = #{noteId}
AND is_deleted = false
ORDER BY created_at DESC
</select>
</mapper>

View File

@ -1,36 +0,0 @@
<?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.example.copykamanotes.mapper.NoteLikeMapper">
<select id="findUserLikedNoteIds" resultType="integer">
<if test="noteIds != null and noteIds.size > 0">
SELECT note_id FROM note_like
WHERE note_id IN
<foreach collection="noteIds" item="noteId" open="(" separator="," close=")">
#{noteId}
</foreach>
AND user_id = #{userId}
</if>
<if test="noteIds == null or noteIds.size == 0">
SELECT note_id FROM note_like WHERE 1 = 0
</if>
</select>
<select id="findByUserIdAndNoteId" resultType="com.example.copykamanotes.model.entity.NoteLike">
SELECT *
FROM note_like
WHERE user_id = #{userId}
AND note_id = #{noteId}
</select>
<insert id="insert">
INSERT INTO note_like (user_id, note_id)
VALUES (#{userId}, #{noteId})
</insert>
<delete id="delete">
DELETE
FROM note_like
WHERE user_id = #{userId}
AND note_id = #{noteId}
</delete>
</mapper>

View File

@ -1,296 +0,0 @@
<?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.kama.notes.mapper.NoteMapper">
<sql id="whereClause">
<where>
<if test="params.questionId != null">
AND question_id = #{params.questionId}
</if>
<if test="params.authorId != null">
AND author_id = #{params.authorId}
</if>
<if test="params.collectionId != null">
AND note_id IN (SELECT note_id FROM collection_note WHERE collection_id = #{params.collectionId})
</if>
<if test="params.recentDays != null">
AND created_at >= DATE_SUB(CURRENT_DATE, INTERVAL #{params.recentDays} DAY)
</if>
</where>
</sql>
<select id="countNotes" resultType="int">
SELECT COUNT(*) FROM note
<include refid="whereClause"/>
</select>
<select id="findByQueryParams" resultType="com.kama.notes.model.entity.Note">
SELECT * FROM note
<include refid="whereClause"/>
<choose>
<when test="params.sort != null and params.sort == 'create'">
ORDER BY created_at
<choose>
<when test="params.order != null and (params.order == 'asc' or params.order == 'desc')">
${params.order}
</when>
<otherwise>
ASC
</otherwise>
</choose>
</when>
</choose>
LIMIT #{limit} OFFSET ${offset}
</select>
<select id="filterFinishedQuestionIdsByUser" resultType="integer">
<if test="questionIds != null and questionIds.size > 0">
SELECT question_id
FROM note
WHERE author_id = #{authorId}
AND question_id IN
<foreach collection="questionIds" item="questionId" open="(" separator="," close=")">
#{questionId}
</foreach>
</if>
<if test="questionIds == null or questionIds.size == 0">
SELECT question_id FROM note WHERE 1 = 0
</if>
</select>
<select id="findByAuthorIdAndQuestionId" resultType="com.kama.notes.model.entity.Note">
SELECT *
FROM note
WHERE question_id = #{questionId}
AND author_id = #{authorId}
</select>
<select id="findByAuthorId" resultType="com.kama.notes.model.entity.Note">
SELECT *
FROM note
WHERE author_id = #{authorId}
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="noteId">
INSERT INTO note (question_id, author_id, content)
VALUES (#{questionId}, #{authorId}, #{content})
</insert>
<resultMap id="BaseResultMap" type="com.kama.notes.model.entity.Note">
<id column="note_id" property="noteId"/>
<result column="author_id" property="authorId"/>
<result column="question_id" property="questionId"/>
<result column="content" property="content"/>
<result column="like_count" property="likeCount"/>
<result column="comment_count" property="commentCount"/>
<result column="collect_count" property="collectCount"/>
<result column="created_at" property="createdAt"/>
<result column="updated_at" property="updatedAt"/>
</resultMap>
<select id="findById" resultMap="BaseResultMap">
SELECT * FROM note WHERE note_id = #{noteId}
</select>
<update id="update">
UPDATE note
SET content = #{content}
WHERE note_id = #{noteId}
</update>
<update id="likeNote">
UPDATE note
SET like_count = like_count + 1
WHERE note_id = #{noteId}
</update>
<update id="unlikeNote">
UPDATE note
SET like_count = like_count - 1
WHERE note_id = #{noteId}
</update>
<update id="collectNote">
UPDATE note
SET collect_count = collect_count + 1
WHERE note_id = #{noteId}
</update>
<update id="unCollectNote">
UPDATE note
SET collect_count = collect_count - 1
WHERE note_id = #{noteId}
</update>
<delete id="deleteById">
DELETE
FROM note
WHERE note_id = #{noteId}
</delete>
<select id="findCollections" resultType="com.kama.notes.model.entity.Collection">
SELECT *
FROM collection
WHERE collection_id = #{collectionId}
</select>
<resultMap id="NoteRankListItemMap" type="com.kama.notes.model.vo.note.NoteRankListItem">
<result property="userId" column="author_id"/>
<result property="username" column="username"/>
<result property="avatarUrl" column="avatar_url"/>
<result property="noteCount" column="author_notes_count"/>
<result property="rank" column="rank"/>
</resultMap>
<select id="submitNoteRank" resultMap="NoteRankListItemMap">
SELECT author_id,
user.username,
user.avatar_url,
COUNT(note_id) AS author_notes_count,
RANK() OVER (ORDER BY COUNT(note_id) DESC) AS `rank`
FROM note
INNER JOIN user ON note.author_id = user.user_id
WHERE DATE (note.created_at) = CURDATE()
GROUP BY author_id, user.username, user.avatar_url
ORDER BY author_notes_count DESC LIMIT 10
</select>
<resultMap id="submitNoteHeatMapMap" type="com.kama.notes.model.vo.note.NoteHeatMapItem">
<result property="count" column="note_count"/>
<result property="date" column="note_date"/>
<result property="rank" column="note_rank"/>
</resultMap>
<!-- sql 复杂度较高,导致使用 IDEA 的 command + option + L 格式化时,
COUNT 函数和 DATE 函数前后会被自动加上空格,这将导致 sql 语法错误
切记切记这段 sql 不要使用 IDEA 进行自动格式化!!!-->
<select id="submitNoteHeatMap" resultMap="submitNoteHeatMapMap">
WITH DailyNoteCounts AS (
SELECT author_id,
DATE(created_at) AS note_date,
COUNT(note_id) AS note_count
FROM note
WHERE DATE(created_at) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 94 DAY) AND CURRENT_DATE
GROUP BY author_id, DATE(created_at)
),
RankedNotes AS (
SELECT author_id, note_date, note_count,
RANK() OVER (PARTITION BY note_date ORDER BY note_count DESC) AS note_rank
FROM DailyNoteCounts
)
SELECT note_date,
note_count,
note_rank
FROM RankedNotes
WHERE author_id = #{authorId};
</select>
<resultMap id="submitNoteTop3CountMap" type="com.kama.notes.model.vo.note.Top3Count">
<result property="thisMonthTop3Count" column="this_month_top_3"/>
<result property="lastMonthTop3Count" column="last_month_top_3"/>
</resultMap>
<!-- 同上,不要格式化-->
<select id="submitNoteTop3Count" resultMap="submitNoteTop3CountMap">
WITH DailyNoteCounts AS (SELECT author_id,
DATE(created_at) AS note_date
, COUNT(note_id) AS note_count
FROM note
WHERE DATE(created_at) BETWEEN DATE_SUB(CURDATE()
, INTERVAL DAYOFMONTH(CURDATE()) - 1 DAY) - INTERVAL 1 MONTH
AND LAST_DAY(CURDATE())
GROUP BY author_id, DATE(created_at)
),
RankedNotes AS (
SELECT author_id, note_date, note_count, RANK() OVER (PARTITION BY note_date ORDER BY note_count DESC) AS note_rank
FROM DailyNoteCounts
)
SELECT author_id,
SUM(
CASE
WHEN
<![CDATA[note_rank <= 3]]>
AND note_date BETWEEN DATE_SUB(CURDATE(), INTERVAL DAYOFMONTH(CURDATE()) - 1 DAY) -
INTERVAL 1 MONTH
AND LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
THEN 1
ELSE 0
END
) AS last_month_top_3,
SUM(
CASE
WHEN
<![CDATA[note_rank <= 3]]>
AND note_date BETWEEN DATE_SUB(CURDATE(), INTERVAL DAYOFMONTH(CURDATE()) - 1 DAY)
AND LAST_DAY(CURDATE())
THEN 1
ELSE 0
END
) AS this_month_top_3
FROM RankedNotes
WHERE author_id = #{authorId}
GROUP BY author_id
</select>
<select id="getTodayNoteCount" resultType="integer">
SELECT COUNT(*)
FROM note
WHERE DATE(created_at) = CURDATE()
</select>
<select id="getTodaySubmitNoteUserCount" resultType="integer">
SELECT COUNT(DISTINCT author_id)
FROM note
WHERE DATE(created_at) = CURDATE()
GROUP BY author_id
</select>
<select id="getTotalNoteCount" resultType="integer">
SELECT COUNT(*)
FROM note
</select>
<update id="incrementCommentCount">
UPDATE note
SET comment_count = comment_count + 1,
updated_at = CURRENT_TIMESTAMP
WHERE note_id = #{noteId}
</update>
<update id="decrementCommentCount">
UPDATE note
SET comment_count = CASE
WHEN comment_count > 0 THEN comment_count - 1
ELSE 0
END,
updated_at = CURRENT_TIMESTAMP
WHERE note_id = #{noteId}
</update>
<!-- 搜索笔记 -->
<select id="searchNotes" resultType="com.kama.notes.model.entity.Note">
SELECT
n.*,
MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance
FROM note n
WHERE MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)
ORDER BY relevance DESC
LIMIT #{limit} OFFSET #{offset}
</select>
<!-- 根据标签搜索笔记 -->
<select id="searchNotesByTag" resultType="com.kama.notes.model.entity.Note">
SELECT DISTINCT
n.*,
MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance
FROM note n
LEFT JOIN note_tag nt ON n.id = nt.note_id
LEFT JOIN tag t ON nt.tag_id = t.id
WHERE
MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)
OR t.name LIKE CONCAT('%', #{tag}, '%')
ORDER BY relevance DESC
LIMIT #{limit} OFFSET #{offset}
</select>
</mapper>

View File

@ -1,80 +0,0 @@
<?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.example.copykamanotes.mapper.QuestionListItemMapper">
<insert id="insert">
INSERT INTO question_list_item (question_list_id, question_id, `rank`)
VALUES (#{questionListId}, #{questionId}, #{rank})
</insert>
<resultMap id="QuestionListItemVOResultMap" type="com.example.copykamanotes.model.vo.questionListItem.QuestionListItemVO">
<id property="questionListId" column="question_list_id"/>
<id property="rank" column="rank"/>
<association property="question"
javaType="com.example.copykamanotes.model.vo.question.BaseQuestionVO">
<id property="questionId" column="question.question_id"/>
<result property="title" column="question.title"/>
<result property="viewCount" column="question.view_count"/>
<result property="examPoint" column="question.exam_point"/>
<result property="difficulty" column="question.difficulty"/>
<result property="categoryId" column="question.category_id"/>
</association>
</resultMap>
<sql id="findByIdSelectClause">
SELECT qli.question_list_id,
qli.rank,
q.question_id AS "question.question_id",
q.title AS "question.title",
q.view_count AS "question.view_count",
q.exam_point AS "question.exam_point",
q.difficulty AS "question.difficulty",
q.category_id AS "question.category_id"
FROM question_list_item qli
LEFT JOIN question q
ON qli.question_id = q.question_id
WHERE qli.question_list_id = #{questionListId}
ORDER BY qli.rank
</sql>
<select id="findByQuestionListId" resultMap="QuestionListItemVOResultMap">
<include refid="findByIdSelectClause"/>
</select>
<select id="countByQuestionListId" resultType="int">
SELECT COUNT(*)
FROM question_list_item
WHERE question_list_id = #{questionListId}
</select>
<select id="findByQuestionListIdPage" resultMap="QuestionListItemVOResultMap">
<include refid="findByIdSelectClause" />
LIMIT #{limit} OFFSET #{offset}
</select>
<delete id="deleteByQuestionListIdAndQuestionId">
DELETE
FROM question_list_item
WHERE question_list_id = #{questionListId}
AND question_id = #{questionId}
</delete>
<delete id="deleteByQuestionListId">
DELETE
FROM question_list_item
WHERE question_list_id = #{questionListId}
</delete>
<select id="nextRank" resultType="int">
SELECT COALESCE(MAX(`rank`), 0) + 1
FROM `question_list_item`
WHERE `question_list_id` = ${questionListId};
</select>
<update id="updateQuestionRank" parameterType="com.example.copykamanotes.model.entity.QuestionListItem">
UPDATE `question_list_item`
SET `rank` = #{rank}
WHERE `question_list_id` = #{questionListId}
AND `question_id` = #{questionId}
</update>
</mapper>

View File

@ -1,37 +0,0 @@
<?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.example.copykamanotes.mapper.QuestionListMapper">
<insert id="insert" useGeneratedKeys="true" keyProperty="questionListId">
INSERT INTO question_list (name, type, description)
VALUES (#{name}, #{type}, #{description})
</insert>
<update id="update">
UPDATE question_list
<set>
<if test="name != null">
name = #{name},
</if>
<if test="type != null">
type = #{type},
</if>
<if test="description != null">
description = #{description},
</if>
</set>
WHERE question_list_id = #{questionListId}
</update>
<delete id="deleteById">
DELETE FROM question_list WHERE question_list_id = #{questionListId}
</delete>
<select id="findById" resultType="com.example.copykamanotes.model.entity.QuestionList">
SELECT * FROM question_list WHERE question_list_id = #{questionListId}
</select>
<select id="findAll" resultType="com.example.copykamanotes.model.entity.QuestionList">
SELECT * FROM question_list
</select>
</mapper>

View File

@ -1,140 +0,0 @@
<?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.example.copykamanotes.mapper.QuestionMapper">
<insert id="insert" useGeneratedKeys="true" keyProperty="questionId"
parameterType="com.example.copykamanotes.model.entity.Question">
INSERT INTO question (category_id, title, difficulty, exam_point)
VALUES (#{categoryId}, #{title}, #{difficulty}, #{examPoint})
</insert>
<select id="findById" resultType="com.example.copykamanotes.model.entity.Question">
SELECT *
FROM question
WHERE question_id = #{questionId}
</select>
<select id="findByIdBatch" resultType="com.example.copykamanotes.model.entity.Question">
SELECT * FROM question
WHERE
<if test="questionIds != null and questionIds.size > 0">
question_id IN
<foreach collection="questionIds" item="questionId" open="(" separator="," close=")">
#{questionId}
</foreach>
</if>
<if test="questionIds == null or questionIds.size == 0">
1 = 2 <!-- 当 questionIds 为空时,返回一个永远不成立的条件 -->
</if>
</select>
<sql id="whereClause">
<where>
<if test="queryParam.categoryId != null">
(category_id = #{queryParam.categoryId}
OR category_id IN (
SELECT category_id
FROM category
WHERE parent_category_id = #{queryParam.categoryId}
))
</if>
</where>
</sql>
<select id="findByQueryParam" resultType="com.example.copykamanotes.model.entity.Question">
SELECT *
FROM question
<include refid="whereClause"/>
<choose>
<when test="queryParam.sort == 'view'">
ORDER BY view_count
</when>
<when test="queryParam.sort == 'difficulty'">
ORDER BY difficulty
</when>
<otherwise>
ORDER BY created_at
</otherwise>
</choose>
<choose>
<when test="queryParam.order == 'asc'">
ASC
</when>
<when test="queryParam.order == 'desc'">
DESC
</when>
<otherwise>
ASC
</otherwise>
</choose>
LIMIT #{limit} OFFSET #{offset}
</select>
<select id="findByKeyword" resultType="com.example.copykamanotes.model.entity.Question">
SELECT *
FROM question
<choose>
<when test="keyword != null">
WHERE title LIKE CONCAT('%', #{keyword}, '%')
</when>
<otherwise>
WHERE 1 = 2
</otherwise>
</choose>
</select>
<update id="update">
UPDATE question
<set>
<if test="question.title != null">
title = #{question.title},
</if>
<if test="question.difficulty != null">
difficulty = #{question.difficulty},
</if>
<if test="question.examPoint != null">
exam_point = #{question.examPoint},
</if>
</set>
WHERE question_id = #{question.questionId}
</update>
<update id="incrementViewCount">
UPDATE question
SET view_count = view_count + 1
WHERE question_id = #{questionId}
</update>
<select id="countByQueryParam" resultType="int">
SELECT COUNT(*)
FROM question
<include refid="whereClause"/>
</select>
<delete id="deleteByCategoryId">
DELETE
FROM question
WHERE category_id = #{categoryId}
</delete>
<delete id="deleteById">
DELETE
FROM question
WHERE question_id = #{questionId}
</delete>
<delete id="deleteByCategoryIdBatch">
<if test="categoryIds != null and categoryIds.size > 0">
DELETE
FROM question
WHERE category_id IN
<foreach collection="categoryIds" item="categoryId" open="(" separator="," close=")">
#{categoryId}
</foreach>
</if>
<if test="categoryIds == null or categoryIds.size == 0">
DELETE FROM question WHERE 1 = 0
</if>
</delete>
</mapper>

View File

@ -1,22 +0,0 @@
<?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.example.copykamanotes.mapper.StatisticMapper">
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
INSERT INTO statistic (login_count, register_count, total_register_count, note_count, submit_note_count,
total_note_count, date)
VALUES (#{loginCount}, #{registerCount}, #{totalRegisterCount}, #{noteCount}, #{submitNoteCount},
#{totalNoteCount}, #{date})
</insert>
<select id="countStatistic" resultType="integer">
SELECT COUNT(*)
FROM statistic
</select>
<select id="findByPage" resultType="com.example.copykamanotes.model.entity.Statistic">
SELECT *
FROM statistic
ORDER BY date DESC
LIMIT #{limit} OFFSET #{offset}
</select>
</mapper>