2013-02-26 37 views
5

Tôi có theo mô hình cơ sở dữ liệuLàm thế nào để sử dụng JdbcTemplate để thực hiện các truy vấn tham

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

Tôi đang sử dụng lò xo JDBC mẫu.

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

    Collection<Diary> getDiaries(Long accountId); 

Và cuốn nhật ký của tôi trông giống như sau:

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

Tôi muốn biết làm thế nào truy vấn sẽ xem xét ngay bây giờ nếu tôi muốn chuẩn bị một đối tượng Diary sử dụng mẫu jdbc. Cũng có thể chỉ cháy một truy vấn và chỉ chuẩn bị đối tượng Nhật ký này vì tôi sẽ tránh yêu cầu nhiều lần truy vấn. Đối với giao diện trên, rất có thể là tôi sẽ sử dụng truy vấn kết nối s hoặc có cách nào đơn giản hơn có thể bằng cách sử dụng khuôn mẫu khuôn mẫu JDBC mùa xuân.

Trả lời

3

Bạn có thể tạo một truy vấn đơn bằng cách sử dụng các kết nối bên ngoài (tôi giả định ở đây là có thể có một cuốn nhật ký không có bất kỳ trang nào và có các trang không có nhận xét).

Bây giờ, thay vì thực hiện nhiều truy vấn (một cho mỗi trang), truy vấn này sử dụng kết nối bên ngoài để kết nối Diary, PageComment. Như bạn có thể thấy bên dưới, điều này có nghĩa là nhật ký và thông tin trang được trả về nhiều lần, nhưng tôi nghĩ có sự cân bằng giữa việc có nhiều cuộc gọi DB và một chút thông tin dư thừa.

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

Lưu ý, các mã không đặc biệt xinh đẹp, bởi vì bạn phải xử lý các tập hợp kết quả và chăm sóc khi một trang mới được trả lại (đó là lý do tại sao các khoản order by là quan trọng), nhưng đó là loại điều mà Hibernate thích chăm sóc cho bạn dưới mui xe khi họ đang háo hức tìm kiếm (tôi không nói Hibernate là tốt hơn hay không, vì tôi thích sử dụng JdbcTemplate để kiểm soát nó cung cấp trên các truy vấn mà tôi đang phát hành, nhưng Hibernate (hoặc JPA) làm rất nhiều việc nâng hạng nặng khi nói đến các đồ thị đối tượng đông dân cư).

Xem thêm JdbcTemplate#query

EDIT:

Modified trả lại toàn bộ nhật ký, trang, nhận xét cho thành viên.

+0

Cảm ơn beny. Tôi phải kiểm tra điều này. –

+0

Tôi vừa viết một truy vấn rất đơn giản -> chọn d.id, d.creationDate, d.name, d.description, d.viewtype từ Member m inner join Diary d vào d.member = m.id ở đâu m.id = "4915018864030990478"; Điều này trả lại cho tôi tất cả nhật ký cho một Thành viên. Bây giờ mỗi cuốn nhật ký có thể có n trang vì vậy bạn nghĩ gì nếu tôi làm nhiều phụ bên trong tham gia vào truy vấn này. Một ofcourse của bạn có vẻ tốt nhưng tôi muốn biết nếu điều này cũng có thể hay không .. –

+0

@SaurabhKumar: Sửa đổi để đối phó với tất cả nhật ký cho một thành viên. – beny23

Các vấn đề liên quan