在HIbernate 4中有效地通过id加载多个实体

Pau*_*lor 15 java entity hibernate identifier query-performance

所以我通过id得到了一个特定实体的实例

for(Integer songId:songGroup.getSongIds()) {
   session = HibernateUtil.getSession();
   Song song = (Song) session.get(Song.class,id);
   processSong(song);
}
Run Code Online (Sandbox Code Playgroud)

这会为每个id生成一个sql查询,所以我觉得我应该在一个中执行此操作,但是除了运行查询之外,我找不到在一次调用中获取多个实体的方法.所以我写了一个查询

return (List) session.createCriteria(Song.class)
       .add(Restrictions.in("id",ids)).list();
Run Code Online (Sandbox Code Playgroud)

但是,如果我启用第二级缓存并不意味着我的旧方法将能够从二级缓存返回对象(如果之前已经请求过),但我的查询将始终转到数据库.

这样做的正确方法是什么?

sha*_*kan 10

你在这里要做的是让Hibernate为你的Criteria做一些特殊的案例处理,这是一个很多问题.

你必须自己做,但这并不难.使用SessionFactory.getCache(),您可以获得对缓存对象的实际存储的引用.执行以下操作:

for (Long id : allRequiredIds) {
  if (!sessionFactory.getCache().containsEntity(Song.class, id)) {
    idsToQueryDatabaseFor.add(id)
  } else {
    songs.add(session.get(Song.class, id));
  }
}

List<Song> fetchedSongs = session.createCriteria(Song.class).add(Restrictions.in("id",idsToQueryDatabaseFor).list();
songs.addAll(fetchedSongs);
Run Code Online (Sandbox Code Playgroud)

然后从那里检索高速缓存中的歌曲,以及那些没有被单个拉出的歌曲select.