大家好,在项目中碰到如下问题: 
hibernate 映射表的时候使用联合主键 
例子如下: 
商品表:Item,主键为联合主键ItemId 
代码如下 public class ItemId{  
   @column  
   Long itemId;  
   @column  
   Long userId;  
}  
  
@Table(...)  
public class Item{  
   @Id  
   ItemId id;  
   @column  
   Date createDate;  
   @column  
   boolean deleted;  
   ...  
}  
三个手动创建索引如下: itemId 主键索引 
userId 主键索引 
itemId, userId 联合索引 数据库表为InnerDB 更新一条语句示例如下: public void softDeleteItem(long itemId, long userId){  
session.createQuery("update Item set deleted = :deleted WHERE id=:id")  
           .setParameter("deleted", 1)  
           .setParameter("id", new ItemId(itemId, userId))  
           .executeQuery();  
}  
通过上面的更新语句hibernate产生如下SQL语句 
update item set delete=? where (itemId, userid) = (?, ?) 在后台查询这条sql语句非常耗时,在item表数据量达到百万级级的时候好使就需要2~3秒 
通过查询返回的详细参数可以看到Mysql做全表查询了,而且锁表了,并没有使用索引。 
之后为了解决线上问题,就做出更改如下 public void softDeleteItem(long itemId, long userId){  
session.createQuery("update Item set deleted = :deleted WHERE id.itemId=:itemId AND id.userId = :userId")  
           .setParameter("deleted", 1)  
           .setParameter("itemId", itemId)  
           .setParameter("userId", userId)  
           .executeQuery();  
}  hibernate生成的语句如下: 
update item set delete=? where itemId = ? and userid=? 效率立即上去了,使用了索引,更新只需要毫秒级的时间。 故,两个问题: 1. hibernate为什么会生成 
update item set delete=? where (itemId, userid) = (?, ?) 
而不是 
update item set delete=? where itemId = ? and userid = ? 2. 上面两条sql语句在mysql执行的效率为什么不一样 ? 何解? 
备注: 
Mysql官方文档对行子查询的说明如下: