如何透過SqlResultSetMapping和NamedNativeQuery生成DTO?

banq發表於2019-02-12

獲取超出你實際需要的資料容易導致效能損失。使用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 。

原始碼下載

相關文章