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

最近在开发一个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联合主键类定义方式相同

猜你喜欢

转载自blog.csdn.net/Maxiao1204/article/details/129071974
今日推荐