Вопрос

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

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

Это было полезно?

Решение

Вы можете установить 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 документы также.

Другие советы

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

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

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

List<ProjectIdAndName> findAll();
.

Мне не нравится синтаксис, особенно (он выглядит немного хакери ...) Но это самое элегантное решение, которое я смог найти (он использует пользовательский запрос 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);
.

Тогда, конечно, вам просто нужно предоставить конструктор для 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;
}
.

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

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

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

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

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

Я думаю, что простой способ может быть использован, используя 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 Language.

Как вы можете увидеть в ссылке, последний выбор кажется, почти для меня, более элегантный, то есть, используя DTO для хранения результата.Применить к вашему примеру, который будет:

JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
.

Определение проекта AS:

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(){....}
}
.

На мой взгляд, это отличное решение:

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

с более новыми версиями весны можно сделать следующим образом:

Если не используйте нативный запрос, это может сделать, как показано ниже:

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

Для деталей Проверьте флажок Документы

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.
.

Можно указать генеракодицетагкод в качестве значения поля в нативном 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);
.

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

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

Вы можете использовать ответ, предложенный @jombie, и:

  • поместите интерфейс в отдельный файл, вне класса сущности;
  • использовать нативный запрос или нет (выбор зависел от ваших потребностей);
  • не переопределяй findAll() метод для этой цели, но используйте имя по вашему выбору;
  • не забудьте вернуть List параметризованный вашим новым интерфейсом (например. List<SmallProject>).
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top