You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中REST API的Get方法实现:按姓名或流派查询艺术家

实现按艺术家姓名或流派查询的REST API接口方案

嘿,我来帮你搞定这个查询接口的问题!结合你给出的实体关联配置,这里有两种靠谱的实现方式,都是Spring Data JPA常用的套路:


方式一:用Spring Data JPA的派生查询方法(最简单)

这种方式不用写JPQL,直接靠方法名就能生成查询语句,非常省心。首先你得把Repository的泛型参数补全(JpaRepository需要实体类和ID类型,假设你的ID是Long),然后添加对应的查询方法:

@Repository
public interface ArtistRepository extends JpaRepository<Artist, Long> {
    // 模糊匹配艺术家姓名,或者模糊匹配关联流派的名称
    List<Artist> findByNameContainingOrGenresNameContaining(String artistName, String genreName);

    // 如果需要精确匹配的话,就把Containing去掉
    // List<Artist> findByNameOrGenresName(String artistName, String genreName);
}

这里要注意:因为你的Artist实体里关联的属性是private Genres genres;,所以派生方法里要用GenresName(驼峰式)来对应流派实体的name字段。


方式二:自定义JPQL查询(更灵活)

如果你需要更复杂的查询逻辑,或者想自己控制SQL生成,就用@Query注解来写JPQL。这里要注意关联查询的写法,因为是ManyToOne关联,直接JOIN实体的关联属性就行:

@Repository
public interface ArtistRepository extends JpaRepository<Artist, Long> {

    @Query("SELECT a FROM Artist a JOIN a.genres g WHERE a.name LIKE %:artistName% OR g.name LIKE %:genreName%")
    List<Artist> findByArtistNameOrGenreName(
            @Param("artistName") String artistName,
            @Param("genreName") String genreName
    );

    // 解决懒加载问题:如果返回Artist时需要同时加载关联的Genre,用FETCH JOIN
    @Query("SELECT a FROM Artist a JOIN FETCH a.genres g WHERE a.name LIKE %:artistName% OR g.name LIKE %:genreName%")
    List<Artist> findByArtistNameOrGenreNameWithGenreLoaded(
            @Param("artistName") String artistName,
            @Param("genreName") String genreName
    );
}

关键注意点:

  • 你的实体类如果是Artist(不是Artists),JPQL里要对应写Artist,不要写错类名
  • JOIN a.genres g 这里的genres是你Artist实体里定义的关联属性名,一定要和实体类里的字段名一致
  • %:param% 是用来做模糊匹配的,如果需要精确匹配,直接写成a.name = :artistName就行
  • 因为你用了FetchType.LAZY,如果在Controller里直接返回Artist对象,可能会触发懒加载异常(比如序列化的时候访问genre属性),这时候用JOIN FETCH就能一次性加载关联的Genre数据,避免这个问题。

最后在Controller里封装接口

把Repository的方法用到REST接口里,处理请求参数,比如允许用户只传姓名、只传流派,或者两个都传:

@RestController
@RequestMapping("/api/artists")
public class ArtistController {

    private final ArtistRepository artistRepository;

    // 构造注入(推荐的方式)
    public ArtistController(ArtistRepository artistRepository) {
        this.artistRepository = artistRepository;
    }

    @GetMapping
    public ResponseEntity<List<Artist>> searchArtists(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String genre) {

        List<Artist> artists;
        if (name != null && genre != null) {
            // 两个参数都传,按姓名或流派查询
            artists = artistRepository.findByNameContainingOrGenresNameContaining(name, genre);
        } else if (name != null) {
            // 只传姓名,按姓名查询
            artists = artistRepository.findByNameContaining(name);
        } else if (genre != null) {
            // 只传流派,按流派查询
            artists = artistRepository.findByGenresNameContaining(genre);
        } else {
            // 什么参数都没传,返回所有艺术家
            artists = artistRepository.findAll();
        }

        return ResponseEntity.ok(artists);
    }
}

小建议:

如果你的流派实体类叫Genre(单数)会更符合Java命名规范,对应的Artist里的关联属性改成private Genre genre;,这样派生方法名也会更直观,比如findByNameContainingOrGenreNameContaining。

内容的提问来源于stack exchange,提问作者Jeta Kasabaqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:49:13