论坛首页 Java企业应用论坛

Hibernat Criteria 控制连接方式问题(如:inner join变left outer join)

浏览 12070 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-08-18  
大家好,第一次发贴,望大家多多指教.

问题背景:
我需要用Criteria或DetachedCriteria查一个到多个表的某几个字段.(因为要只查某几个字段,所以用了Projection,不知有没有其他方法?)
DetachedCriteria criteria = DetachedCriteria.forClass(Company.class);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Property.forName("companyName"));
projectionList.add(Property.forName("C.cityName"));
projectionList.add(Property.forName("A.areaName"));
criteria.createAlias("city", "C")
        .createAlias("area", "A")
        .setProjection(projectionList);
return getHibernateTemplate().findByCriteria(criteria);

打印出来的sql语句是:
select .... from company C inner join City C1 on C.city_id=C1.city_Id 
inner join area A on C.area_id=A.area_id;


以前没有用projection时可以用下面的代码来达到生成left outer join sql的效果
DetachedCriteria criteria = DetachedCriteria.forClass(Company.class);
criteria.setFetchMode("city", FetchMode.JOIN);
criteria.setFetchMode("area", FetchMode.JOIN);
return getHibernateTemplate().findByCriteria(criteria);


问题:
1. 怎样才能变成用left outer join查询而不用inner join?
2. 这个问题顺便问问,查一个到多个表的某几个字段时,查询结果是Object[],能不能让它返回要查询的那个对象,而只有要查的几个field有值,其他为空?

望大家能指点一二,谢谢




   发表时间:2007-08-22  
第一个问题不太清楚.
第二个问题只要加一句:
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
就行了!
0 请登录后投票
   发表时间:2007-08-23  
终于有人回复了,谢谢啊 

关于criteria.setResultTransformer(Criteria.ROOT_ENTITY);
我也试过,但返回的结果还是一个Object[],
我还试了其余的几个,除了Criteria.ALIAS_TO_ENTITY_MAP返回一个空的map外,
其他都是返回Object[], 而且也没报错.

关于第一个问题,刚才看了Hibernate3.1.3的doc,发现新加了个
createCriteria(String associationPath, String alias, int joinType)
的接口,多了个joinType的参数,我想应该可以通过设为Criteria.LEFT_JOIN来达到控制join的方式.
现在项目比较紧,迟点再试了.
0 请登录后投票
   发表时间:2007-08-28  
呀,搞错了,应该加criteria.setProjection(null);这一句才是!
0 请登录后投票
   发表时间:2007-08-28  
smalltiger1984 写道
呀,搞错了,应该加criteria.setProjection(null);这一句才是!

那样楼主的那个setProjection(projectionList)就没用了,变成了第二种方式
0 请登录后投票
   发表时间:2007-08-28  
引用
能不能让它返回要查询的那个对象,而只有要查的几个field有值,其他为空?
你觉得这样还能是一个持久化的与数据库一致的对象吗?所以是不可能的。其实绝大部分情况下返回整个对象并没有你想象的那样糟糕。

引用
createCriteria(String associationPath, String alias, int joinType)
DetachedCriteria中没有加入该方法,除非你改源代码。
0 请登录后投票
   发表时间:2007-08-30  
java 代码
  1. /**  
  2.      * detachedCriteria:使用DetachedCriteria构造查询条件  
  3.      * pageSize:每一页需要显示的记录数  
  4.      * startIndex:每一页记录的起始数  
  5.      * return ps:PaginationSupport对分页数据进行处理  
  6.      */  
  7.     public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int pageSize,final int startIndex) {   
  8.         return (PaginationSupport) getHibernateTemplate().execute(new HibernateCallback() {   
  9.             public Object doInHibernate(Session session) throws HibernateException {      
  10.                 Criteria criteria = detachedCriteria.getExecutableCriteria(session);      
  11.                 int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();      
  12.                 criteria.setProjection(null);   
  13.                 criteria.setResultTransformer(Criteria.ROOT_ENTITY);   
  14.                 List items = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();   
  15.                 PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);      
  16.                 return ps;   
  17.             }   
  18.         }, true);   
  19.     }  
这个方法我用了一年了,没发现任何问题!
0 请登录后投票
   发表时间:2007-08-30  
 
c.setProjection(null); 目的是为了获得行数,并设置投影为空,为的是返回List出来,如果不设置setProjection(null)的话,c.list将返回的是行数(int型),而不是所要查询的数据库信息。但是Criteria的ResultTransformer会变成PassThroughResultTransformer,criteria.list的时候可能结果会跟理想的不一样。所以我们还要再c.setResultTransformer(Criteria.ROOT_ENTITY);把结果以Entity的形式返回,而不是Object[]的形式返回。具体的ResultTransformer可以google一下。    
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics