一、一对多

以班级Classes和学生Student为例:
 
回忆sql语句:

//内链接,两种方式效果一样,查询的是两边都有的数据

SELECT c.*,s.* FROM classes c,student s WHERE s.cid=c.cid;

SELECT c.cname,s.sname FROM classes c INNER JOIN student s ON s.cid=c.cid;

//左外连接,在内链接基础上,左边表有而右边表没有,两种方式等效;
SELECT c.* ,s.* FROM student s LEFT OUTER JOIN classes c ON s.cid=c.cid;
SELECT c.* ,s.* FROM student s LEFT  JOIN classes c ON s.cid=c.cid;

//右外连接,在内链接基础上,右边有而左边无,两种方式等效;
SELECT c.* ,s.* FROM classes c RIGHT  OUTER JOIN student s ON s.cid=c.cid;
SELECT c.* ,s.* FROM classes c RIGHT  JOIN student s ON s.cid=c.cid;

 
HQL语句:
//查询所有:
from Classes c,Student s where c.cid=s.classes.cid;
//选择某些属性查询
select c.cname,s.sname from Classes c,Student s where c.cid=s.classes.cid;
//选择某些属性,封装为bean查询;
select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  from Classes c,Student s where c.cid=s.classes.cid;
//内链接查询,得到的是两个bean
from Classes c inner join c.students s;
//内敛链接查询,得到的是Classes对象,对象中包含studet集合
from Classes c inner join fetch c.students s;
 
from Student s inner join fetch s.classes c;
 
select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  from Student s inner join  s.classes c ;
 
from Classes c left outer join fetch c.students s;
 
from Student s left outer join fetch s.classes;
 
 
示例代码:
/**
      * 1.一对多
      * sql:select c.*,s.* from classes c,student s where c.cid=s.cid;
      * hql:from Classes c,Student s where c.cid=s.classes.cid,注意与上句的区别;
      * 得到的list是object[],数组中的元素是Classes和Student对象;
      *
      */
     @Test
     public void testOneToMany_EQ(){
          Session   session = sessionFactory.openSession();
         Query query = session.createQuery( "from Classes c,Student s where c.cid=s.classes.cid");
         List list = query.list();
         System. out.println(query.list().size());
         session.close();
     }
     
     /**
      * 2.带属性的查询;
      * list中装的是object[];
      */
     @Test
     public void testOneToMany_EQ_Property(){
          Session   session = sessionFactory.openSession();
         Query query = session.createQuery( "select c.cname,s.sname from Classes c,Student s where c.cid=s.classes.cid");
         query.list();
         session.close();
     }
     /**
      * 3.带属性查询,将查询结果封装成一个bean;
      * 得到的list中装的是classView对象;
      */
     @Test
     public void testOneToMany_EQ_Property_Constructor(){
          Session   session = sessionFactory.openSession();
         Query query = session.createQuery( "select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname) " +
                "from Classes c,Student s where c.cid=s.classes.cid");
         List list = query.list();
        
         session.close();
     }
     
     /**
      * 4.内连接
      * 结果与例子1一样;
      */
     @Test
     public void testOneToMany_InnerJoin_Query(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Classes c inner join c.students s");
         Query query = session.createQuery(buffer.toString());
         query.list();
         session.close();
     }
     
     /**
      * 5.迫切内连接1:获取所有有学生的班级及班级下的学生;
      * 要想得到的集合中装的Classes对象,对象中set集合中装student,可以使用迫切内链接。
      *
      */
     @Test
     public void testOneToMany_InnerJoin_Fetch_Query_1(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Classes c inner join fetch c.students s");
         Query query = session.createQuery(buffer.toString());
         List list = query.list();
         session.close();
     }
     
     /**
      * 6.迫切内连接2
      * 从学生端出发;
      */
     @Test
     public void testOneToMany_InnerJoin_Fetch_Query_2(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Student s inner join fetch s.classes c");
         Query query = session.createQuery(buffer.toString());
         query.list();
         session.close();
     }
     
     /**
      * 7.迫切内连接3:获取属性,封装结果;
      * select new cn.itheima03.hibernate.domain.ClassView(c.cname,s.sname)
      *   from Student s inner join fetch s.classes c;
      * 上述的 hql语句会报错,因为from后面想要的结构和select想要的结构是冲突的,所以
          如果在from后面加fetch,不能写select语句,如果加select,不能写fetch,两者只能选择其一
      *
      */
     @Test
     public void testOneToMany_InnerJoin_Fetch_Query_Property(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
           //下面的写法不对;
//        buffer.append("select new cn.itheima03.hibernate.domain.ClassView(c.cname,s.sname) " +
//                 " from Student s inner join fetch s.classes c");
          
           //不要fetch;
          buffer.append( "select new cn.itheima03.hibernate.domain.ClassesView(c.cname,s.sname)  " +
           "  from Student s inner join  s.classes c " );
          
         Query query = session.createQuery(buffer.toString());
         List list = query.list();
         session.close();
     }
     
     /**
      * 8.迫切左外连接
      * 从班级出发,得到班级对应的学生
      */
     @Test
     public void testOneToMany_LeftJoin_Fetch(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Classes c left outer join fetch c.students s");
         Query query = session.createQuery(buffer.toString());
         List<Classes> list = query.list();
        
         for (Classes classes : list) {
               System. out.println("classes:" +classes.getCname());
              Set<Student> students = classes.getStudents();
               for (Student student : students) {
                   System. out.println("     student:" +student.getSname());
              }
          }
        
         session.close();
     }
     
     /**
      * 9.迫切左外连接2
      * 从学生出发,得到对应的班级
      */
     @Test
     public void testOneToMany_RightJoin_Fetch(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Student s left outer join fetch s.classes ");
         Query query = session.createQuery(buffer.toString());
         List<Student> list = query.list();
        
         for (Student student : list) {
               System. out.println("student:" +student.getSname());
               if (student.getClasses()!=null) {
                   System. out.println("     " +student.getClasses().getCname());
              }
          }
        
         session.close();
     }
 
 
二。多对多
学生Student和课程Course为例:
Student里有装Course的set集合,Course里也有装Student的set集合;
多对多与一对多操作差不多
     /**
      * 1.得到所有的学生以及其对应的课程
      * 从学生端出发
      * list装的是学生;
      */
     @Test
     public void testManyToMany_LeftJoin_Fecth(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Student s left outer join fetch s.courses");
         Query query = session.createQuery(buffer.toString());
         List list = query.list();
         session.close();
     }
     /**
      * 2.得到所有的课程及课程下对应的学生;
      * list装的是课程
      */
     @Test
     public void testManyToMany_LeftJoin_Fecth_2(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Course c left outer join fetch c.students s");
         Query query = session.createQuery(buffer.toString());
         query.list();
         session.close();
     }
     
     /**
      * 3.一对多和多对多的结合
      * 得到所有班级下的所有学生以及所有学生下的所有课程;
      * 从班级出发
      */
     @Test
     public void testManyToManyAndOneToMany(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Classes c left outer join fetch" +
                    " c.students s left outer join fetch s.courses");
          
         Query query = session.createQuery(buffer.toString());
         List<Classes> classeList = query.list();
         //去掉集合中的重复元素
         Set<Classes> sets = new HashSet<Classes>(classeList);
         classeList = new ArrayList<Classes>(sets);
        
         System. out.println(classeList.size());
         for(Classes classes:classeList){//遍历班级
          System. out.println(classes.getCname());
          Set<Student> students = classes.getStudents();//得到班级下的学生
           for(Student student:students){//遍历学生
               System. out.println(student.getSname());
               Set<Course> courses = student.getCourses();
                for(Course course:courses){//遍历学生下的课程
                   System. out.println(course.getCname());
               }
          }
         }
         session.close();
     }
     /**
      * 从中间表出发,班级有学生,学生修课程,故从学生角度出发进行查询;
      */
     @Test
     public void testManyToManyAndOneToMany_2(){
          Session   session = sessionFactory.openSession();
          StringBuffer buffer = new StringBuffer();
          buffer.append( "from Student s left outer join fetch s.classes c 
                           left outer join fetch s.courses cc");
         Query query = session.createQuery(buffer.toString());
         List<Student> studentList = query.list();
         for(Student student:studentList){
          System. out.println(student.getSname());
          Classes classes = student.getClasses();
          System. out.println(classes.getCname());
          Set<Course> courses = student.getCourses();
           for(Course course:courses){
               System. out.println(course.getCname());
          }
         }
         session.close();
     }
     
     /*******************************************************************************/
        /**
         * 面向对象的查询
         */
           @Test
           public void testQueryCriteria(){
              Session   session = sessionFactory.openSession();
              List<Classes>  classesList = session.createCriteria(Classes.class).list() ;
              System. out.println(classesList.size());
              session.close();
          }
          
           @Test
           public void testQueryCriteria_Where(){
              Session   session = sessionFactory.openSession();
              Classes classes = (Classes)session.createCriteria(Classes.class).add(Restrictions.eq("cid" , 1L)).uniqueResult();
              System. out.println(classes.getCname());
              session.close();
          }
}
 
总结:
无论是一对多还是多对多,hql语句中含有fetch时,得到的list装的是From 后面的对象,对象中可能有相关联对象的集合或者对象;

HQL之多表查询(一对多和多对多)的更多相关文章

  1. django(3) 一对多跨表查询、ajax、多对多

    1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询hos ...

  2. django ORM模型表的一对多、多对多关系、万能双下划线查询

    一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...

  3. Mybatis_resultMap的关联方式实现多表查询(一对多)

    a)在 ClazzMapper.xml 中定义多表连接查询 SQL 语句, 一次性查到需要的所有数据, 包括对应学生的信息. b)通过<resultMap>定义映射关系, 并通过<c ...

  4. 2.1、Hibernate多表操作--一对多、多对一、多对多。

    一.什么是一对一.一对多.多对一及多对多关系(以简单的学生和老师的关系为例来说): 1.一对一:学生具有学号和姓名(假定没有同名的学生)这两个属性,那么我知道了学生的学号也就能找到对应的学生姓名,如果 ...

  5. Mybatis表关联一对多、多对一、多对多

    项目工程结构如下: 1. 搭建MyBatis框架环境 首先需要引入两个包:mybatis.jar 和 sqljdbc42.jar包 若分页需要导入两个包:pagehelper-5.1.0.jar 和 ...

  6. django(八)之数据库表的一对多,多对多表-增删改查

    单表操作 表记录的添加 方式一: Book() b=Book(name="python基础",price=99,author="yuan",pub_date=& ...

  7. SSH框架的多表查询和增删查改 (方法一)中

    原创作品,允许转载,转载时请务必标明作者信息和声明本文章==>http://www.cnblogs.com/zhu520/p/7774144.html   这边文章是接的刚刚前一遍的基础上敲的  ...

  8. Django多表查询

    一.前言 1.什么是ORM? ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候, ...

  9. .NetCore中EFCore的使用整理(二)-关联表查询

    EF常用处理关联加载的方式有3中:延迟加载(Lazy Loading).贪婪加载 (Eager Loading)以及显示加载. 一.EF Core  1.1 1.当前的版本,还不支持延迟加载(Lazy ...

随机推荐

  1. Z.XML第二次迭代分数分配

    这是一篇简介的日志. 它关于二轮迭代Z-XML团队7名成员的分数分配. 每名成员的工作内容与之前的任务分工相同,即,大家都非常好的完成了计划的工作. 按照最初设定的分数分配原则,在今晚大家吃全家桶之前 ...

  2. IIS上发布WCF发布服务,访问不到

    1 环境是IIS7,发布WCF发布服务,访问不到. 一种原因站点自动生成“程序应用池”和站点的Framwork版本不一致. 解决的办法:新建一个“程序应用池”,然后站点指向这个新建的“程序应用池”

  3. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  4. HDU 1796 How many integers can you find 容斥入门

    How many integers can you find Problem Description   Now you get a number N, and a M-integers set, y ...

  5. loj 1013(LCS+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25839 思路:第一小问可以很快求出了,两个字符串的长度-LCS,然 ...

  6. Windbg 双机代码同步调试设置

    Windbg的设置 Windbg的设置 Windbg本身可以直接从微软的网站上下载下载地址:http://www.microsoft.com/whdc/devtools/debugging/defau ...

  7. 【练习】ViewPager标签滑动

    效果图: 布局: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:a ...

  8. xcode命令行编译时:codesign命令,抛出“User interaction is not allowed.”异常 的处理

    之前正常运行的hudson iOS编译服务器slave节点,忽然出现编译失败.发现原因有2个: 第一个原因是编译机上用来签名的用户帐号过期,第二个原因是操作系统和xCode升级造成的. 对于第一个,重 ...

  9. cocos2d CCDictionary

    CCDictionary* dict=CCDictionary::create(); CCString* str1=CCString::create("); CCString* str2=C ...

  10. [Cocos2d-x For WP8]Hello world

    [Cocos2d-x For WP8]Hello world Cocos2d-x For WP8使用C++开发,使用cocos2d-xv0.13同样的接口,Cocos2d-x For WP8的相关项目 ...