Весна JPA выбор конкретных столбцов



Я использую Spring JPA для выполнения всех операций с базой данных. Однако я не знаю, как выбрать определенные столбцы из таблицы в Spring JPA?



например:
SELECT projectId, projectName FROM projects

652   12  

12 ответов:

вы можете установить 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()

вероятно, стоит посмотреть на весенние данные docs как хорошо.

мне не нравится синтаксис особенно (это выглядит немного хаки...) но это самое элегантное решение, которое я смог найти (он использует пользовательский запрос JPQL в классе репозитория JPA):

@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 & filename в качестве конструктора args.

вы можете использовать проекции из весенних данных JPA (doc). В вашем случае создайте интерфейс:

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

и добавить следующий метод в репозиторий

List<ProjectIdAndName> findAll();

в моем случае я создал отдельный класс сущностей без полей, которые не требуются (только поля, которые требуются).

сопоставьте объект с той же таблицей. Теперь, когда все столбцы требуются, я использую старую сущность, когда требуются только некоторые столбцы, я использую облегченную сущность.

например

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

это работает, когда вы знаете столбцы для выборки (и это не собираюсь изменение.)

не будет работать, если вам нужно динамически определить столбцы.

в моей ситуации мне нужен только результат 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;
}

Я думаю, самый простой способ может быть с помощью 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(){....}
}

можно указать null как значение поля в собственном sql.

@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);
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.

вы можете применить приведенный ниже код в своем классе интерфейса репозитория.

entityname означает имя таблицы базы данных, как проекты. И список означает, что проект-это класс сущности в ваших проектах.

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

вы можете использовать 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();

Используя Собственный Запрос:

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

большинство ответов здесь предлагают использовать некоторые варианты собственного SQL-запроса. Однако, используя встроенные spring-data jpa, мы также можем добиться этого:

вам просто нужно использовать следующую сигнатуру метода в классе репозитория.

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

в зависимости от схемы он может возвращать список или один экземпляр. Этот подход может быть применен к одной или нескольким столбцам, как показано выше.

для вашего примера это может быть что-то например:

Project findByProjectIdAndProjectNameIn(long projectId, String projectName);

projectId, projectName

Comments

    Ничего не найдено.