Spring JPA选择特定列

时间:2014-02-25 07:25:26

标签: java jpa spring-data-jpa

我正在使用Spring JPA来执行所有数据库操作。但是我不知道如何从Spring JPA中的表中选择特定的列?

例如:
SELECT projectId, projectName FROM projects

16 个答案:

答案 0 :(得分:110)

我特别不喜欢语法(看起来有点像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);

然后当然,你只需要提供一个接受docId&amp;的Document的构造函数。 filename作为构造函数args。

答案 1 :(得分:99)

您可以使用Spring Data JPA (doc)中的投影。在您的情况下,创建接口:

interface ProjectIdAndName{
    String getId();
    String getName();
}

并将以下方法添加到您的存储库

List<ProjectIdAndName> findAll();

答案 2 :(得分:49)

您可以在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数据docs

答案 3 :(得分:13)

在我的情况下,我只需要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;
}

答案 4 :(得分:12)

在我的情况下,我创建了一个单独的实体类,没有不需要的字段(仅限于需要的字段)。

将实体映射到同一个表。 现在当需要所有列时,我使用旧实体,当只需要一些列时,我使用lite实体。

e.g。

@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;
}

当你知道要获取的列时(这不会改变),这是有效的。

如果您需要动态决定列,

无法工作。

答案 5 :(得分:7)

我想简单的方法可能就是使用Spring数据附带的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)); 
}}

实体管理器可以是自动连接的,你总是可以使用对象和clases而不使用* 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(){....}
}

答案 6 :(得分:3)

我认为这是一个很好的解决方案:

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);
}

答案 7 :(得分:2)

Using Spring Data JPA there is a provision to select specific columns from database


---- In DAOImpl ----
@Override
    @Transactional
    public List<Employee> getAllEmployee() throws Exception {
    LOGGER.info("Inside getAllEmployee");
    List<Employee> empList = empRepo.getNameAndCityOnly();
    return empList;
    }

---- In Repo ----
public interface EmployeeRepository extends CrudRepository<Employee,Integer> {
    @Query("select e.name, e.city from Employee e" )
    List<Employee> getNameAndCityOnly();
}

It worked 100% in my case.
Thanks.

答案 8 :(得分:2)

可以在本机sql中将null指定为字段值。

@Query(value = "select p.id, p.uid, p.title, null as documentation, p.ptype " +
            " from projects p " +
            "where p.uid = (:uid)" +
            "  and p.ptype = 'P'", nativeQuery = true)
Project findInfoByUid(@Param("uid") String uid);

答案 9 :(得分:2)

您可以在存储库接口类中应用以下代码。

  

entityname表示您的数据库表名称与项目类似。   而List表示Project是您项目中的Entity类。

@Query(value="select p from #{#entityName} p where p.id=:projectId and p.projectName=:projectName")

List<Project> findAll(@Param("projectId") int projectId, @Param("projectName") String projectName);

答案 10 :(得分:1)

您可以使用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();

答案 11 :(得分:1)

使用较新的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();
}

有关详细信息,请检查docs

答案 12 :(得分:0)

使用原生查询:

Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();

答案 13 :(得分:0)

这里的大多数答案都建议使用本机SQL查询的某些变体。但是,使用内置的spring-data jpa也可以实现它:

您只需要在Repository类中使用以下方法签名。

ModelClass findBy$Column_1And$Column_2In(Object $col1Value, Object $col2Value );

根据架构,它可以返回列表或单个实例。如上所述,该方法可以应用于单列或多列。

以您的示例为例:

Project findByProjectIdAndProjectNameIn(long projectId, String projectName);

projectId,projectName

答案 14 :(得分:0)

您可以使用@jombie建议的答案,以及:

  • 将接口放置在实体类之外的单独文件中;
  • 是否使用本机查询(选择取决于您的需求);
  • 请勿为此目的覆盖findAll()方法,而应使用您选择的名称;
  • 记住要返回一个用新界面(例如List)参数化的List<SmallProject>

答案 15 :(得分:0)

public static final String FIND_PROJECTS = "select ac_year_id,ac_year from tbl_au_academic_year where ac_year_id=?1";

    @Query(value = FIND_PROJECTS, nativeQuery = true)
    public  List<Object[]> findByAcYearId(Integer ac_year_id);

这对我有用