Я використовую 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. працює бездоганно
У моєму випадку я створив окремий клас сутності без полів, які не є обов'язковими (лише з необхідними полями).
Зіставте об’єкт в одній таблиці. Тепер, коли всі стовпці потрібні, я використовую стару сутність, коли потрібні лише деякі стовпці, я використовую сутність Lite.
напр
@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));
}}
Менеджер об'єктів може бути автоматичним, і ви завжди будете працювати з об'єктом і фразами без використання * 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();
Ви можете застосувати наведений нижче код в класі інтерфейсу вашого сховища.
ім'я сутності означає назву таблиці вашої бази даних, як проекти. А "Список" означає, що проект - клас особи у ваших проектах.
@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>
).