关于使用@NameNativeQuery和@SqlResultSetMapping自定义复杂查询

2 篇文章 0 订阅
2 篇文章 0 订阅

最近在开发一个demo,在做一条查询的的时候会涉及到很多张表的关联,如果直接使用jpa提供的hql语句的话势必效率很低而且需要准备很多实体,所以决定采用使用原生sql然后自定义一个vo的方式实现,首先我想到的方法是:

@Query(value = ".....",nativeQuery = true)
使用这种方式需要将查询出来的数据注入vo中,准备好vo,修改原生sql语句

@Query(value = "select new ...vo.*Vo(...) from ....",nativeQuery = true)
这个时候出现了问题,在原生sql查询过程中不能使用这种方式注入到vo中。

在网上查资料查资料看到了@NameNativeQuery和@SqlResultSetMapping结合使用来将自定义的查询结果保存到自定义的Vo中,@NamedNativeQuery和上面提到原生查询类似,功能相同,@SqlResultSetMapping是对结果集和Vo中属性的一个映射,代码

@Entity
@NamedNativeQuery(
        name = "TestVo.test",
        query = "SELECT id,name FROM test",
        resultSetMapping = "test")
@SqlResultSetMapping(
        name="test",
        entities = {
                @EntityResult(entityClass = TestVo.class,
                fields = {
                        @FieldResult(name = "id",column = "id"),
                        @FieldResult(name = "name",column = "name")
                })
        }
)
public class TestVo {
    @Id
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

@namedNativeQuery中resultSetMapping属性指向@SqlResultSetMapping,然后定义一个Reponsitory,reponsitory中的方法名和@namedNativeQuery中的name相对应,注意name命名必须是“当前所在Vo.方法名的形式”通过下面这段代码就能查询出数据:

List<TestEntity> test();

另外在Vo中必须要通过@Id注解来指明主键,Vo中不能必须含有不带参数的构造函数,如果添加了带参数的构造函数必须再添加一个不带参数的构造函数。

查询的出来的主键是联合主键,网上很多资料说使用IdClass(*PrimaryKey.class)加上多个@Id注解的形式,我在使用这种方式时一直报错找不到对应的栏位,然后通过使用下面这种方式完美解决

@Entity
@NamedNativeQuery(
        name = "TestEntity.test",
        query = "SELECT id1,id2,name FROM test",
        resultSetMapping = "test")
@SqlResultSetMapping(
        name="test",
        entities = {
                @EntityResult(entityClass = TestEntity.class,
                fields = {
                        @FieldResult(name = "id.id1",column = "id1"),
                        @FieldResult(name = "id.id2",column = "id2"),
                        @FieldResult(name = "name",column = "name")
                })
        }
)
public class TestEntity {
    @Id
    private TestPrimaryKey id;
    private String name;


联合主键类和Jpa联合主键类定义方式相同

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`@SqlResultSetMapping` 注解用于定义将 SQL 查询结果映射到实类、构造函数或 DTO(数据输对象)类的规则。它提了灵活的方式来处理复杂查询的结果映射。 下面是一个使用 `@SqlResultSetMapping` 注解的示例: ```java @Entity @SqlResultSetMapping( name = "EmployeeDepartmentMapping", classes = { @ConstructorResult( targetClass = EmployeeDepartmentDto.class, columns = { @ColumnResult(name = "employee_name", type = String.class), @ColumnResult(name = "department_name", type = String.class) } ) } ) @NamedNativeQuery( name = "getEmployeeDepartment", query = "SELECT e.name AS employee_name, d.name AS department_name FROM employee e JOIN department d ON e.department_id = d.id", resultSetMapping = "EmployeeDepartmentMapping" ) public class Employee { // ... } ``` 在上面的示例中,我们定义了一个名为 "EmployeeDepartmentMapping" 的 `@SqlResultSetMapping`,它将查询结果映射到 `EmployeeDepartmentDto` 类。`EmployeeDepartmentDto` 类是一个简单的 DTO 类,它包含了 `employee_name` 和 `department_name` 字段。 然后,我们使用 `@NamedNativeQuery` 注解来定义一个原生 SQL 查询,并指定了 `resultSetMapping` 为 "EmployeeDepartmentMapping",以将查询结果映射到 `EmployeeDepartmentDto` 类。 接下来,我们来看一下 `EmployeeDepartmentDto` 类的定义: ```java public class EmployeeDepartmentDto { private String employeeName; private String departmentName; public EmployeeDepartmentDto(String employeeName, String departmentName) { this.employeeName = employeeName; this.departmentName = departmentName; } // Getter and Setter methods } ``` 在上面的示例中,`EmployeeDepartmentDto` 类有一个包含两个参数的构造函数,与 `@SqlResultSetMapping` 注解中定义的字段一一对应。 通过以上配置,当执行 `getEmployeeDepartment` 查询时,JPA 将根据 `@SqlResultSetMapping` 的配置,将查询结果映射到 `EmployeeDepartmentDto` 类中的字段。 请注意,`@SqlResultSetMapping` 注解还支持其他的配置选项,例如使用 `entities` 属性将结果映射到实体类,或者使用 `columns` 属性将结果映射到构造函数参数中。你可以根据实际情况进行调整和配置。 总结来说,`@SqlResultSetMapping` 注解提供了一种强大的方式来定义 SQL 查询结果的映射规则,使得我们可以更灵活地处理复杂查询的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值