一、

Hibernate主要支持两种查询方式:HQL查询和Criteria查询。前者应用较为广发,后者也只是调用封装好的接口。

现在有一个问题,就是实现多表连接查询,且查询结果集不与任何一个实体类对应,怎么解决呢?

举个例子:

现在有两个表,一个users用户表, 一个goods商品表,每个用户可以有多个商品,而一个商品只能对应一个用户。

users表中的字段:userId,userName,telephone,address

goods表中的字段:goodsId,goodsName,userId

现在要实现两表连接查询,查出每个用户所拥有的商品,并把该用户的信息和其商品信息显示出来。

使用Hibernate反向生成的实体类分别是Users和Goods。

有两种方式:

(1)使用传统方式:


String hql="select u.userName, u.telephone, u.address, g.goodsName from Users u, Goods g where u.userId=g.userId";


根据这个查询语句,调用query.list()方法得到一个List值,这个List中的每一个值都是Object[]类型的,里面包含了查询出来的所有值,剩下的自个儿去处理就行了

(2)增加一个映射类

增加一个映射类UsersVoGoods.java,添加需要查询的信息相关的所有属性,本例中添加userName, telephone, address, goodsName。并为这几个属性添加setter和getter方法,增加构造函数,参数与这四个属性对应,那么可以用hql查询方式:


String hql = "select new com.test.UsersVoGoods(u.userName, u.teltphone, u.address, g.goodsName) from Users u, Goods g where u.userId=g.userId";

query.list()的返回值List中的值都是UsersVoGoods型的,直接使用get()就能获取。

其实不增加映射类也是可以的,只需要在Users.java实体类里增加一个构造函数,函数参数还是需要的所有字段,并为这些参数中Users实体原来没有的字段添加属性和getter() setter()即可


二、

以前用sql实现联合查询 是非常简单的事,只需要写sql语句就可以,第一次遇到hibernate要实现多表联合查询的时候还楞了一下。最后看了下资料,才恍然大悟,hibernate实现多表联合查询跟SQL没多大差别。  

   hibernate很多实现都是靠喜欢配关系,但是如果两张表,数据量都非常大的时候,并不合适配关系。

   例如:student表和score表需要做联合查询。

   1)sql: select s.id,s.name,sc.score from student as s,score as sc where s.id = sc.userId;

   (字段都是用的数据库中字段名称)

   2)HQL: select s.id,s.name,sc.score from Student as s,Score as sc where s.id = sc.userId;

   (上面字段都是 javabean的属性)

    如果我们按1)查询的话,必须调用 session.createSQLQuery();方法

    如果按2)查询,还是调用 session.createQuery();

    只是要注意,平时我们查询的时候,例如:“from Student ”查询的结果集 封装的全都是student对象,但是2)执行的结果集里面不是对象,而是一系列数组。需要转换成需要的样式。

下面 是查询的一段代码:

Session session = getHibernateTemplate().getSessionFactory()

   .getCurrentSession();

   StringBuffer sb = new StringBuffer(" select user.username,user.truename,user.sex,user.idnum,user.level,s.sumScore from Score as s,Examuser as user where s.id.userId = user.id ");

   if(score != null){

    if(score.getExamId()!=null && !"".equals(score.getExamId())

      && !"null".equals(score.getExamId())){

     sb.append(" and s.examId =:examId ");

    }

    if(score.getExamPlace()!=null && !"".equals(score.getExamPlace())

      && !"null".equals(score.getExamPlace())){

     sb.append(" and s.examPlace =:examPlace ");

    }

    if(score.getUsername()!=null && !"".equals(score.getUsername())

      && !"null".equals(score.getUsername())){

     sb.append(" and s.username like:username ");

    }

   }

   sb.append(" order by s.sumScore desc ");

   Query q = session.createQuery(sb.toString());

   if(score != null){

    if(score.getExamId()!=null && !"".equals(score.getExamId())

      && !"null".equals(score.getExamId())){

     q.setParameter("examId",score.getExamId());

    }

    if(score.getExamPlace()!=null && !"".equals(score.getExamPlace())

      && !"null".equals(score.getExamPlace())){

     q.setParameter("examPlace",score.getExamPlace());

    }

    if(score.getUsername()!=null && !"".equals(score.getUsername())

      && !"null".equals(score.getUsername())){

     q.setParameter("username","%"+score.getUsername()+"%");

    }

   }

   List list = q.list();

需要将查询的结果集 进行一下转换:

List stuList = scoreService.findAllScore(queryScore, null); // 返回的结果集

   if(stuList != null && stuList.size()>0){

    list = new LinkedList();

    StudentScore st;

    for(int i = 0; i < stuList.size();i++){

     st = new StudentScore();

     Object[] object = (Object[])stuList.get(i);// 每行记录不在是一个对象 而是一个数组

     String userId =  (String)object[0];

     String username =  (String)object[1];

     String truename =  (String)object[2];

     String sex =  (String)object[3];

     String idnum =  (String)object[4];

     String level =  (String)object[5];

     Double sumScore =  Double.parseDouble(String.valueOf(object[6]));

     String paperId =  (String)object[7];

     // 重新封装在一个javabean里面

     st.setUserId(userId);

     st.setUsername(username);

     st.setTruename(truename);

     st.setIdnum(idnum);

     st.setLevel(DictSwitch.getValue("DICT_LEVEL",level));

     st.setSex(DictSwitch.getValue("DICT_SEX",sex));

     st.setPaperId(paperId);

     st.setSumScore(sumScore);

     st.setExamplace(DictSwitch.getValue("DICT_EXAMSTATION",examplace));

     list.add(st); // 最终封装在list中 传到前台。

    }