我正在使用Spring JPA执行所有数据库操作。但是我不知道如何从Spring JPA的表中选择特定的列?
例如:
SELECT projectId, projectName FROM projects
我正在使用Spring JPA执行所有数据库操作。但是我不知道如何从Spring JPA的表中选择特定的列?
例如:
SELECT projectId, projectName FROM projects
Answers:
您可以从这样的类nativeQuery = true
中在@Query
注释中进行设置Repository
:
public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";
@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();
注意,您将不得不自己进行映射。像这样使用常规映射查找可能会更容易,除非您确实只需要这两个值:
public List<Project> findAll()
也许也值得看一下Spring数据文档。
FIND_PROJECTS
用value
属性名称来限定第一个属性(在上方)(因此,如果这是我的代码,则必须将其写为@Query(value = FIND_PROJECTS, nativeQuery = true)
,等等。)
您可以使用Spring Data JPA (doc)中的投影。在您的情况下,请创建接口:
interface ProjectIdAndName{
String getId();
String getName();
}
并将以下方法添加到您的存储库
List<ProjectIdAndName> findAll();
我不特别喜欢这种语法(看起来有点hacky ...),但这是我能够找到的最优雅的解决方案(它在JPA储存库类中使用了自定义JPQL查询):
@Query("select new com.foo.bar.entity.Document(d.docId, d.filename) from Document d where d.filterCol = ?1")
List<Document> findDocumentsForListing(String filterValue);
然后,当然,您只需要提供一个Document
接受docId
&filename
作为构造函数args的构造函数即可。
在我的情况下,我只需要json结果,这对我有用:
public interface SchoolRepository extends JpaRepository<School,Integer> {
@Query("select s.id, s.name from School s")
List<Object> getSchoolIdAndName();
}
在控制器中:
@Autowired
private SchoolRepository schoolRepository;
@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
List<Object> schools = schoolRepository.getSchoolIdAndName();
return schools;
}
Object
使用mpr描述的自定义界面替换。完美无瑕的作品
在我的情况下,我创建了一个单独的实体类,其中没有不需要的字段(仅带有必需的字段)。
将实体映射到同一张表。现在,当需要所有列时,我使用旧实体,而当只需要某些列时,我使用精简实体。
例如
@Entity
@Table(name = "user")
Class User{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
@Column(name = "address", nullable=false)
Address address;
}
您可以创建类似以下内容:
@Entity
@Table(name = "user")
Class UserLite{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
}
当您知道要提取的列(并且不会改变)时,此方法有效。
如果您需要动态确定列,将无法正常工作。
我想简单的方法可能是使用Spring-Data附带的QueryDSL。
使用您的问题的答案可以是
JPAQuery query = new JPAQuery(entityManager);
List<Tuple> result = query.from(projects).list(project.projectId, project.projectName);
for (Tuple row : result) {
System.out.println("project ID " + row.get(project.projectId));
System.out.println("project Name " + row.get(project.projectName));
}}
实体管理器可以自动装配,并且您始终可以使用对象和类而不使用* QL语言。
正如您在链接中看到的那样,对于我来说,最后的选择似乎更为优雅,那就是使用DTO存储结果。适用于您的示例将是:
JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
将ProjectDTO定义为:
class ProjectDTO {
private long id;
private String name;
@QueryProjection
public ProjectDTO(long projectId, String projectName){
this.id = projectId;
this.name = projectName;
}
public String getProjectId(){ ... }
public String getProjectName(){....}
}
使用较新的Spring版本,可以执行以下操作:
如果不使用本机查询,则可以执行以下操作:
public interface ProjectMini {
String getProjectId();
String getProjectName();
}
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query("SELECT p FROM Project p")
List<ProjectMini> findAllProjectsMini();
}
使用本机查询可以完成以下操作:
public interface ProjectRepository extends JpaRepository<Project, String> {
@Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
List<ProjectMini> findAllProjectsMini();
}
有关详细信息,请检查文档
我认为这是一个很好的解决方案:
interface PersonRepository extends Repository<Person, UUID> {
<T> Collection<T> findByLastname(String lastname, Class<T> type);
}
像这样使用
void someMethod(PersonRepository people) {
Collection<Person> aggregates =
people.findByLastname("Matthews", Person.class);
Collection<NamesOnly> aggregates =
people.findByLastname("Matthews", NamesOnly.class);
}
使用Spring Data JPA,可以从数据库中选择特定的列
----在DAOImpl中----
@Override
@Transactional
public List<Employee> getAllEmployee() throws Exception {
LOGGER.info("Inside getAllEmployee");
List<Employee> empList = empRepo.getNameAndCityOnly();
return empList;
}
----在回购区----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
@Query("select e.name, e.city from Employee e" )
List<Employee> getNameAndCityOnly();
}
在我的情况下,它的工作效率为100%。谢谢。
您可以使用JPQL:
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
或者您可以使用本机sql查询。
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();