2015-04-01 7 views
10

Sono nuovo di primavera Boot & APP ...modo corretto allo strato DAO basato Primavera JPA utilizzando Boot Spring Framework

Diciamo che ho due entità mappate a due tabelle che sono uniti in un database.

Student-1 ------ < -Corso

Inoltre, lascia presumere che il database è già stato creato e popolato.

Questo raffigura che uno studente ha molti corsi ...

mio studente Entity:

@Entity 
public class Student { 

    @OneToMany(mappedBy="student") 
    private List<Courses> courses; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "Student_Id") 
    private long studentId; 

    @Column(name = "Student_Name") 
    private String studentName; 

    protected Student() { } 

    // Getters & Setters 
} 

mio corso Entity:

@Entity 
public class Course { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "Course_Id") 
    private long courseId; 

    @Id 
    @Column(name = "Student_Id") 
    private long studentId; 

    @ManyToOne 
    @PrimaryKeyJoinColumn(name="Student_Id", referencedColumnName="Student_Id") 
    private Student student; 

    @Column(name = "Course_Name") 
    private String courseName; 

    // Getters & Setters 

} 

nelle guide tutorial di Primavera di avvio, si illustra come per estendere un'interfaccia CrudRepository, ma non specifica come impostare un DAO basato sulla primavera che contiene metodi di ricerca personalizzati che utilizzano HQL e Entit yManager al suo interno.

Il seguente DAO e DaoImpl è corretto?

public interface CourseDao { 
    List<Course> findCoursesByStudentName(String studentName); 
} 

@Repository 
public class CourseDaoImpl implements CourseDao { 

    @PersistenceContext 
    EntityManager em; 

    public List<Course> findCoursesByStudentName(String studentName) { 
     String sql = "select c.courseName" + 
        "from Course c, Student s " + 
        "where c.course_id = s.student_id " + 
        "and s.studentName = :studentName "; 

     Query query = em.createQuery(sql); 
     query.setParameter("studentName", studentName); 
     return query.getResultList(); 
    } 
} 

E poi nel codice client, ad esempio, nella classe principale:

public class Application { 

    @Autowired 
    CustomerDao dao; 

    public static void main (String args []) { 
     List<Course> courses = dao.findCoursesByStudentName("John"); 
    } 
} 

E 'questo il modo standard per usare HQL all'interno Spring DAO? Ho visto esempi dell'annotazione @Transactional anteposta all'imp della classe DAO (ad esempio CustomerDAOImpl)?

Per favore fatemi sapere se questo è il modo di scrivere per strutturare la mia app Spring Boot o dovrei estendere/aggiungere solo al CrudRepository?

Se qualcuno potesse correggere il mio esempio e indicarmi un URL che parla di HQL usando Entità che sono state unite, sarei molto grato.

Le guide di avvio di primavera non descrivevano join o DAO: ho solo bisogno di imparare come creare correttamente i metodi finder che emulano l'istruzione select che restituisce elenchi o strutture dati.

Grazie per aver il tempo di leggere questo ...

risposta

1

Se si annota il vostro CourseDaoImpl con @Transactional (Assumendo che il hanno definito JpaTransactionManager correttamente) Si può solo recuperare lo studente con il nome corrispondente e chiamare il metodo getCourses() a pigro caricare i corsi collegati a quello studente. Poiché findCoursesByStudentName verrà eseguito all'interno di una transazione, verrà caricato correttamente i corsi.

@Repository 
@Transactional(readOnly=true) 
public class CourseDaoImpl implements CourseDao { 

    @PersistenceContext 
    EntityManager em; 

    public List<Course> findCoursesByStudentName(String studentName) { 
     String sql = "select s " + 
        "from Student s " + 
        "where s.studentName = :studentName "; 

     Query query = em.createQuery(sql); 
     query.setParameter("studentName", studentName); 
     User user = query.getSingleResult(); 
     if(user != null) { 
      return user.getCourses(); 
     } 

     return new ArrayList<Course>(); 
    } 
} 
+0

shazin, grazie per rispondere ... È questo il modo standard per fare HQL? Stai facendo una selezione di studenti e non il join? Sono confuso ... Inoltre, perché readOnly = true? Cosa intendi per definire correttamente JpaTransactionManager? Come lo faresti in Spring Boot? Perché non usare il CrudRespository? Quello che sto cercando è il modo standard per fare le cose ... Grazie per il tuo aiuto. –

+0

Dove è definito questo User class/oggetto ref? Intendevi Studente? –

10

Se ho capito la tua domanda corretta si ha due domande:

  1. Come creare un DAO e DAOImpl?
  2. Dove inserire le annotazioni della transazione?

Per quanto riguarda la prima domanda che voglio far notare che questa è una domanda per quanto riguarda spring-data-jpa usando Hibernate come provider JPA, non spring-boot.

Utilizzo di dati di primavera In genere, salta completamente per creare un DAO ma utilizzare direttamente un repository personalizzato estendendone uno standard come CrudRepository. Quindi nel tuo caso in cui non hanno nemmeno bisogno di scrivere più codice rispetto:

@Repository 
public interface StudentRepository extends CrudRepository<Student, Long> { 

    List<Student> findByStudentName(String studentName); 

} 

Quale sarà sufficiente e Spring dati si prenderà cura di riempire con la corretta applicazione se si utilizza

@Autowired 
StudentRepository studentRepo; 

nella tua classe di servizio. Questo è dove solitamente annoto i miei metodi con @Transactional per assicurarmi che tutto funzioni come previsto.

Per quanto riguarda la tua domanda su HQL, guarda nello spring data jpa documentation, che sottolinea che per la maggior parte dei casi dovrebbe essere sufficiente attenersi ai metodi con i nomi corretti nell'interfaccia o andare per le interrogazioni denominate (sezione 3.3.3) oppure utilizzare l'annotazione @Query (sezione 3.3.4) per definire manualmente la query, ad es. dovrebbe funzionare (non provato):

@Repository 
public interface @CourseRepository extends CrudRepository<Course, Long> { 

    @Query("select c.courseName from Course c, Student s where c.course_id = s.student_id and s.studentName = :studentName") 
    public List<Course> findCoursesByStudentName(String studentName); 

} 
+0

che è meglio? Repository JPA o Cruid? possiamo usare il repository? l'ultima volta che ho usato Hibernate There Ware Spring 2.5 e Hibernate 3, non solo ho dimenticato di cosa si trattava, inoltre non ho usato queste funzionalità, prima di vederle di nuovo su youtube ... – deadManN

+1

'JPARepository' in realtà eredita da' CRUDRepository' quindi è un tipo specifico per trattare con JPA Pojos. Vedi http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html –

+0

grazie mille, ' S saveAndFlush (S entity)' : O non salva l'operazione all'interno di crud, esegue tutte le modifiche di salvataggio sul database? – deadManN

Problemi correlati