利用Hibernate对未做级联关系的表进行连接查询

目前存在的问题:

1. 最初我希望将CmParent和CmChild中的记录全部set入一个包含双方数据属性的普通VO中, 结果失败.
2. Object[] 的length必然是和希望封装成POJO的对象个数是匹配的, 如果通过连接查询, 子表中无记录, 则被set为null.
3. 还是希望能通过HQL实现类似功能.

新建两个表:

sql 代码
  1. — Create table CM_PARENT   
  2. create table CM_PARENT   
  3. (   
  4.   ID   NUMBER not null,   
  5.   NAME VARCHAR2(20)   
  6. );   
  7. alter table CM_PARENT   
  8.   add constraint CPP primary key (ID);   
  9.   
  10. — Create table CM_CHILD   
  11. create table CM_CHILD   
  12. (   
  13.   ID       NUMBER not null,   
  14.   NAME     VARCHAR2(20),   
  15.   PARENTID VARCHAR2(20)   
  16. );   
  17. alter table CM_CHILD   
  18.   add constraint CCP primary key (ID);  

向其中插入测试数据:

sql 代码
  1. insert into CM_PARENT (ID, NAMEvalues (1, ‘como’);   
  2. insert into CM_PARENT (ID, NAMEvalues (2, ‘chenmeng’);   
  3. insert into CM_CHILD (ID, NAME, PARENTID) values (1, ‘como son1’, ‘1’);   
  4. insert into CM_CHILD (ID, NAME, PARENTID) values (2, ‘como son2’, ‘1’);  

执行左外连接查询:

sql 代码
  1. select * from cm_parent cp left outer join cm_child cc on cp.id = cc.parentid  

将获得:

sql 代码
  1. ID NAME                         ID NAME                 PARENTID   
  2. — ——————– ———- ——————– ——————–   
  3.  1 como                          1 como son1            1   
  4.  1 como                          2 como son2            1   
  5.  2 chenmeng                                               

但是在Hibernate中, 如果两个表未做级联,则采用HQL尝试连接查询时会报:

java 代码
  1. org.hibernate.hql.ast.QuerySyntaxException: Path expected for join!  

但是经过试验, 这种情况可以通过Hibernate的SQLQuery折衷解决. 方法如下:

1.对这两个表建立POJO及HBM, 过程略.

2.在DAO中加入方法:

java 代码


  1. public List executeSQLFind(final String sql, final String[] alias, final Class[] clasz) throws DaoException {   
  2.         Session session = getHibernateTemplate().getSessionFactory().openSession();   
  3.         SQLQuery realQuery = session.createSQLQuery(sql);   
  4.         for(int i=0; i
  5.             realQuery.addEntity(alias[i], clasz[i]);   
  6.         }   
  7.         List dataList = realQuery.list();   
  8.         return dataList;   
  9.            
  10.     }  

 在Service层调用:

java 代码
  1. String sql = “select {cp.*}, {cc.*} from cm_parent cp left outer join cm_child cc on cp.id = cc.parentid”;
  2. String[] alias = new String[]{“cp”,“cc”};   
  3. Class[] clasz = new Class[]{CmParent.class, CmChild.class};   
  4. List b = baseDao.executeSQLFind(sql, alias, clasz);  

返回的b为一个元素类型为Object[]的List. 测试如下:

java 代码
  1. for (int i = 0; i < b.size(); i++) {   
  2.     Object[] o = (Object[]) b.get(i);   
  3.     logger.info(“CmParent No.#” + i + ” == “ + ((CmParent)o[0]).getName());   
  4.     if(null != o[1]) {   
  5.         logger.info(“CmChild No.#” + i + ” == “ + ((CmChild)o[1]).getName());   
  6.     } else {   
  7.         logger.info(“CmChild No.#” + i + ” == NULL”);   
  8.     }   
  9. }  

其中的o[0]为封装好的CmParent, o[1]为封装好的CmChild. 如图:

 

发表评论

邮箱地址不会被公开。 必填项已用*标注

昵称 *