如何通过javax.persistence.Tuple和JPQL提取DTO?

19-02-13 banq
              

从实体中获取DTO数据,也就是从DDD聚合中获取DDD值对象有多种方式,如果我们不使用DTO方式,直接返回完整实体聚合,容易导致性能损失,使用DTO可以让我们只提取所需的数据。在这个应用程序中,我们展示如何依赖于javax.persistence.Tuple和JPQL生成DTO。点击#DTO标签可获得更多生成DTO的方式。

主要方式:

编制自己的Dao调用EntityManager.createQuery(),返回java.persistence.Tuple类型:

@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<Tuple> fetchCars() {
        List<Tuple> result = entityManager
                .createQuery(
                        "select c.name as name, c.color as color from Car c", Tuple.class
                ).getResultList();

        return result;
    }

    protected EntityManager getEntityManager() {
        return entityManager;
    }
}

在服务中调用:

@Service
public class CarService {

    private final Dao dao;

    public CarService(Dao dao) {
        this.dao = dao;
    }

    public List<Tuple> fetchCars() {
        return dao.fetchCars();
    }
}

客户端调用:

List<Tuple> cars = carService.fetchCars();
            
cars.forEach((e) -> logger.info(() -> "Car: " + e.get("name") + "," + e.get("color")));

源码下载