2014-07-12 21 views
26

È possibile selezionare, ad esempio, solo le proprietà A e B di un oggetto che utilizza una query JPA senza utilizzare query di criteri?Domanda JPA che seleziona solo colonne specifiche senza utilizzare la query criteri?

Per selezionare tutte le proprietà che avevo appena fare qualcosa di simile:

SELECT i FROM ObjectName i WHERE i.id = 10 

Ma ho un oggetto con molti immobili in un sistema legacy, e desidera selezionare solo alcuni, anche se io sono saper selezionare diverse proprietà è in genere veloce.

Ciò è possibile senza utilizzare query di criteri?

Grazie!

+0

ERRm, si può fare qualsiasi cosa con JPQL basato sulle stringhe come si può con i criteri. Non ho idea del motivo per cui qualcuno avrebbe pensato diversamente. –

+0

Le proiezioni nei dati di primavera possono essere utilizzate per ottenere lo stesso risultato. –

risposta

58

Sì, come in SQL pianura è possibile specificare il tipo di proprietà che si desidera selezionare:

SELECT i.firstProperty, i.secondProperty FROM ObjectName i WHERE i.id=10 

L'esecuzione di questa query restituirà un elenco di Object [], in cui ogni matrice contiene le proprietà selezionate di uno oggetto.

Un altro modo è quello di avvolgere le proprietà selezionate in un oggetto personalizzato ed eseguirlo in un TypedQuery:

String query = "SELECT NEW CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=10"; 
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class); 
List<CustomObject> results = typedQuery.getResultList(); 

Esempi possono essere trovati in this articolo.

+2

Quindi ho bisogno di un tipo di pojo per lo stesso tavolo? uno per ogni esigenza? non posso usare solo un oggetto per tutti, lasciando alcuni campi nulli? –

+0

qual è l'alternativa a TypedQuery? Devo lavorare su jpa 1.0. Non c'è una query scritta laggiù. –

+0

@AndreaScarafoni, puoi avere costruttori multipli sulla stessa classe e usarlo per ogni caso. –

10

Si può usare qualcosa di simile:

List<Object[]> list = em.createQuery("SELECT p.field1, p.field2 FROM Entity p").getResultList(); 

allora si può scorrere su di esso:

for (Object[] obj : list){ 
    System.out.println(obj[0]); 
    System.out.println(obj[1]); 
} 

MA se si dispone di un solo campo nella query, si ottiene una lista di digita non da Object []

0

Sì, è possibile. Tutto quello che devi fare è cambiare la tua query in qualcosa come SELECT i.foo, i.bar FROM ObjectName i WHERE i.id = 10. Il risultato della query sarà un List di matrice di Object. Il primo elemento di ciascun array è il valore di i.foo e il secondo elemento è il valore i.bar. Vedere la sezione pertinente di JPQL reference.

6

Ottima risposta! Ho una piccola aggiunta. Per quanto riguarda questa soluzione:

TypedQuery<CustomObject> typedQuery = em.createQuery(query , String query = "SELECT NEW CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=100"; 
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class); 
List<CustomObject> results = typedQuery.getResultList();CustomObject.class); 

Per evitare un errore di classe non trovato, è sufficiente inserire il nome completo del pacchetto. Supponendo org.company.directory è il nome del pacchetto di CustomObject:

String query = "SELECT NEW org.company.directory.CustomObject(i.firstProperty, i.secondProperty) FROM ObjectName i WHERE i.id=10"; 
TypedQuery<CustomObject> typedQuery = em.createQuery(query , CustomObject.class); 
List<CustomObject> results = typedQuery.getResultList(); 
2

Projections possono essere usati per selezionare solo le proprietà specifiche (colonne) di un oggetto entità.

Dalla documentazione

primavera dati repository di solito ritornare il modello di dominio quando si utilizzano metodi di query. Tuttavia, a volte, potrebbe essere necessario modificare la visualizzazione di quel modello per vari motivi. Nella sezione this, imparerai come definire le proiezioni per offrire viste semplificate e ridotte delle risorse.

Definire un'interfaccia con solo lo getters desiderato.

interface CustomObject { 
    String getA(); // Actual property name is A 
    String getB(); // Actual property name is B 
} 

Ora tornare CustomObject dal repository in questo modo:

public interface YOU_REPOSITORY_NAME extends JpaRepository<YOUR_ENTITY, Long> { 
    CustomObject findByObjectName(String name); 
}