2016-08-01 98 views
6

我对Hibernate很新。 在这里我想比较两个选项。休眠性能问题

第一选项

我休眠POJO类如下。

Stock { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "stock_id") 
    private Long stockId; 

    @Column(name = "stock_name") 
    private String stockName; 

    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(name = "stock_characteristics", joinColumns = {@JoinColumn(name = "stock_id")}, inverseJoinColumns = {@JoinColumn(name = "ct_id")}) 
    private List<Characteristic> characteristics = new ArrayList<>(); 

    //constructor, getters and setters 

} 

Characteristics { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ct_id", nullable = false) 
    private Long id; 

    @Column(name = "name", nullable = false, length = 32) 
    private String name; 

    //constructor, getters and setters 
} 

每个股票都包含一个特征列表。每当我拿到股票时,特征条目列表都会关联,并且结果越来越好。

我的股票表包含了超过100万条记录,并与10特性(使stock_characteristics包含超过10万行)相关联的每个股票。当我们获取整个结果时,股票和特征之间的关联可能会变慢。

第二种选择。

我重写我的pojo类如下。

Stock { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "stock_id") 
    private Long stockId; 

    @Column(name = "stock_name") 
    private String stockName; 

    //constructor, getters and setters 

} 

特性 - 同上

StockCharacteristics { 
     @Id 
     @GeneratedValue(strategy = GenerationType.AUTO) 
     @Column(name = "id") 
     private Long id; 
     @Column(name = "stock_id", nullable = false) 
     private Long stockId; 
     @Column(name = "ct_id", nullable = false) 
     private Long ctId; 
    } 

为了得到我的结果集,我只透过特性集。例如,如果将特征传递为2,那么首先我找到具有两个特征的股票id。然后我将从Stock类投影股票详情。 这是我第一个选项的示例代码。

criteria.createAlias("stock.characteristics", "stockCharacteristics",  CriteriaSpecification.INNER_JOIN).add(Restrictions.in("stockCharacteristics.id", listOfSelectedCharacteristics)); 
    List<Object[]> projectedList = criteria.setProjection(Projections.projectionList().add(Projections.count("id")).add(Projections.groupProperty("id"))).list(); 
    List<Long> stockIdList = new ArrayList<>(); 
    for(Object[] entry: projectedList){ 
     if(((Long) entry[0]).intValue() == listOfSelectedCharacteristics.size()){ 
      stockIdList.add((Long)entry[1]); 
     } 
    } 

    if(!stockIdList.isEmpty()){ 
     Criteria criteriaWithCharacteristics = getDb(true).createCriteria(Stock.class, "stock").add(Restrictions.in("id", stockIdList)); 
     selectedStocks = criteriaWithCharacteristics.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); 
    } 

在这里你可以看到的是股票和特性之间进行了连接的查询可能减缓下来,

这里是第二个选项

List<Object[]> stockIdList = //gets the stock id list from StockCharacteristics 
    if(!stockIdList.isEmpty()){ 
     Criteria criteriaWithCharacteristics = getDb(true).createCriteria(Stock.class, "stock").add(Restrictions.in("id", stockIdList)); 
     selectedStocks = criteriaWithCharacteristics.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); 
    } 

作为一个程序点我的示例代码查看哪个是最佳选择?或者我应该使用哪一个来获得更好的性能?

回答

0

我认为你应该在hibernate中映射实体之间的所有关系。如果你想使用hql和条件,这将有所帮助,否则你将无法在实体之间进行连接。

对于性能,纪念所有的映射,懒惰和阅读:

https://zeroturnaround.com/rebellabs/how-to-use-jpa-correctly-to-avoid-complaints-of-a-slow-application/

我经常使用的MS SQL服务器,并检查我的慢查询的执行计划,以确保我的查询有很好的索引。 用mysql可以用“show index”