Hibernate distinct 查询的多种实现方式
这里只是简单的写两个方式。
一个是使用Criteria
一个是使用HQL Query
一:Criteria (下面的代码用不上事务的处理,代码片段中的事务只是一个为了保证事务的完整性而使用的一个标准格式化的代码片段。为了保持风格的统一,对于查询片段也使用了事务处理格式。虽然Spring本身提供了事务管理,但是对于简单事务来讲,直接处理的效率比较高,可读性与可控性也强一些。)
getHibernateTemplate().execute(
new HibernateCallback<Object>() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Object ret = null;
Transaction tx = session.beginTransaction();
try {
Criteria crit = session.createCriteria(Diary.class);
//
这行将对occasion进行唯一性合并
crit.setProjection(
Projections.distinct(Projections.property("occasion")));
crit.createAlias("mission", "mission", Criteria.LEFT_JOIN);
crit.addOrder(Order.asc("occasion"));
ret = crit.list();
tx.commit();
} catch (Exception e) {
if (null != tx) {
tx.rollback();
}
e.printStackTrace();
if (e instanceof HibernateException)
throw (HibernateException) e;
if (e instanceof SQLException)
throw (SQLException) e;
}
return ret;
};
});
二:HQL Query(关于事务的管理同上。)
getHibernateTemplate().execute(new HibernateCallback<Recommendation>() {
@Override
public Recommendation doInHibernate(Session session)
throws HibernateException, SQLException {
Object ret = null;
Transaction tx = session.beginTransaction();
try {
//
当查询的结果集中只存在Recommendation对象时,distinct将结果集中的相同
//
对象合并成一个,如果left join fetch导致结果集中Recommendation对象与多个其它对象
//
造成查询结果的记录行不相同,则distinct无法对Recommendation对象合并。
String hql = "select
distinct r from Recommendation r ";
hql += " left join fetch r.carries c left join fetch c.diary d ";
hql += " left join fetch r.prospectuses ps left join fetch ps.prospectus p ";
hql += " left join fetch p.policyTerms pt left join fetch pt.cover ";
hql += " where r.status=3503 or r.status=3504 ";
Query q = session.createQuery(hql);
Object lst = q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP).list();
tx.commit();
} catch (Exception e) {
if (null != tx) {
tx.rollback();
}
e.printStackTrace();
if (e instanceof HibernateException)
throw (HibernateException) e;
if (e instanceof SQLException)
throw (SQLException) e;
}
return lst;
}
});
Hibernate用Criteria查询时使用Distinct方法去除重复数据
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like("name", name, MatchMode.ANYWHERE));
criteria.createAlias("perms","p");
criteria.add(Restrictions.in("p.uuid", perms)); //join 查询,出现重复数据
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); //设置ENTITY级的DISTINCT模式,根实体
criteria.list(); //得出去除了重复数据后的结果集
//注:此方法完全正确,如果不成功请查看是否有其它类的方法把criteria.setResultTransformer设成了其它的值。
String sql = "SELECT distinct r.site FROM Report r where r.site.channel.id=8 and r.keyword.group.profile.id="+profileId ;
Query countQuery = createQuery(sql);
List<Site> results = countQuery.setCacheable(true).list();
return results;