Я использую Spring JPA для выполнения всех операций с базой данных. Однако я не знаю, как выбрать конкретные столбцы из таблицы в Spring JPA?
Например:
SELECT projectId, projectName FROM projects
Я использую 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 .
FIND_PROJECTS
) с value
именем атрибута (следовательно, если бы это был мой код, я должен был бы написать его как @Query(value = FIND_PROJECTS, nativeQuery = true)
и т. Д.
Вы можете использовать прогнозы из Spring Data JPA (doc) . В вашем случае создайте интерфейс:
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
как аргументы конструктора.
В моей ситуации мне нужен только результат 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;
}
Это работает, когда вы знаете столбцы для извлечения (и это не изменится).
не будет работать, если вам нужно динамически выбирать столбцы.
Я предполагаю, что самый простой способ - использовать QueryDSL , который поставляется с Spring-Data.
Используя на ваш вопрос ответ может быть
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));
}}
Менеджер сущностей может быть Autowired, и вы всегда будете работать с объектом и предложениями без использования языка * 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();
Вы можете применить приведенный ниже код в своем классе интерфейса репозитория.
entityname означает имя вашей таблицы базы данных как проекты. И Список означает, что Проект является классом 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);
Использование собственного запроса:
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();
Вы можете использовать ответ, предложенный @jombie, и:
findAll()
метод для этой цели, но используйте имя по вашему выбору;List
параметризованный с вашим новым интерфейсом (например List<SmallProject>
).