我们从数据库中提取数据,才能确定应用程序的执行方式。为了构建最佳的提取计划,我们需要了解每种提取类型。直接获取数据是最简单的,无需编写任何显式SQL查询语句,并且在我们知道实体主键时非常有用。
如何通过通过Spring Data EntityManager和Hibernate Session示例直接获取?
关键点:
通过Spring Data直接获取, findById()
通过EntityManager直接获取 EntityManager#find()
通过Hibernate直接获取 Session#get()
源代码可以在这里找到
通过Spring Data Projections获取DTO
获取比所需数据更多的数据是导致性能损失的最常见问题之一。获取实体而无意修改它们也是一个坏主意。我们可以通过Spring Data Projections(DTO)仅从数据库中获取所需的数据。
假设对于实体User我们只想提取其中的name和city,做成一个DTO对象返回,实体User的代码:
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String surname;
private String city;
private String country;
private long ssn;
private int age;
关键点:
编写一个包含getter的接口(投影),仅用于应从数据库中提取的列
public interface UserNameAndCity {
String getName();
String getCity();
}
写一个返回的正确查询List:
@Repository
public interface UserRepository extends JpaRepository {
@Transactional(readOnly = true)
List findFirst2BySurname(String surname);
}
如果可能,限制返回的行数(例如,via LIMIT)。在这里,我们可以使用Spring Data存储库基础结构中内置的查询构建器机制
调用:
List users = userRepository.findFirst2BySurname("Francisco");
logger.info(() -> "Number of users:" + users.size());
for (UserNameAndCity user : users) {
logger.info(() -> "User:" + user.getName() + ", " + user.getCity());
}
源代码可以在这里找到