获取超出你实际需要的数据容易导致性能损失。使用DTO可以让我们只提取所需的数据。在这里我们展示依赖SqlResultSetMapping,NamedNativeQuery和EntityManager实现DTO。
假设需要从实体Car中获取name和color两项数据的CarDto,Car代码如下,在其中使用了注释@SqlResultSetMapping,@NamedNativeQuery:
@NamedNativeQuery(
name="CarDto",
query="select name, color from car",
resultSetMapping="CarDto"
)
@SqlResultSetMapping(
name="CarDto",
classes=@ConstructorResult(
targetClass=CarDto.class,
columns={
@ColumnResult(name="name"),
@ColumnResult(name="color")
}
)
)
@Entity
@Table(name = "car")
public class Car implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String engine;
private String color;
|
CarDto代码:
public class CarDto implements Serializable {
private static final long serialVersionUID = 1L;
private final String name;
private final String color;
public CarDto(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
@Override
public String toString() {
return "CarDto{" + "name=" + name + ", color=" + color + '}';
}
}
|
第二步,编制DTO调用EntityManager的createNameQuery返回CarDto的List:
@Repository
@Transactional
public class Dao<T, ID extends Serializable> implements GenericDao<T, ID> {
@PersistenceContext
private EntityManager entityManager;
@Override
public <S extends T> S persist(S entity) {
Objects.requireNonNull(entity, "Cannot persist a null entity");
entityManager.persist(entity);
return entity;
}
@Transactional(readOnly=true)
public List<CarDto> fetchCars() {
Query query = entityManager.createNamedQuery("CarDto");
List<CarDto> result = query.getResultList();
return result;
}
protected EntityManager getEntityManager() {
return entityManager;
}
}
Service调用:
|
@Service
public class CarService {
private final Dao dao;
public CarService(Dao dao) {
this.dao = dao;
}
public List<CarDto> fetchCars() {
return dao.fetchCars();
}
}
|
也可以使用Spring data project投影实现获取DTO,参考https://www.jdon.com/51628 。
源码下载