2016-10-11 92 views
1

使用hibernate從數據庫填充表時,理想情況下希望使用最少量的查詢,以便快速應用它們。理想情況下,您不希望執行比您正在構建的表中的列更多的查詢,因爲按查詢分組將允許您填充所有行。所以如果你有m列和n行,你只需要執行m個查詢。減少休眠所需的查詢數

但是,我發現很難在沒有寫入新方法的情況下在Daos中實現這一點。比方說,你正在處理名爲Employee實體,並且你想計算的工作時間平均數量,你會再需要2種方法:

public interface EmployeesDao 
{ 
    public List<Double> averageOfHoursWorked(List<Integer> ids); 
    public double averageOfHoursWorked(Integer id); 
} 

所以,當你想創建一個表,你會使用的方法接受一個列表,但是當你只處理一個單一的員工時,你會使用一個單一的ID。

但我不想寫2個方法,我只想寫一個理想的方法。但是,如果我寫一個方法,我最終使用一個for循環,這使得查詢,而不只是一個的一大堆:

// THIS IS BAD, creates many queries 
    List<Integer> ids = Arrays.asList(1,3,5,99, 1921); 
    for (Integer id : ids) { 
     double avg = dao.averageOfHoursWorked(id); 
     // .... doing some table stuff with avg... 
    } 

    // THIS IS GOOD, only 1 query, yet now I must write more code): 
    List<Double> avgs = dao.averageOfHoursWorked(ids); 
    for (Double avg : avgs) { 
     // .... doing some table stuff with avg... 
    } 

所以我知道的第二個版本要快得多,但它需要我更長的時間來代碼然後。但正如我在寫這個我想我可以做這樣的事情:

class EmployeesDaoImp implements EmployeesDao { 

    @Override 
    public double averageOfHoursWorked(Integer id) { 
     return averageOfHoursWorked(Arrays.asList(id)).get(0); 
    } 
} 

那我就只需要編寫List<Double> averageOfHoursWorked(List<Integer> ids),這是個好主意嗎?一般來說,有人會用一種更優雅的方式來製作表格嗎?也許一個生成器模式或某事會更好,如:

Table table = dao.buildTable().withIds(ids).columnId().columnAvgHoursWorked().columnDaysOff()

其中ColumnID的()會給你的ID列,columnAvgHoursWorked,會給你的另一列與工作時間等。使用hibernate製作表格的最佳方式是什麼,需要最少量的查詢和代碼。

+0

我得到你所要求的一般要點,但它仍然不清楚。你能給出一個(可能是簡化版)的數據庫模式,以及它如何轉換爲你正在製作的mxn表?你還可以顯示你用來創建表的代碼片段嗎?但是請注意,通常情況下,您可以使用HQL編寫自定義查詢,因此始終可以使用獨立於dbms的方式創建自己的特定查詢。作爲開始,請參閱https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql。 –

+0

我想我會刪除這個問題,我想不出一個沒有更清楚也不太寬泛的方法,我只想盡量減少我寫的代碼的數量,但不會執行太多的數據庫操作。 – Snickers3192

+0

我不能刪除這個問題,請問主持人請關閉這個,或者只是在我的問題上投票結束。 – Snickers3192

回答

-1

起初,對不起我可憐的英語。 我認爲可以創建一個DTO對象,該對象將成爲數據對象,並將包含要在JSP中使用的所有信息,您將把這些對象作爲一個唯一方法的返回,並以一次唯一調用解決您的問題。

例如:

public List getAllEmployeesWithAverageHoursWorked(int start, int finish){

List<EmployeeDTO> result = new ArrayList<EmployeeDTO>(); 
///execute query that load registers that start in parameter start and finishes in parameter finish 

return result; 

}

類EmployeeDTO將有你需要在你的JSP頁面中使用的所有字段,或者,如果這個選項不解決這個問題,你將改變方法和EmployeeDTO類來獲得您需要的字段。

+0

問題是詢問我如何避免做出正確答案。我不想每次製作表格時都要寫一個自定義的dao方法。我只想重用我擁有的東西。但如果我不需要,我也不想再進行100次數據庫調用。但是當我重複使用我所擁有的東西時,最終會這樣做。 – Snickers3192

-1

我不明白你的問題,但我會給出三種形式,我認爲人們可以提供幫助。

1 - 使用泛型並將相同的DAO用於軟件中所有類型的對象。

2 - 在我的答案中可以指定你需要閱讀的開始點和結束點,例如:你收穫了10條記錄,現在需要閱讀更多,然後通過10和20,並閱讀更多10.

3 - 在第一個調用中,您將把需要的記錄放入一個靜態變量中並使用(這太可怕了)。

如果你的問題不是「寫」代碼,使用泛型,這是很好的解決這個問題。

但是,如果我的答案不正確,請再次提出您的問題,但換句話說,我可以幫助您。

0

我相信,現在我明白你的問題,請參見下面的選項:

public abstract class GenericDAOImpl<T> implements GenericDAO<T>{ 

     private Class<T> entityBeanType; 

     @Autowired 
     protected SessionFactory sessionFactory; 

     public GenericDAOImpl() { 

      ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); 
      Type type = genericSuperclass.getActualTypeArguments()[0]; 

      @SuppressWarnings("unchecked") 
      Class<T> clazz = (Class<T>) type; 

      this.entityBeanType = clazz; 
     } 

     @SuppressWarnings("unchecked") 
     public T save(T t) { 
      T t1 = (T) sessionFactory.getCurrentSession().merge(t); 
      sessionFactory.getCurrentSession().flush(); 
      return t1; 
     } 
    } 

</code> 

Repair that if you need to create another table, you will can extend this class to create a concrete DAO.

Example:

1 - create a table User and use the following code:

public class UserDAOImpl extends GenericDAOImpl<User> implements UserDAO{ 
    ///other specific methods will be here 
} 

2 - 創建一個表,收據和使用下面的代碼:

public class ReceiptsDAOImpl extends GenericDAOImpl<Receipts> implements  ReceiptsDAO{ 
    ///other specific methods will be here 
} 

通用類型T可以是你的軟件的一些實體。

我希望我的回答能幫助你。

+1

請停止發佈許多答案,格式化您的答案,儘量只有1個答案,如果可以的話。你用垃圾填寫這篇文章。 – Snickers3192