2015-03-12 15 views
17

Trong dự án của chúng tôi, chúng tôi có một thực thể 'Nhà hàng' với gần 30 trường (một số có mối quan hệ với các thực thể khác). Vì vậy, mỗi lần chúng ta cần một đối tượng 'Nhà hàng' ngay cả đối với một vài lĩnh vực, tất cả các trường khác đều được truy xuất. Điều này ảnh hưởng đến hiệu suất. Vì vậy, trong tệp HBM, chúng tôi đã viết hai lớp, cả hai đều trỏ đến cùng lớp vật lý và cùng một bảng cơ sở dữ liệu, như được hiển thị bên dưới.Cách ánh xạ hai thực thể JPA hoặc Hibernate trên cùng một bảng cơ sở dữ liệu

=== restaurant.hbm.xml === 
<!-- Light Weight Version --> 
<class name="com.raj.model.Restaurant" table="RESTAURANTS" entity-name="RestaurantLite" 
       dynamic-update="false" dynamic-insert="false"> 
<cache usage="read-only"/> 
    <!-- few basic properties and relationships --> 
</class> 

<!-- Restaurant --> 
<class name="com.raj.model.Restaurant" table="RESTAURANTS" entity-name="Restaurant"> 
    <!-- all properties and relationships --> 
</class> 

Trong một trong các triển khai DAO, chúng tôi đang sử dụng Tiêu chí nhận 'RestaurantLite' và danh sách các nhà hàng trả lại như minh họa bên dưới.

Criteria criteria = session.createCriteria("RestaurantLite"); 

    // criteria related stuff 

return new LinkedHashSet<Restaurant>(criteria.list()); 

Bây giờ, chúng tôi muốn xóa tất cả các tệp hbm và sử dụng chú thích. Vì vậy, làm thế nào cùng có thể được thực hiện bằng cách sử dụng chú thích cho entites? Chúng ta có cần tạo thêm một lớp 'RestaurantLite' không? Nếu sau đó, cách các tiêu chí trên trả về các đối tượng 'Nhà hàng'?

+1

Điều này ảnh hưởng đến hiệu suất. Đến mức độ nào? Bạn đã đo? Theo lưu ý tài liệu Hibernate: tối ưu hóa hàng đọc là quan trọng hơn nhiều so với tối ưu hóa đọc cột. Tuy nhiên, chỉ tải một số thuộc tính của một lớp có thể hữu ích trong ** trường hợp cực **. Ví dụ: khi các bảng cũ có ** hàng trăm ** cột và mô hình dữ liệu không thể được cải thiện. https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching-lazy –

+0

@Alan Hay Chúng tôi có một cơ sở dữ liệu với hàng nghìn bản ghi cho mỗi bảng. Lớp học được đề cập ở trên là cần thiết cho hầu hết các hoạt động. Vì vậy, lấy tất cả các thuộc tính cho mỗi nhà hàng mỗi lần chắc chắn tác động đến hiệu suất. Vì vậy, chúng tôi đã đưa ra giải pháp đó trong các tệp hbm. – Raj44

+0

Tất cả cơ sở dữ liệu đều có hàng nghìn, hàng chục nghìn hàng triệu hàng. Như các tài liệu Hibernate chỉ ra tối ưu hóa cột hiếm khi đáng giá. http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize –

Trả lời

32

chủ đề này cũng như làm thế nào bạn có thể sử dụng nó cho các thuộc tính quyến rũ lười biếng, nó được mô tả chi tiết trong in this article.

Để tóm tắt nó, ánh xạ sau đây sẽ chứng minh làm thế nào bạn có thể ánh xạ nhiều đơn vị vào bảng cơ sở dữ liệu tương tự:

@Entity(name = "Post") 
public class Post { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    private String name; 

    private String description; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 
} 

@Entity(name = "PostSummary") 
@Table(name = "Post") 
@Immutable 
public class PostSummary { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

@Entity(name = "UpdatablePostSummary") 
@Table(name = "Post") 
@DynamicUpdate 
public class UpdatablePostSummary { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

Và Hibernate sẽ chỉ làm việc tốt:

@Test 
public void testOneTableMultipleEntities() { 
    doInTransaction(session -> { 
     Post post = (Post) session.get(Post.class, 1L); 
     PostSummary postSummary = (PostSummary) session.get(PostSummary.class, 1L); 
     UpdatablePostSummary updatablePostSummary = (UpdatablePostSummary) session.get(UpdatablePostSummary.class, 1L); 
     assertEquals(post.getName(), postSummary.getName()); 
     assertEquals(post.getName(), updatablePostSummary.getName()); 
     updatablePostSummary.setName("Hibernate Master Class Tutorial."); 
    }); 
} 
  1. PostSummary chỉ là chế độ xem chỉ đọc trên thực thể ban đầu của bạn, do đó tôi đã chú thích nó với @Immutable.

  2. UpdatablePostSummary được đánh dấu bằng @DynamicUpdate và vì vậy bạn cũng có thể truyền bá thay đổi từ thực thể Chế độ xem này.

Thử nghiệm này cũng có sẵn trên GitHub.

+0

Điều gì xảy ra nếu bạn cập nhật 'UpdatablePostSummary'?Mục 'Post' sẽ được cập nhật thành? (Bên trong Hibernate tôi có nghĩa là, rõ ràng trong cơ sở dữ liệu này là cùng một bảng). –

+3

Trong Hibernate, thực thể 'Post' sẽ phải được làm mới theo cách thủ công, vì nếu không Hibernate sẽ không tự động làm điều đó. –

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