2015-04-01 10 views
10

Am neuen Spring-Boot & JPA ...richtige Weg Frühling JPA basiert DAO mit Spring-Boot-Rahmen

Lassen Sie uns sagen, ich habe zwei Einheiten auf zwei Tabellen zugeordnet Schicht, die in einer Datenbank verbunden sind.

Schüler-1 ------ < -Kurs

Auch lässt vermuten, dass die Datenbank bereits erstellt und mit Daten gefüllt ist.

Dies zeigt, dass ein Schüler viele Kurse ...

Mein Studenten Entity hat:

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

My Course 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 

} 

Im Frühjahr Boot-Tutorial Guides, es zeigt, wie um eine CrudRepository-Schnittstelle zu erweitern, aber wird nicht angegeben, wie ein Spring-based DAO eingerichtet wird, das benutzerdefinierte Finder-Methoden enthält, die HQL und Entität verwenden yManager drin.

Sind die folgenden DAO und DaoImpl korrekt?

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

Und dann im Client-Code, zum Beispiel in der Hauptklasse:

public class Application { 

    @Autowired 
    CustomerDao dao; 

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

Ist dies der normale Weg HQL innerhalb Frühlings DAOs zu benutzen? Ich habe Beispiele der @Transactional Annotation, die dem Impl der DAO-Klasse vorangestellt ist (z. B. CustomerDAOImpl)?

Bitte lassen Sie mich wissen, wenn dies die Schreibweise ist, um meine Spring Boot App zu strukturieren, oder soll ich nur das CrudRepository erweitern/ergänzen?

Wenn jemand mein Beispiel korrigieren und mich auf eine URL verweisen könnte, die über HQL mit Entitäten spricht, die verbunden sind, wäre ich sehr dankbar.

Die Spring Boot-Guides zeigten keine Joins oder DAOs - ich muss nur lernen, wie man Finder-Methoden erstellt, die select-Anweisungen emulieren, die Listen oder Datenstrukturen zurückgeben.

Vielen Dank für die Zeit nehmen, diese zu lesen ...

Antwort

1

Wenn Sie Ihre Anmerkungen versehen CourseDaoImpl mit @Transactional (Angenommen, Ihre haben JpaTransactionManager richtig definiert) Sie können die Schüler mit dem passenden Namen und rufen Sie die getCourses() Methode nur abrufen faul laden Sie die Kurse, die diesem Schüler beigefügt sind. Da findCoursesByStudentName innerhalb einer Transaktion ausgeführt wird, werden die Kurse problemlos geladen.

@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, danke für die Antwort ... Ist das der Standard Weg, um HQL zu tun? Sie machen eine Auswahl von Studenten und nicht die beitreten? Ich bin verwirrt ... Und warum ist readOnly = true? Was meinst du JpaTransactionManager richtig definieren? Wie würdest du das in Spring Boot machen? Warum nicht das CrudRespository benutzen? Was ich suche, ist die übliche Art, Dinge zu tun ... Danke für deine Hilfe. –

+0

Wo ist diese Benutzerklasse/Objektref definiert? Meinst du Student? –

10

Wenn ich Ihre Frage verstanden richtigen Sie zwei Fragen haben:

  1. Wie ein DAO und DAOImpl schaffen?
  2. Wo können Sie Ihre Transaktionskommentare platzieren?

In Bezug auf die erste Frage, die ich, dass dies eine Frage in Bezug auf spring-data-jpa mit Hibernate als JPA-Provider hinweisen will, nicht spring-boot.

Verwenden von Spring Data Ich überspringe normalerweise vollständig, um ein DAO zu erstellen, benutze aber direkt ein Custom Repository, das einen Standard wie zB CrudRepository erweitert. Also in Ihrem Fall müssen Sie nicht einmal mehr Code schreiben als:

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

    List<Student> findByStudentName(String studentName); 

} 

Welche ausreichend sein wird und Spring Data wird es mit der korrekten Anwendung der Füllung kümmern, wenn Sie

@Autowired 
StudentRepository studentRepo; 

verwenden in Ihrer Serviceklasse. Hier notiere ich auch meine Methoden normalerweise mit @Transactional, um sicherzustellen, dass alles wie erwartet funktioniert.

In Bezug auf Ihre Frage zu HQL schauen Sie bitte in die spring data jpa documentation, die darauf hinweist, dass es für die meisten Fälle ausreichend sein sollte, bei benannten Methoden in der Schnittstelle zu bleiben oder für benannte Abfragen (Abschnitt 3.3.3) oder verwenden Sie die @Query Annotation (Abschnitt 3.3.4), um die Abfrage manuell zu definieren, z sollte funktionieren (nicht versucht):

@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

was ist besser? JPA oder Cruid Repository? Können wir nur Repository verwenden? Letztes Mal habe ich den Winterschlaf genutzt, war Frühling 2.5 und überwintere 3, nicht nur, ich habe vergessen, worum es ging, ich habe diese Funktion auch nicht benutzt, bevor ich sie auf youtube gesehen habe ... – deadManN

+1

'JPARepository' erbt tatsächlich von ' CRUDRepository "ist also ein spezieller Typ, der sich mit JPA Pojos befasst. Siehe http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html –

+0

vielen dank, ' S saveAndFlush (S entity)' : O speichert nicht Operation innerhalb der Crud, führen Sie alle speichert Änderungen in der Datenbank? – deadManN

Verwandte Themen