关于使用@NameNativeQuery和@SqlResultSetMapping自定义复杂查询
@NameNativeQuery
最近在开发一个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联合主键类定义方式相同
更多推荐
所有评论(0)