Frage

Ich verwende Spring JPA, um alle Datenbankoperationen durchzuführen.Ich weiß jedoch nicht, wie ich bestimmte Spalten aus einer Tabelle in Spring JPA auswählen soll?

Beispielsweise:
SELECT projectId, projectName FROM projects

War es hilfreich?

Lösung

Sie können einstellen nativeQuery = true in der @Query anmerkung von a Repository klasse wie diese:

public static final String FIND_PROJECTS = "SELECT projectId, projectName FROM projects";

@Query(value = FIND_PROJECTS, nativeQuery = true)
public List<Object[]> findProjects();

Beachten Sie jedoch, dass Sie das Mapping selbst durchführen müssen.Es ist wahrscheinlich einfacher, einfach die reguläre zugeordnete Suche wie folgt zu verwenden, es sei denn, Sie benötigen wirklich nur diese beiden Werte:

public List<Project> findAll()

Es lohnt sich wahrscheinlich, sich die Frühlingsdaten anzusehen Dok sowie.

Andere Tipps

Sie können Projektionen aus Spring Data JPA verwenden (Dok).Erstellen Sie in Ihrem Fall eine Schnittstelle:

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

und fügen Sie Ihrem Repository die folgende Methode hinzu

List<ProjectIdAndName> findAll();

Ich mag die Syntax nicht besonders (sie sieht ein bisschen hackig aus...) aber das ist die eleganteste Lösung, die ich finden konnte (es verwendet eine benutzerdefinierte JPQL-Abfrage in der JPA-Repository-Klasse):

@Query("select new com.foo.bar.entity.Document(d.docId, d.filename) from Document d where d.filterCol = ?1")
List<Document> findDocumentsForListing(String filterValue);

Dann müssen Sie natürlich nur einen Konstruktor für bereitstellen Document das akzeptiert docId & filename als Konstruktor args.

In meiner Situation brauche ich nur das JSON-Ergebnis, und das funktioniert bei mir:

public interface SchoolRepository extends JpaRepository<School,Integer> {
    @Query("select s.id, s.name from School s")
    List<Object> getSchoolIdAndName();
}

im Prüfer:

@Autowired
private SchoolRepository schoolRepository;

@ResponseBody
@RequestMapping("getschoolidandname.do")
public List<Object> getSchool() {
    List<Object> schools = schoolRepository.getSchoolIdAndName();
    return schools;
}

In meinem Fall habe ich eine separate Entitätsklasse ohne die nicht erforderlichen Felder erstellt (nur mit den erforderlichen Feldern).

Ordnen Sie die Entität derselben Tabelle zu.Wenn jetzt alle Spalten benötigt werden, verwende ich die alte Entität, wenn nur einige Spalten benötigt werden, verwende ich die Lite-Entität.

beispielsweise.

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

Sie können so etwas erstellen wie :

@Entity
@Table(name = "user")
Class UserLite{
         @Column(name = "id", unique=true, nullable=false)
         int id;
         @Column(name = "name", nullable=false)
         String name;
}

Dies funktioniert, wenn Sie die zu abrufenden Spalten kennen (und dies wird sich nicht ändern).

funktioniert nicht, wenn Sie die Spalten dynamisch festlegen müssen.

Ich denke, der einfache Weg könnte sein, zu verwenden ANFRAGENDSL, das kommt mit den Frühlingsdaten.

Auf Ihre Frage kann die Antwort lauten

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

Der Entitätsmanager kann automatisch verdrahtet werden und Sie werden immer mit Objekten und Klassen arbeiten, ohne die Sprache * QL zu verwenden.

Wie Sie im Link sehen können, scheint die letzte Wahl für mich fast eleganter zu sein, dh DTO zum Speichern des Ergebnisses zu verwenden.Bewerben Sie sich auf Ihr Beispiel, das sein wird:

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

Definieren von ProjectDTO als:

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

Meiner Meinung nach ist das eine großartige Lösung:

interface PersonRepository extends Repository<Person, UUID> {

    <T> Collection<T> findByLastname(String lastname, Class<T> type);
}

und benutze es so

void someMethod(PersonRepository people) {

  Collection<Person> aggregates =
    people.findByLastname("Matthews", Person.class);

  Collection<NamesOnly> aggregates =
    people.findByLastname("Matthews", NamesOnly.class);
}

Mit den neueren Federversionen kann man wie folgt vorgehen:

Wenn Sie keine native Abfrage verwenden, kann dies wie folgt erfolgen:

public interface ProjectMini {
    String getProjectId();
    String getProjectName();
}

public interface ProjectRepository extends JpaRepository<Project, String> { 
    @Query("SELECT p FROM Project p")
    List<ProjectMini> findAllProjectsMini();
}

Mit der nativen Abfrage kann das Gleiche wie folgt gemacht werden:

public interface ProjectRepository extends JpaRepository<Project, String> { 
    @Query(value = "SELECT projectId, projectName FROM project", nativeQuery = true)
    List<ProjectMini> findAllProjectsMini();
}

Für Details überprüfen Sie die Dok

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.

Es ist möglich zu spezifizieren null als Feldwert in nativem 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);

Sie können den folgenden Code in Ihrer Repository-Schnittstellenklasse anwenden.

entityname bedeutet den Namen Ihrer Datenbanktabelle wie Projekte.Und Liste bedeutet, dass Projekt eine Entitätsklasse in Ihren Projekten ist.

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

Sie können JPQL verwenden:

TypedQuery <Object[]> query = em.createQuery(
  "SELECT p.projectId, p.projectName FROM projects AS p", Object[].class);

List<Object[]> results = query.getResultList();

oder Sie können eine native SQL-Abfrage verwenden.

Query query = em.createNativeQuery("sql statement");
List<Object[]> results = query.getResultList();

Native Abfrage verwenden:

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

Sie können die von @jombie vorgeschlagene Antwort verwenden und:

  • platzieren Sie die Schnittstelle in einer separaten Datei außerhalb der Entitätsklasse;
  • verwenden Sie eine native Abfrage oder nicht (die Wahl hing von Ihren Anforderungen ab);
  • nicht überschreiben findAll() methode für diesen Zweck, aber verwenden Sie einen Namen Ihrer Wahl;
  • denken Sie daran, eine zurückzugeben List parametriert mit Ihrer neuen Schnittstelle (z. List<SmallProject>).
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top