jpa2.2.10 Query 使用entityManager构建sql查询返回Dto,实体类和Dto中都有set<实体类>集合,不使用xml配置,不使用for进行转换,写个详细的示例
时间: 2023-06-10 15:03:29 浏览: 163
好的,针对您的问题,我可以提供以下示例代码:
实体类 User.java:
```java
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Address> addresses;
// getters and setters
}
```
实体类 Address.java:
```java
@Entity
@Table(name = "address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "street")
private String street;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
// getters and setters
}
```
Dto 类 UserDto.java:
```java
public class UserDto {
private Long id;
private String name;
private Set<AddressDto> addresses;
// getters and setters
}
```
Dto 类 AddressDto.java:
```java
public class AddressDto {
private Long id;
private String street;
// getters and setters
}
```
然后,在查询中可以使用 entityManager 创建 NativeQuery,并使用 JPA 的构造函数表达式进行转换,代码示例如下:
```java
String sql = "SELECT u.id AS id, u.name AS name, a.id AS address_id, a.street AS street " +
"FROM user u " +
"LEFT JOIN address a ON u.id = a.user_id " +
"WHERE u.id = :userId";
List<UserDto> userDtos = entityManager.createNativeQuery(sql, "userDtoMapping")
.setParameter("userId", userId)
.getResultList();
```
其中,“userDtoMapping” 是在 EntityManagerFactory 中配置的实体映射关系,示例代码如下:
```java
Map<String, Class<?>> entityClassMap = new HashMap<>();
entityClassMap.put("userDtoMapping", UserDto.class);
entityClassMap.put("addressDtoMapping", AddressDto.class);
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(false);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan("com.example.domain");
factoryBean.setMappingResources("META-INF/orm.xml");
factoryBean.setMappingClasses(User.class, Address.class);
factoryBean.setJpaPropertyMap(properties);
factoryBean.setEntityNameResolvers(Collections.singletonList(new AnnotationMetadataEntityNameResolver()));
factoryBean.setPersistenceUnitName("unitName");
factoryBean.setEntityMappings(createEntityMappings(entityClassMap));
private static InputStream createEntityMappings(Map<String, Class<?>> entityClassMap) {
StringWriter writer = new StringWriter();
XStream xStream = new XStream(new DomXmlWriterFactory());
xStream.autodetectAnnotations(true);
xStream.alias("entity-mappings", Object.class);
xStream.alias("entity", Object.class);
xStream.alias("field", Object.class);
xStream.useAttributeFor(Field.class, "name");
xStream.aliasField("name", Field.class, "name");
xStream.aliasField("column-name", Field.class, "columnName");
xStream.aliasField("entity-class", Object.class, "entityClass");
xStream.aliasField("class", Object.class, "entityClass");
xStream.aliasField("entity-name", Object.class, "entityName");
xStream.aliasField("table", Object.class, "tableName");
xStream.aliasField("id-class", Object.class, "idClass");
xStream.aliasField("id", Object.class, "idFieldName");
xStream.aliasField("sequence-generator", Object.class, "sequenceGenerator");
xStream.aliasField("table-generator", Object.class, "tableGenerator");
xStream.aliasField("query", Object.class, "query");
entityClassMap.forEach((mapping, clazz) -> {
xStream.addImplicitMap(Field.class, "fields", "field", Field.class);
xStream.useAttributeFor(AddressDto.class, "id");
xStream.useAttributeFor(AddressDto.class, "street");
xStream.alias(mapping, EntityMappings.class);
xStream.alias(mapping + "-entity", Entity.class);
xStream.alias(mapping + "-field", Field.class);
EntityMappings entityMappings = new EntityMappings();
Entity entity = new Entity();
entity.setEntityClass(clazz.getName());
Reflections fieldReflections = new Reflections(clazz);
Set<Field> fields = fieldReflections.getFieldsAnnotatedWith(Column.class).stream()
.map(field -> {
Column column = field.getAnnotation(Column.class);
Field f = new Field();
f.setName(field.getName());
f.setColumnName(column.name());
return f;
})
.collect(Collectors.toSet());
entity.setFields(fields);
entityMappings.addEntity(entity);
try {
xStream.toXML(entityMappings, writer);
} catch (Exception e) {
// handle exception
}
});
return new ByteArrayInputStream(writer.toString().getBytes());
}
```
这样,使用 JPA 构建 SQL 查询,并将结果转换为 Dto 对象集合,便不需要手动遍历集合进行类型转换了。
阅读全文