获取超出你实际需要的数据容易导致性能损失。使用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 。
源码下载