Springboot JPA如何使用distinct返回对象

目录
  • JPA如何使用distinct返回对象
  • JPA自定义返回对象
    • 方法一
    • 方法二
    • 方法三
    • 方法四

JPA如何使用distinct返回对象

package com.frank.jpaBatchSave.repository;
import com.frank.jpaBatchSave.entity.Person;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface PersonRepository extends PagingAndSortingRepository<Person, Integer> {

    @Query("select distinct new Person(p.name, p.province, p.city) from Person p")
    List<Person> getAllPerson();
}

这里如果需要返回的是对象,则需要new Person(p.name, p.province, p.city),同时Person类必须要有三参的构造器。

public Person(String name, String province, String city) {
        this.name = name;
        this.province = province;
        this.city = city;
    }

因为:select distinct name, province, city) from Person p 这样写的话返回的是Object[]数组。所以需要使用上面的方式。

JPA自定义返回对象

任何ORM框架都少不了开放自定义sql的问题。jpa自然也不例外,很多场景需要写复杂sql的。

首先定义一个方法签名,然后打上@Query注解。像下面这样,需要注意nativeQuery,这个表示query中的字符以原始的sql语句执行,也就是不做任何调整。你写啥,就执行啥sql语句。但是想返回自定义的实体,Sorry,做不到。的用另一种方式。

@Query(value = "SELECT * from table where id= :id", nativeQuery = true)
List<aa> getByaaId(@Param("id") BigInteger id);

方法一

下面这个就是实现自定义的实体方法。首先需要定义个实体,这个实体必须包含无参和全参构造函数。然后去掉nativeQuery,同时还有一点必须注意,写的语句里面不是数据库中对应的实际表名,而是你定义的实体映射。比如下面的table1和table2,其实都是你定义的实体类的名字,不是你的数据库表名,是你代码中映射数据表的实体类名。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class aaDto {
    private String aa;
    private String bb;
    private String cc;
}
@Query(value = "SELECT new com.xxx.xxx.dto.aaDto(i.aa,i.bb,i.cc) FROM table1 i JOIN table2 e on i.id=e.id")
List<aaDto> getList();

方法二

方法一这种写法还是非常不灵活,有时候写一些函数什么的,估计会搞死,还是得写原生的sql才行。我说的查询字段属于多个表。如果只查询一个表字段,关联查询只是条件,可以直接返回对应的实体也是没问题的。

List<Map<String, Object>>
@Query(value = "SELECT a.aa,b.bb from a LEFT JOIN b a.id=b.id", nativeQuery = true)
List<Map<String, String>> getFundAccountList();

这样返回的数据就是一个集合,是键值型的,如果我们实在想用对象,不用Map,我是先把返回参数序列化成json,然后将这个json再反序列化成我们想要的对象即可。

方法三

在继承jpa接口的时候,里面的实体类写你的对应结果类,就可以用相应的结果来接收了。

public interface xxxDTORepository extends JpaRepository<xxxDTO, Long>

方法四

以上的方法都是基于继承JpaRepository接口来实现,其实又另外一种更加灵活的方式,这种方式可以更加灵活的写sql和定义返回对象。

@PersistenceContext
private EntityManager entityManager;

记录一个错误:Path expected for join!

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!

就这么个错误,其实很简单,只是我没有细看错误信息,导致在正确的语句找错误,找不到。出现这个错误,后面会跟你写的hql语句,注意留意这个hql语句,仔细检查,他一定是有错误的。

有个博客说需要添加映射关系,其实完全不用的,就是一对多,A类里面包含List<B> 是不需要这样的,独立类没任何关联也是可以的,细心细心细心。。。

顺带再来记录一个问题吧,这个问题简单,出现下面这段代码,后面会跟一些信息,根据信息就可以知道是返回对象的构造函数类型问题,既然这样,那就调整下返回实体对象的属性类型即可。

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot使用JPA实现查询部分字段

    目录 SpringBoot JPA查询部分字段 自定义简单的查询方法 SpringBoot JPA查询部分字段 用过JPA的都知道,只需要继承JpaRepository 根据Jpa的函数命名规范写出接口中的函数,不需要实现,底层就可以自动解析成各种数据库的sql语句,进行增删改查等操作. 自定义简单的查询方法 如findByUserName,findByUserNameOrEmail(String username, String email)等条件的属性名称与个数要与参数的位置与个数一一对应,

  • springboot jpa之返回表中部分字段的处理详解

    目录 springboot jpa返回表中部分字段 JPA 自定义返回字段 springboot jpa返回表中部分字段 使用springboot jpa操作数据库可以加快我们的开发效率,对于简单的crud操作来说,使用jpa来开发不要太爽,但是说实话对于一些复杂的数据库操做jpa使用起来就不是这么爽了. 在开发中很多时候我们要返回的可能只是数据库表中或某个类中的一部分字段,这个要是用mybatis的话就很简单,直接在sql中select字段就好了,规范一点就数据传输类接一下,偷个懒的话直接用m

  • SpringBoot+JPA 分页查询指定列并返回指定实体方式

    目录 SpringBoot+JPA分页查询指定列并返回指定实体 SpringBoot JPA实现自定义语句分页查询 SpringBoot+JPA分页查询指定列并返回指定实体 用习惯Mybatis,没用过jpa 真是各种踩坑了 脑壳疼,一个分页弄老半天,原来就一句话的事情,唉 先来说说正常的JPA如何操作 实体类对应表来创建,举个例子 @Entity @Table(name = "td_user") public class TdUser extends BaseModel { priv

  • Springboot JPA如何使用distinct返回对象

    目录 JPA如何使用distinct返回对象 JPA自定义返回对象 方法一 方法二 方法三 方法四 JPA如何使用distinct返回对象 package com.frank.jpaBatchSave.repository; import com.frank.jpaBatchSave.entity.Person; import org.springframework.data.jpa.repository.Query; import org.springframework.data.reposi

  • Springboot jpa使用sum()函数返回结果如何被接收

    目录 jpa使用sum()返回结果如何接收 1.需求 2.解决方法一 3.解决方法二 jpa使用count函数和sum函数 方法一 方法二 方法三 jpa使用sum()返回结果如何接收 1.需求 我的需求是统计域名以及域名出现的次数. 之前使用springboot jpa都是把数据库中的表跟实体类绑定,创建继承JpaRepository的接口.如下: @Repository public interface UrlsRepository extends JpaRepository<Urls, S

  • SpringBoot返回Json对象报错(返回对象为空{})

    目录 1 需求描述 2 代码展示 3 原因分析 4 解决方案 5 效果展示 6 结束语 1 需求描述 我们现在要干一个什么事情呢,我们要在浏览器输入一个请求地址,然后我们的后端就给我返回一个User对象即可,并且我希望以Json的格式返回.这个需求很明确,我们先直观的展示一下效果.发送请求: 接受结果: 2 代码展示 行了,明确了需求我们开始整活儿.首先我们老规矩还是先展示一下目录结构(其中标红的文件使我们今天要用到的): 接下来是具体的文件内容首先呢我们展示一下User.java文件 pack

  • springboot jpa 实现返回结果自定义查询

    目录 jpa返回结果自定义查询 第一种方法 第二种方法 使用jpa两张表联查返回自定义实体 1.创建一个SpringBoot空白项目,引入pom依赖 2.application.yml配置文件 3.数据库(有两张表user/address) 4.User.java和Address.java 5.UserDaoRepository.java和AddressDaoRepository.java 6.UserAddressDto.java代码 7.TestController.java jpa 返回结

  • SpringBoot+JPA 分页查询指定列并返回指定实体方式

    目录 SpringBoot JPA分页查询指定列并返回指定实体 实体类对应表来创建,举个例子 SpringBoot JPA实现自定义语句分页查询 1.JPA持久层 InvoiceRepository.java 2.服务层 SpringBoot JPA分页查询指定列并返回指定实体 用习惯Mybatis,没用过jpa 真是各种踩坑了 脑壳疼,一个分页弄老半天,原来就一句话的事情,唉 先来说说正常的JPA如何操作 实体类对应表来创建,举个例子 @Entity @Table(name = "td_use

  • SpringBoot返回对象时,如何将Long类型转换为String

    目录 SpringBoot返回对象将Long类型转换为String 1.自定义ObjectMapper 2.把MappingJackson2HttpMessageConverter 3.定义返回的VO类 4.返回的Long类型id为String类型 Long类型转换为String类型的方法及区别 注意事项 SpringBoot返回对象将Long类型转换为String 1.自定义ObjectMapper /** * 返回Long转换为String * @author Jingly */ publi

  • 使用JPA自定义VO接收返回结果集(unwrap)

    目录 JPA自定义VO接收返回结果集(unwrap) JPA返回自定义VO JPA自定义VO接收返回结果集(unwrap) JPA跟mybitis比较,简单的业务搜索是方便的,但是设计到复杂的SQL搜索时,我们需要自定义SQL. 1.@Query直接写SQL,缺点是无法动态的组装条件 2.JPA的Specification对象动态组装where搜索条件 3.entityManager执行CriteriaBuilder 4.entityManger直接使用createNativeQuery,执行原

  • SpringBoot Jpa 自定义查询实现代码详解

    这篇文章主要介绍了SpringBoot Jpa 自定义查询实现代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 持久层Domain public interface BaomingDao extends JpaRepository<BaomingBean,Integer> { @Query(value = "select distinct t.actid from BaomingBean t where t.belongs=?

随机推荐