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