Spring JPA wybór konkretnych kolumn
Używam Spring JPA do wykonywania wszystkich operacji bazodanowych. Jednak nie wiem, jak wybrać konkretne kolumny z tabeli na wiosnę JPA?
Na przykład:SELECT projectId, projectName FROM projects
12 answers
Możesz ustawić nativeQuery = true
w adnotacji @Query
z klasy Repository
w następujący sposób:
public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";
@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();
Zauważ, że będziesz musiał zrobić mapowanie samodzielnie. Prawdopodobnie łatwiej jest po prostu użyć zwykłego wyszukiwania mapowanego w ten sposób, chyba że naprawdę potrzebujesz tylko tych dwóch wartości:
public List<Project> findAll()
Warto też przyjrzeć się źródłowym danym docs.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 18:34:17
Nie podoba mi się składnia szczególnie (wygląda trochę chwiejnie...), ale jest to najbardziej eleganckie rozwiązanie, jakie udało mi się znaleźć (używa niestandardowego zapytania JPQL w klasie repozytorium 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);
Wtedy, oczywiście, wystarczy podać konstruktor dla dokumentu, który akceptuje docId & filename jako konstruktor args.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-12 21:34:23
Możesz użyć prognoz z danych źródłowych JPA (doc). W Twoim przypadku utwórz interfejs:
interface ProjectIdAndName{
String getId();
String getName();
}
I dodaj następującą metodę do repozytorium
List<ProjectIdAndName> findAll();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-02 14:07:56
W moim przypadku utworzyłem osobną klasę encji bez pól, które nie są wymagane (tylko z polami, które są wymagane).
Mapuj obiekt do tej samej tabeli. Teraz, gdy wszystkie kolumny są wymagane, używam starego encji, gdy tylko niektóre kolumny są wymagane, używam encji lite.
Np.
@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;
}
Możesz utworzyć coś w stylu:
@Entity
@Table(name = "user")
Class UserLite{
@Column(name = "id", unique=true, nullable=false)
int id;
@Column(name = "name", nullable=false)
String name;
}
To działa, gdy znasz kolumny do pobrania(i to się nie zmieni).
Nie zadziała, jeśli trzeba dynamicznie decydować o kolumnach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-07 10:50:43
W mojej sytuacji potrzebuję tylko wyniku json, a to działa dla mnie:
public interface SchoolRepository extends JpaRepository<School,Integer> {
@Query("select s.id, s.name from School s")
List<Object> getSchoolIdAndName();
}
In Controller:
@Autowired
private SchoolRepository schoolRepository;
@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
List<Object> schools = schoolRepository.getSchoolIdAndName();
return schools;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-10 23:19:05
Myślę, że łatwym sposobem może być użycie QueryDSL , które pochodzi z Spring-Data.
Używając do twojego pytania odpowiedź może być
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));
}}
Menedżer encji może być Autowirowany i zawsze będziesz pracować z obiektami i klasami bez użycia języka *QL.
Jak widać w linku ostatni wybór wydaje się, prawie dla mnie, bardziej elegancki, czyli używanie DTO do przechowywania wyniku. Zastosuj do swojego przykładu, który będzie:
JPAQuery query = new JPAQuery(entityManager);
QProject project = QProject.project;
List<ProjectDTO> dtos = query.from(project).list(new QProjectDTO(project.projectId, project.projectName));
Definiowanie ProjectDTO jako:
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(){....}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-15 08:49:31
Można określić null
jako wartość pola w natywnym 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-08 19:36:12
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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 07:51:24
Możesz zastosować poniższy kod w klasie interfejsu repozytorium.
Entityname oznacza nazwę tabeli bazy danych, podobnie jak projekty. A lista oznacza, że projekt jest klasą encji w twoich projektach.
@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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-12 10:59:42
Możesz użyć JPQL:
TypedQuery <Object[]> query = em.createQuery(
"SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);
List<Object[]> results = query.getResultList();
Lub możesz użyć natywnego zapytania sql.
Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 07:39:08
Using Native Query:
Query query = entityManager.createNativeQuery("SELECT projectId, projectName FROM projects");
List result = query.getResultList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 08:39:53
Większość odpowiedzi sugeruje użycie pewnej odmiany natywnego zapytania SQL. Jednak przy użyciu wbudowanego spring-data jpa również możemy to osiągnąć:
Musisz tylko użyć następującej metody w klasie repozytorium.
ModelClass findBy$Column_1And$Column_2In(Object $col1Value, Object $col2Value );
W zależności od schematu może zwrócić listę lub pojedynczą instancję. Podejście to można zastosować do pojedynczych lub wielu kolumn, jak pokazano powyżej.
Dla Twojego przykładu może to być coś w stylu:
Project findByProjectIdAndProjectNameIn(long projectId, String projectName);
ProjectId, projectName
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-04 08:23:34