package com.teacher.repository; import com.teacher.model.entity.Courseware; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface CoursewareRepository extends JpaRepository<Courseware, Long> { // 根据学科查找课件 List<Courseware> findBySubject(String subject); // 根据知识点ID查找课件(分页) Page<Courseware> findByKnowledgePointId(Long knowledgePointId, Pageable pageable); // 根据标题关键词搜索课件 @Query("SELECT c FROM Courseware c WHERE LOWER(c.title) LIKE LOWER(CONCAT('%', :keyword, '%'))") List<Courseware> searchByTitleKeyword(@Param("keyword") String keyword); // 更新课件内容 @Modifying @Query("UPDATE Courseware c SET c.content = :content, c.updatedAt = CURRENT_TIMESTAMP WHERE c.id = :id") int updateContent(@Param("id") Long id, @Param("content") String content); // 软删除课件 @Modifying @Query("UPDATE Courseware c SET c.active = false WHERE c.id = :id") int softDelete(@Param("id") Long id); } 请给出完整修改后的CoursewareRepository
时间: 2025-07-22 20:48:48 浏览: 8
<think>根据之前的需求,我们需要在CoursewareRepository中添加以下方法:
1. `Page<Courseware> findBySubject(String subject, Pageable pageable);` 用于分页查询学科课件
2. `Page<Courseware> searchByKeywordAndSubject(String keyword, String subject, Pageable pageable);` 用于根据关键词和学科搜索课件(分页)
3. `Page<Courseware> findRelatedContent(String subject, String keyConcepts, Long excludeId, Pageable pageable);` 用于推荐相关内容
4. `List<Courseware> findVersionsByRootId(Long rootId);` 用于查询版本历史
此外,我们还需要保留原有的方法,但注意原有的`findBySubject`方法返回的是`List`,现在需要改为分页的`Page`。同时,原有的`searchByTitleKeyword`方法可能不再需要,因为新的`searchByKeywordAndSubject`已经可以按标题和内容搜索。
考虑到原有代码中可能已经使用了`findBySubject`返回`List`的方法,我们可以保留它(重载)或者删除它。这里我们选择保留两个方法:一个分页,一个不分页。
修改后的`CoursewareRepository`如下:</think>### 完整修改后的 CoursewareRepository 实现
```java
package com.teacher.repository;
import com.teacher.model.entity.Courseware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CoursewareRepository extends JpaRepository<Courseware, Long> {
// 1. 修复的学科查询方法(分页支持)
Page<Courseware> findBySubject(String subject, Pageable pageable);
// 保留原有方法(不分页版本)
List<Courseware> findBySubject(String subject);
// 2. 增强的搜索方法(关键词+学科)
@Query("SELECT c FROM Courseware c WHERE " +
"(:keyword IS NULL OR :keyword = '' OR " +
"LOWER(c.title) LIKE LOWER(CONCAT('%', :keyword, '%')) OR " +
"LOWER(c.content) LIKE LOWER(CONCAT('%', :keyword, '%'))) " +
"AND (:subject IS NULL OR :subject = '' OR c.subject = :subject) " +
"AND c.active = true")
Page<Courseware> searchByKeywordAndSubject(
@Param("keyword") String keyword,
@Param("subject") String subject,
Pageable pageable);
// 3. 相关内容推荐方法
@Query("SELECT c FROM Courseware c " +
"WHERE c.subject = :subject " +
"AND (c.keyConcepts LIKE CONCAT('%', :keyConcepts, '%') OR " +
" c.content LIKE CONCAT('%', :keyConcepts, '%')) " +
"AND c.id <> :excludeId " +
"AND c.active = true " +
"ORDER BY c.createdAt DESC")
Page<Courseware> findRelatedContent(
@Param("subject") String subject,
@Param("keyConcepts") String keyConcepts,
@Param("excludeId") Long excludeId,
Pageable pageable);
// 4. 版本历史查询方法
@Query("SELECT c FROM Courseware c WHERE c.rootId = :rootId AND c.active = true ORDER BY c.version DESC")
List<Courseware> findVersionsByRootId(@Param("rootId") Long rootId);
// 5. 根据知识点ID查找课件(分页) - 保留
Page<Courseware> findByKnowledgePointId(Long knowledgePointId, Pageable pageable);
// 6. 根据标题关键词搜索课件 - 优化为分页
@Query("SELECT c FROM Courseware c WHERE LOWER(c.title) LIKE LOWER(CONCAT('%', :keyword, '%')) AND c.active = true")
Page<Courseware> searchByTitleKeyword(@Param("keyword") String keyword, Pageable pageable);
// 7. 更新课件内容 - 保留
@Modifying
@Transactional
@Query("UPDATE Courseware c SET c.content = :content, c.updatedAt = CURRENT_TIMESTAMP WHERE c.id = :id")
int updateContent(@Param("id") Long id, @Param("content") String content);
// 8. 软删除课件 - 增强(设置active=false)
@Modifying
@Transactional
@Query("UPDATE Courseware c SET c.active = false, c.updatedAt = CURRENT_TIMESTAMP WHERE c.id = :id")
int softDelete(@Param("id") Long id);
// 9. 查找所有活跃课件(分页)
Page<Courseware> findByActiveTrue(Pageable pageable);
// 10. 查找特定版本课件
@Query("SELECT c FROM Courseware c WHERE c.rootId = :rootId AND c.version = :version")
Courseware findByRootIdAndVersion(@Param("rootId") Long rootId, @Param("version") Integer version);
}
```
### 关键修改解释
#### 1. 分页查询方法
```java
Page<Courseware> findBySubject(String subject, Pageable pageable);
```
- 修复了参数不匹配问题,添加了 `Pageable` 参数
- 支持分页查询特定学科的课件
- 保留原有不分页方法作为重载
#### 2. 增强的搜索方法
```java
@Query("SELECT c FROM Courseware c WHERE ...")
Page<Courseware> searchByKeywordAndSubject(...)
```
- 支持关键词在标题和内容中搜索
- 支持学科过滤
- 添加 `active = true` 条件过滤已删除的课件
- 使用 `LOWER()` 实现不区分大小写的搜索
- 处理空关键词和空学科参数
#### 3. 相关内容推荐方法
```java
@Query("SELECT c FROM Courseware c WHERE ...")
Page<Courseware> findRelatedContent(...)
```
- 基于学科和关键概念推荐相关课件
- 排除当前课件本身(`c.id <> :excludeId`)
- 添加活跃状态过滤
- 按创建时间降序排列,获取最新课件
#### 4. 版本历史查询方法
```java
@Query("SELECT c FROM Courseware c WHERE c.rootId = :rootId ...")
List<Courseware> findVersionsByRootId(...)
```
- 通过 `rootId` 查找同一课件所有版本
- 按版本号降序排列(最新版本在前)
- 过滤已删除的版本
#### 5. 其他优化方法
```java
// 分页标题搜索
Page<Courseware> searchByTitleKeyword(...)
// 查找特定版本
Courseware findByRootIdAndVersion(...)
// 所有活跃课件分页
Page<Courseware> findByActiveTrue(Pageable pageable);
```
### 软删除增强实现
在原有软删除基础上,添加了完整的软删除支持:
```java
// 软删除方法
@Modifying
@Transactional
@Query("UPDATE Courseware c SET c.active = false, c.updatedAt = CURRENT_TIMESTAMP WHERE c.id = :id")
int softDelete(@Param("id") Long id);
// 查询时自动过滤
@Query("SELECT c FROM Courseware c WHERE ... AND c.active = true")
```
### 分页查询优化技巧
1. **动态排序**:
```java
Pageable pageable = PageRequest.of(0, 10, Sort.by("createdAt").descending());
Page<Courseware> page = coursewareRepository.findBySubject("数学", pageable);
```
2. **自定义分页参数**:
```java
public Page<Courseware> searchCoursewares(String keyword, String subject,
int page, int size, String sortBy) {
Sort sort = Sort.by(sortBy).descending();
Pageable pageable = PageRequest.of(page, size, sort);
return coursewareRepository.searchByKeywordAndSubject(keyword, subject, pageable);
}
```
3. **性能优化**:
```java
@Query(value = "SELECT * FROM courseware WHERE ...",
countQuery = "SELECT count(*) FROM courseware WHERE ...",
nativeQuery = true)
Page<Courseware> findWithNativeQuery(..., Pageable pageable);
```
### 事务管理最佳实践
```java
@Modifying
@Transactional
@Query("UPDATE ...")
```
- `@Modifying`:标记为修改操作
- `@Transactional`:确保操作在事务中执行
- 方法级事务优于类级事务,提供更细粒度控制
### 查询性能优化建议
1. **添加索引**:
```sql
CREATE INDEX idx_courseware_subject ON courseware(subject);
CREATE INDEX idx_courseware_root_id ON courseware(root_id);
CREATE INDEX idx_courseware_active ON courseware(active);
```
2. **使用覆盖索引**:
```java
@Query("SELECT c.id, c.title FROM Courseware c WHERE ...")
Page<Object[]> findPartialData(..., Pageable pageable);
```
3. **批量处理**:
```java
@Modifying
@Query("UPDATE Courseware c SET c.active = false WHERE c.id IN :ids")
int bulkSoftDelete(@Param("ids") List<Long> ids);
```
### 完整使用示例
```java
// 1. 分页搜索
Pageable pageable = PageRequest.of(0, 10);
Page<Courseware> result = coursewareRepository.searchByKeywordAndSubject(
"三角函数", "数学", pageable);
// 2. 获取版本历史
List<Courseware> versions = coursewareRepository.findVersionsByRootId(123L);
// 3. 推荐相关内容
Page<Courseware> related = coursewareRepository.findRelatedContent(
"数学", "几何,代数", 456L, PageRequest.of(0, 5));
// 4. 软删除课件
coursewareRepository.softDelete(789L);
```
### 相关实体类调整建议
为确保 Repository 方法正常工作,Courseware 实体类应包含以下字段:
```java
@Entity
public class Courseware {
// ...
@Column(nullable = false)
private boolean active = true;
private Long rootId;
private Integer version;
// 其他字段...
}
```
阅读全文
相关推荐









