Ale*_*lex 6 hibernate hibernate-mapping hibernate-criteria
我对Hibernate很新.在这里我想比较两个选项.
第一种选择
我的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
}
Run Code Online (Sandbox Code Playgroud)
每个库存包含一系列特征.每当我获取股票时,特征条目列表将关联并且结果正在获得.
我的库存表包含超过100万条记录,每条库存与10个特征相关联(因此stock_characteristics包含超过1000万行).当我们获取整个结果时,库存和特征之间的关联可能会变慢.
第二种选择.
我按如下方式重写了我的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
}
Run Code Online (Sandbox Code Playgroud)
特点-同上和
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;
}
Run Code Online (Sandbox Code Playgroud)
为了获得我的结果集,我只传递了一组特征.例如,如果将特征传递为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();
}
Run Code Online (Sandbox Code Playgroud)
在这里,您可以看到在库存和特征之间执行连接查询,这可能会减慢速度和速度
这是我的第二个选项的示例代码
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();
}
Run Code Online (Sandbox Code Playgroud)
作为一个程序观点,哪个是最佳选择?或者我应该使用哪一个以获得更好的性能?
我认为你应该在休眠中映射实体之间的所有关系。如果您想使用 hql 和条件,它将有所帮助,否则您将无法在实体之间进行联接。
为了提高性能,请将所有映射标记为 LAZY 并阅读以下内容:
我经常使用 MS SQL Server 并检查慢速查询的执行计划,以确保我的查询有良好的索引。对于 mysql,您可以使用“显示索引”