webentwicklung-frage-antwort-db.com.de

Wie holt man mit Spring JPA nur ausgewählte Attribute einer Entität?

Ich verwende Spring Boot (1.3.3.RELEASE) und Hibernate JPA in meinem Projekt. Meine Entität sieht so aus:

@Data
@NoArgsConstructor
@Entity
@Table(name = "rule")
public class RuleVO {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "name", length = 128, nullable = false, unique = true)
    private String name;

    @Column(name = "tag", length = 256)
    private String tag;

    @OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<RuleOutputArticleVO> outputArticles;

    @OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<RuleInputArticleVO> inputArticles;
}

Mein Repository sieht so aus:

@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
}

In einigen Fällen muss ich nur id und name - Attribute der Entität RuleVO abrufen. Wie kann ich das erreichen? Ich habe eine Nachricht gefunden, die mit Criteria API und Projektionen machbar sein sollte, aber wie? Vielen Dank im Voraus. Vojtech

9
Vojtech

UPDATE:

Wie mir gesagt wurde, bin ich faul und das kann sehr gut gemacht werden. Daher aktualisiere ich meine Antwort, nachdem ich mich im Internet nach einer richtigen Frage umgesehen habe.

Hier ein Beispiel, wie man nur die IDs und nur die Namen erhält:

@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {

    @Query("SELECT r.id FROM RuleVo r where r.name = :name") 
    List<Long> findIdByName(@Param("name") String name);

    @Query("SELECT r.name FROM RuleVo r where r.id = :id") 
    String findNameById(@Param("id") Long id);
}

Hoffentlich erweist sich dieses Update als hilfreich


Alte Antwort:

Nur das Abrufen der spezifischen Attribute Name/ID ist nicht möglich, da Spring nicht so konzipiert wurde wie die SQL-Datenbank, da Sie immer eine Zeile auswählen, die eine Entität ist.

Was Sie tun können, ist eine Abfrage über die Variablen in der Entität, zum Beispiel:

@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {

    public RuleVo findOneByName(String name);
    public RuleVo findOneByNameOrId(String name, Long id);
    public List<RuleVo> findAllByName(String name);
    // etc, depending on what you want
}

Sie können diese beliebig ändern. Deine Bedürfnisse. Sie können diese Methoden direkt über das autowired Repository aufrufen

Siehe http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ - Abschnitt 5.3 für weitere Optionen und Beispiele

10

Ja, Sie können es mit Projektionen erreichen. Sie haben viele Möglichkeiten, sie anzuwenden:

Wenn Sie ein Upgrade auf Spring Data Hopper durchführen könnten, bietet es eine einfach zu bedienende Unterstützung für Projektionen. Informationen zur Verwendung finden Sie in der Referenzdokumentation .

Andernfalls erstellen Sie zunächst ein DTO mit den Attributen, die Sie laden möchten, etwa:

package org.example;

public class RuleProjection {

    private final Long id;

    private final String name;

    public RuleProjection(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

Natürlich können Sie auch Lombok-Anmerkungen verwenden.

Dann können Sie in den JPQL-Abfragen wie folgt verwenden:

select new org.example.RuleProjection(rule.id, rule.name) from RuleVO rule order by rule.name

Wenn Sie die Verwendung von DTO-Klassennamen in Ihren Abfragen vermeiden möchten, können Sie auch eine eigene Abfragemethode mit QueryDSL implementieren. Mit Spring Data JPA müssen Sie:

  • Erstellen Sie eine neue Schnittstelle mit der neuen Methode. Ex:

    public interface RuleRepositoryCustom {
       public List<RuleProjection> findAllWithProjection();
    }
    
  • Ändern Sie Ihr Repository, um die neue Schnittstelle zu erweitern. Ex:

    public interface RuleRepository extends JpaRepository<RuleVO, Long>, RuleRepositoryCustom {
    ...
    
  • Erstellen Sie eine Implementierung des benutzerdefinierten Repositorys mithilfe der Spring Data JPA QueryDSL-Unterstützung. Sie müssen zuvor die Q-Klassen von QueryDSL mithilfe des Maven-Plugins generieren. Ex:

    public class RuleRepositoryImpl {
    
        public List<RuleProjection> findAllWithProjection() {
            QRuleVO rule = QRuleVO.ruleVO;
            JPQLQuery query = getQueryFrom(rule);     
            query.orderBy(rule.name.asc());
            return query.list(ConstructorExpression.create(RuleProjection.class, rule.id, rule.name));
        }
    }
    
3
Cèsar

Sie können dies tun, indem Sie die @Query-Annotation (HQL) verwenden.

Bitte beachten Sie die folgenden Spring-Dokumente:

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

(Suche nach @Query im Frühlingsdokument)

2
shankarsh15

Sie können auch einen benutzerdefinierten Konstruktor definieren, um bestimmte Spalten mit JPQL abzurufen.

Beispiel:

Ersetzen Sie {javaPackagePath} durch den vollständigen Java-Paketpfad der Klasse Verwendung als Konstruktor in JPQL.

public class RuleVO {
   public RuleVO(Long id, String name) {
    this.id = id;
    this.name = name;
   }
}


@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {

    @Query("SELECT new {javaPackagePath}.RuleVO(r.id, r.name) FROM RuleVo r where r.name = :name") 
    List<RuleVO> findIdByName(@Param("name") String name);
}
1
Abhilekh Singh
interface IdOnly{
    String getId();
}

@Repository
public interface RuleRepository extends JpaRepository<RuleVO, Long> {
    public List<IdOnly> findAllByName(String name);
}

Ich stelle fest, dass dies ein sehr alter Beitrag ist, aber wenn noch jemand nach einer Antwort sucht, probieren Sie es aus. Es hat für mich funktioniert.

0
Pranjal Gore