2013-02-26 18 views
5

ich die folgende Datenbankmodell habenWie JdbcTemplate verwenden, um Abfragen auszuführen Join

 create table Diary (id bigint NOT NULL AUTO_INCREMENT, 
       creationDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
       name varchar(255) not null, 
       description text, 
       viewtype varchar(255) not null, 
       member bigint, 
       primary key (id), 
       foreign key (member) references Member(id)); 


     create table Page (id bigint NOT NULL AUTO_INCREMENT, 
       creationDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
       viewtype varchar(255) not null, 
       diary bigint, 
       member bigint, 
       primary key (id), 
       foreign key (diary) references Diary(id), 
       foreign key (member) references Member(id)); 

     create table Comment (id bigint NOT NULL AUTO_INCREMENT, 
       postingDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 
       comment text not null, 
       page bigint, 
       member bigint, 
       primary key (id), 
       foreign key (page) references Page(id) 
       foreign key (member) references Member(id)); 

Ich bin mit Feder Jdbc Vorlage.

 My interface looks like follows: accountid is the memeberid in the database. 

    Collection<Diary> getDiaries(Long accountId); 

Und mein Tagebuch sieht aus wie folgt:

  public class Diary { 
      private Collection<Page> pages; 
      private Long id; 
      private LocalTime creationDate; 
      private String name; 
      private String description; 
      private ViewType type; 
      } 

ich, wie die Abfrage aussehen wird nun ein Tagebuch Object mit jdbc Vorlage vorzubereiten, wenn ich wollte wissen wollte. Es ist auch möglich, nur eine Abfrage auszulösen und nur dieses Tagebuch-Objekt vorzubereiten, weil ich für dieselbe Anfrage mehrere Abfeuern von Abfragen vermeiden werde. Für die obige Schnittstelle ist es sehr wahrscheinlich, dass ich s join-Abfrage verwenden werde oder gibt es eine einfachere Möglichkeit, Spring JDBC Template Framework zu verwenden.

Antwort

3

Sie könnten eine einzige Abfrage mit Outer Joins erstellen (ich gehe hier davon aus, dass es möglich ist, ein Tagebuch zu haben, das keine Seiten hat und Seiten hat, die keine Kommentare haben).

Anstatt mehrere Abfragen auszuführen (eine für jede Seite), führt dies eine einzige Abfrage mit Outer-Joins zur Verbindung Diary, Page und Comment aus. Wie Sie unten sehen können, bedeutet dies, dass die Tagebuch- und Seiteninformationen mehrmals zurückgegeben werden, aber ich denke, es gibt einen Kompromiss zwischen mehreren DB-Anrufen und ein wenig redundanter Information.

class FullDiaryRowCallbackHandler implements RowCallbackHandler { 
    private Collection<Diary> diaries = new ArrayList<Diary>(); 
    private Diary currentDiary = null; 
    private Page currentPage = null; 

    public void processRow(ResultSet rs) { 
     long diaryId = rs.getLong("d.id"); 
     if (currentDiary == null || diaryId != currentDiary.getId()) { 
      currentDiary = new Diary(); 
      currentPage = null; 
      diaries.add(currentDiary); 
      currentDiary.setId(diaryId); 
      currentDiary.setCreationDate(toLocalTime(rs.getTimestamp("d.creationDate"))); 
      currentDiary.setDescription(rs.getString("d.description")); 
      ... 
     } 
     long pageId = rs.getLong("p.id"); 
     if (!rs.wasNull() && currentPage != null && currentPage.getId() != pageId) { 
      currentPage = new Page(); 
      if (currentDiary.getPages() == null) { 
       currentDiary.setPages(new ArrayList<Page>()); 
      } 
      currentDiary.getPages().add(currentPage); 
      currentPage.setId(pageId); 
      currentPage.setCreationDate(toLocalTime(rs.getTimestamp("p.creationDate"))); 
      ... 
     } 
     long commentId = rs.getLong("c.id"); 
     if (!rs.wasNull() && currentPage != null) { 
      Comment comment = new Comment(); 
      if (currentPage.getComments() == null) { 
       currentPage.setComments(new ArrayList<Comment>()); 
      } 
      currentPage.getComments().add(comment); 
      comment.setId(commentId); 
      comment.setPostingDate(toLocalTime(rs.getTimestamp("c.postingDate"))); 
      comment.setComment(rs.getString("c.comment")); 
     } 
    } 

    public Collection<Diary> getDiaries() { 
     return diaries; 
    } 
} 

FullDiaryRowCallbackHandler rowCallbackHandler = new FullDiaryRowCallbackHandler(); 
Collection<Diary> result = jdbcTemplate.query(
    "select d.id, " + 
      "d.creationDate, " + 
      "d.description, " + 
      "p.id, " + 
      "p.creationDate, " + 
      "c.id, " + 
      "c.postingDate, " + 
      "c.comment " + 
     "from Diary d " + 
     "left outer join Page p on d.id = p.diary " + 
     "left outer join Comment c on p.id = c.page " + 
    "where d.member = ? " + 
    "order by d.id, p.id, c.id", 
    rowCallbackHandler, 
    myMemberId); 
Collection<Diary> diariesForMember = rowCallbackHandler.getDiaries(); 

Hinweis, ist der Code nicht besonders hübsch, weil man die Ergebnismengen zu verarbeiten hat und kümmert sich um, wenn eine neue Seite zurückgegeben wird (deshalb die order by Klausel wichtig ist), aber das ist die Art von Dinge, die wie Hibernate für Sie unter der Haube sorgen, wenn sie eifrig holen (ich sage nicht, Hibernate ist besser oder nicht, denn ich verwende JdbcTemplate für die Kontrolle über die Abfragen, die ich ausstelle, aber Hibernate (oder JPA) machen viel von dem schweren Heben, wenn es darum geht, Objektgraphen zu füllen).

Siehe JdbcTemplate#query

EDIT auch:

Geändert alle Tagebücher zurück, Seiten, Kommentare für ein Mitglied.

+0

Danke Beny. Ich muss das testen. –

+0

Ich habe gerade eine sehr einfache Abfrage geschrieben -> wähle d.id, d.creationDate, d.name, d.description, d.viewtype aus Mitglied m inner join Tagebuch d auf d.member = m.id where m.id = "4915018864030990478"; Dies gibt mir alle Tagebücher für ein Mitglied zurück. Jetzt kann jedes Tagebuch n Seiten haben, was denkst du, wenn ich mehrere Sub-Inner Joins zu dieser Abfrage mache. Dein natürlich sieht gut aus, aber ich wollte wissen, ob das auch möglich ist oder nicht. –

+0

@SaurabhKumar: Geändert, um alle Tagebücher für ein Mitglied zu behandeln. – beny23

Verwandte Themen