SpringBoot中使用spring-data-JPA的Repository常用示例(模糊、分页,字段查询),实现无sql语句查询

文章目录


前言

近期使用了spring-data-jpa框架,进行无sql语句优雅查询,在此总结记录。


使用JPA

范例代码:
默认JPA中默认:在JpaRepository接口中可以看到默认的方法

返回数据库所有数据
	List<T> findAll();
	排序
	List<T> findAll(Sort sort);
	一个可以迭代的ids,jpa分别进行查找,有此id对应的数据就返回,没有也不报错
	List<T> findAllById(Iterable<ID> ids);
	批量保存
	List<S> saveAll(Iterable<S> entities);
	批量删除
	void deleteAllByIdInBatch(Iterable<ID> ids);
	根据id获取单一数据实体
	getById(ID id);

自己定义的高级用法

    /**
     * 根据项目Id判断项目额外信息是否已经存在
     * @param projectOpenId 项目Id
     * @return 存在true;不存在false
     */
    boolean existsByProjectOpenId(String projectOpenId);
    /**
     * 根据项目openId找项目额外信息实体
     * @param projectOpenId 属性名称
     * @return optional
     */
    Optional<ProjectExtraData> findFirstByProjectOpenId(String projectOpenId);
    /**
     * 分页查询
     * @param spec 复杂查询条件
     * @param pageable 分页参数
     * @return 分页数据
     */
    Page<DemanderInfo> findAll(Specification<DemanderInfo> spec, Pageable pageable);
        /**
     * 根据ids获取需求方明细
     * @param ids 需求方id
     * @return 明细列表
     */
    List<DemanderInfo> findAllByIdIn(long[] ids);
    /**
     * 判断某字符串是否存在(某动态属性是否被使用)
     * @param searchWords 搜索关键词
     * @return 存在true;不存在false
     */
    boolean existsByPropertyValuesLike(String searchWords);
    
    Page<Privilege> findAllByParentOpenIdIsNull(Pageable pageable);
    
    List<Privilege> findAllByParentOpenIdAndIsDeletedFalse(String parentOpenId, Sort sort);
    
   	List<ProjectWbs> findAllByParentOpenIdAndDeletedAtIsNull(String parentOpenId, Sort sort);



总结

持续更新,遇到合适的就加进来

<think>好的,我现在需要帮助用户解决在JpaRepository查询特定字段的问题。用户之前已经得到了三种方法的回答,现在他们再次询问,可能希望得到更详细的示例或者需要确认正确的实现方式。首先,我需要回顾之前的回答,确保新的回答不重复但更深入。用户提到参考了站内引用,其中引用[1]和[2]提到了JPA查询方法关键字和分页查询的例子。这可能意味着用户需要结合这些知识点,或者希望看到更多使用这些关键字的例子。 用户现在明确要求查询特定字段的方法和示例代码。之前的回答中已经列举了三种方法:原生SQL、JPQL构造函数、接口投影。我需要确保每种方法都有清晰的代码示例,并且符合用户当前的上下文。 可能需要检查是否有遗漏的方法,比如使用SpringData JPA的派生查询,但派生查询常用于基于字段名的查询,返回整个实体,而不是特定字段。不过,如果用户想通过方法名自动生成查询,可能无法直接返回部分字段,所以可能还是需要结合@Query注解。另外,用户提到的引用[2]中有分页的例子,可能需要考虑如何在查询特定字段时加入分页功能,比如在方法中添加Pageable参数,并返回Page对象。这可能是一个扩展点,但用户的问题可能暂时不需要,但可以作为相关信息提及。 需要确保示例代码正确,比如在接口投影中,字段别名必须与接口的getter方法匹配,否则会映射失败。同时,构造函数方式需要全参构造器,这些注意事项要再次强调,避免用户出错。可能还需要比较不同方法的优缺点,比如原生SQL可能更高效,但失去数据库的移植性;接口投影更灵活,但需要定义接口。用户可能需要根据实际情况选择合适的方法。 最后,生成的相关问题需要与当前主题紧密相关,比如动态查询、联表查询部分字段、性能比较等,这些都是用户在实现特定字段查询后可能遇到的后续问题。</think>### JpaRepository 查询特定字段的三种实现方法 --- #### 方法 1:原生 SQL 查询(返回 Object[]) 使用 `@Query` 注解配合原生 SQL 语句,直接获取字段值数组[^1]: ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "SELECT username, email FROM users WHERE age > :age", nativeQuery = true) List<Object[]> findUserInfoByAge(@Param("age") int age); } // 调用示例 List<Object[]> results = userRepository.findUserInfoByAge(18); results.forEach(arr -> { String username = (String) arr[0]; String email = (String) arr[1]; }); ``` --- #### 方法 2:JPQL 构造函数表达式(返回 DTO) 通过自定义 DTO 接收字段值,需定义全参构造函数[^1]: ```java // DTO 定义 public record UserInfoDTO(String username, String email) {} @Query("SELECT NEW com.example.dto.UserInfoDTO(u.username, u.email) " + "FROM User u WHERE u.age > :age") List<UserInfoDTO> findUserDTOByAge(@Param("age") int age); // 调用示例 List<UserInfoDTO> dtos = userRepository.findUserDTOByAge(18); dtos.forEach(dto -> { System.out.println(dto.username() + ": " + dto.email()); }); ``` --- #### 方法 3:接口投影(Interface Projection) 定义接口自动映射查询结果,字段别名必须与接口方法匹配[^1]: ```java public interface UserProjection { String getUsername(); String getEmail(); } @Query("SELECT u.username AS username, u.email AS email FROM User u WHERE u.age > ?1") List<UserProjection> findProjectionsByAge(int age); // 调用示例 List<UserProjection> projections = userRepository.findProjectionsByAge(18); projections.forEach(proj -> { System.out.println(proj.getUsername() + " - " + proj.getEmail()); }); ``` --- ### 性能优化建议 1. **选择性加载**:当实体包含大字段(如 `TEXT`/`BLOB`)时,投影查询可减少数据传输量 2. **分页支持**:所有方法均可添加分页参数,例如: ```java @Query("SELECT u.username FROM User u") Page<String> findAllUsernames(Pageable pageable); ``` 3. **索引利用**:仅查询必要字段可提升索引覆盖概率,减少回表查询[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值