2016-04-06 4 views
2

beitreten Ich habe unter 2 Entitätsklassen 1.student 2. resluts und ich habe eine resultset zurückkehren, indem Sie die unten angepasste AbfrageZugriff auf mehrere Unternehmen Abfrage Suchresultates mit Frühlings-JPA

select s.roll_no , s.first_name, s.age ,r.subject_name , r.marks from student s , results r where s.roll_no= : rollNo and r.marks >70 

Ausführung, die das Ergebnis liefert Set mit Kombination von Student und Ergebniseinheit. In so einem Szenario schreibe ich meine Implementierung. Ich habe unten zwei Ansätze versucht

Ansatz 1:

public interface GetStudentDetail extends CrudRepository<Student, String> { 
    @Transactional(readOnly=true) 
    @Query("select s.roll_no , s.first_name, s.age ,r.subject_name , r.marks from student s , results r where s.roll_no= : rollNo and r.marks >70") 
    public List<student> getStudentDetails(@Param("rollNo")String rollNo); 
} 

Mit dem oben ich in der Lage war nur die Schüler Einheit Werte aus den Suchresultates und Ergebnisse Entitätsobjekten zu bekommen waren hier nicht sichtbar.

Ansatz 2:

public interface GetStudentDetail extends CrudRepository<Student, String> { 
    @Transactional(readOnly=true) 
    @Query("select s.roll_no , s.first_name, s.age ,r.subject_name , r.marks from student s , results r where s.roll_no= : rollNo and r.marks >70") 
    public List<Object[]> getStudentDetails(@Param("rollNo")String rollNo); 
} 

Hierdurch erstellt ich eine weitere VO Klasse sowohl mit der Einheit variable und i manuell auf das Objekt gesetzt durch die Position, um es den Zugriff wie unten

List<StudentResultVo>studtVoObjList = new ArrayList<StudentResultVo>(); 
    for (Object[] resObj : resultSetList) { 
     StudentResultVo studtVO = new StudentResultVo(); 
     if (resObj[0] != null) { 
      studtVO.setRollNo(resObj[0].toString().trim()); 
     } 
     //.First name 
     //.Age 

     if (resObj[3] != null) { 
      studtVO.setSubName(resObj[3].toString().trim()); 
     } 
     //.Marks 
     studtVoObjList.add(studtVO); 
    } 

i wusste, dass der obige Ansatz keine gute Kodierungspraxis ist. Gibt es eine Möglichkeit, dieses Problem zu lösen?

Danke.

Antwort

2

erste neue Schnittstelle erstellen und erklären, um Ihre Methode

public interface GetStudentDetailCustom { 
    public List<Object[]> getStudentDetails(String rollNo); 
} 

und zweiter Klasse schaffen GetStudentDetailImpl und implementieren die Schnittstelle

public class GetStudentDetailImpl implements GetStudentDetailCustom { 

    @PersistenceContext 
    private EntityManager entitymanager; // I use entity manager also you want to use inject SessionFactory etc.. 

    @Override 
    public List<Object[]> getStudentDetails(String rollNo) { 
     String queryString = "SELECT s.roll_no , s.first_name, s.age ,r.subject_name , r.marks FROM student s " 
       + ", results r WHERE s.roll_no= :rollNo and r.marks > 70"; 

     Query query = entitymanager.createQuery(queryString); 
     query.setParameter("rollNo", rollNo); 

     return query.getResultList(); 
    } 

} 

und Refactoring Ihr Repository wie diese

public interface GetStudentDetail extends CrudRepository<Student, String>, GetStudentDetailCustom {} 

und finaly Verwenden Sie inject GetStudentDetail in Ihrem Dienst E-Klasse und rufen getStudentDetails Methode

Beispiel für die Verwendung in der Dienstschicht:

@Autowired 
private GetStudentDetail getStudentDetail; 

getStudentDetail.getStudentDetails(String rollNo); 

Referenz Antwort: How to add custom method to Spring Data JPA

und Feder Referenz: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behaviour