Recently, I am developing a demo. When doing a query, it will involve the association of many tables. If you directly use the hql statement provided by jpa, the efficiency will be very low and you need to prepare a lot of entities, so I decided to use native sql and then customize it. A vo way to achieve, the first method I thought of is:
@Query(value = "....", nativeQuery = true)
In this way, you need to inject the queried data into vo, prepare vo, and modify the native sql statement
@Query(value = "select new ...vo.*Vo(...) from ....",nativeQuery = true) There is a
problem at this time, this method cannot be used to inject into the native sql query process in vo.
Check the information on the Internet and see that @NameNativeQuery and @SqlResultSetMapping are used in combination to save the custom query results in the custom Vo. @NamedNativeQuery is similar to the native query mentioned above and has the same function. @SqlResultSetMapping is for the result set and A mapping of attributes in Vo, code
@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;
}
The resultSetMapping attribute in @namedNativeQuery points to @SqlResultSetMapping, and then defines a Reponsitory. The method name in the reponsitory corresponds to the name in @namedNativeQuery. Note that the name name must be in the form of the current Vo. method name. You can query through the following code Output data:
List<TestEntity> test();
In addition, in Vo, the @Id annotation must be used to indicate the primary key. Vo must not contain a constructor without parameters. If a constructor with parameters is added, a constructor without parameters must be added.
The primary key queried is a joint primary key. Many information on the Internet say to use IdClass (*PrimaryKey.class) plus multiple @Id annotations. When I use this method, I keep reporting errors and cannot find the corresponding field, and then pass Use the following method to solve it perfectly
@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;
The joint primary key class is defined in the same way as the Jpa joint primary key class