• Hibernate中的HQL的基本常用小例子,单表查询与多表查询


    [cpp] view plain copy
     
    1. <span style="font-size:24px;color:#3366ff;">本文章实现HQL的以下功能:</span>  
    2. /** 
    3.  * hql语法: 
    4.  *   1)单表查询 
    5.  *       1.1 全表查询 
    6.  *       1.2 指定字段查询 
    7.  *       1.3 排除重复记录 
    8.  *       1.4 条件查询(重点) 
    9.  *       1.5 分页查询 
    10.  *       1.6 聚合查询 
    11.  *       1.7 查询排序 
    12.  *       1.8 分组查询 
    13.  *       1.9 分组后筛选 
    14.  *        
    15.  *   2)多表查询 
    16.  *       1.1 内连接 
    17.  *       1.2 左外连接/右外连接    
    18. */  
    19. </span>  


    首先要配置Hibernate的xml文件,让两个数据库建立联系,是一对多的映射连接

    Employee.hbm.xml

    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
    3. <hibernate-mapping>  
    4.     <class name="star.july.d_hql.Employee" table="employee">  
    5.         <id name="id">  
    6.             <generator class="native"></generator>  
    7.         </id>  
    8.         <property name="name"></property>  
    9.         <property name="gender"></property>  
    10.         <property name="title"></property>  
    11.         <property name="email"></property>  
    12.         <property name="salary"></property>  
    13.         <many-to-one name="dept"   
    14.             class="star.july.d_hql.Dept"  
    15.             column="deptId"  
    16.         ></many-to-one>  
    17.     </class>  
    18. </hibernate-mapping>  

    Dept.hbm.xml

    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
    3. <hibernate-mapping>  
    4.     <class name="star.july.d_hql.Dept" table="dept">  
    5.         <id name="id">  
    6.             <generator class="native"></generator>  
    7.         </id>  
    8.         <property name="deptName" column="name">  
    9.         </property>  
    10.         <set name="employee"  
    11.             cascade="all"  
    12.         >  
    13.         <key column="id"></key>  
    14.             <one-to-many class="star.july.d_hql.Employee"  
    15.             />  
    16.         </set>  
    17.     </class>  
    18. </hibernate-mapping>  


    再建立两个实体类

    Employee.java

    [cpp] view plain copy
     
    1. package star.july.d_hql;  
    2.   
    3. public class Employee {  
    4.     private int id;  
    5.     private String name;  
    6.     private String gender;  
    7.     private String title;  
    8.     private String email;  
    9.     private double salary;  
    10.     private Dept dept = new Dept();  
    11.       
    12.     public Dept getDept() {  
    13.         return dept;  
    14.     }  
    15.     public void setDept(Dept dept) {  
    16.         this.dept = dept;  
    17.     }  
    18.     public int getId() {  
    19.         return id;  
    20.     }  
    21.     public void setId(int id) {  
    22.         this.id = id;  
    23.     }  
    24.     public String getName() {  
    25.         return name;  
    26.     }  
    27.     public void setName(String name) {  
    28.         this.name = name;  
    29.     }  
    30.     public String getGender() {  
    31.         return gender;  
    32.     }  
    33.     public void setGender(String gender) {  
    34.         this.gender = gender;  
    35.     }  
    36.     public String getTitle() {  
    37.         return title;  
    38.     }  
    39.     public void setTitle(String title) {  
    40.         this.title = title;  
    41.     }  
    42.     public String getEmail() {  
    43.         return email;  
    44.     }  
    45.     public void setEmail(String email) {  
    46.         this.email = email;  
    47.     }  
    48.     public double getSalary() {  
    49.         return salary;  
    50.     }  
    51.     public void setSalary(double salary) {  
    52.         this.salary = salary;  
    53.     }  
    54.     @Override  
    55.     public String toString() {  
    56.         return "Employee [id=" + id + ", name=" + name + ", gender=" + gender  
    57.                 + ", title=" + title + ", email=" + email + ", salary="  
    58.                 + salary + "]";  
    59.     }  
    60.       
    61.       
    62. }  


    Dept.java

    [java] view plain copy
     
    1. package star.july.d_hql;  
    2.   
    3. import java.util.HashSet;  
    4. import java.util.Set;  
    5.   
    6. public class Dept {  
    7.     private int id;  
    8.     private String deptName;  
    9.     private Set<Employee> employee = new HashSet<Employee>();  
    10.     public int getId() {  
    11.         return id;  
    12.     }  
    13.     public void setId(int id) {  
    14.         this.id = id;  
    15.     }  
    16.     public String getDeptName() {  
    17.         return deptName;  
    18.     }  
    19.     public void setDeptName(String deptName) {  
    20.         this.deptName = deptName;  
    21.     }  
    22.     public Set<Employee> getEmployee() {  
    23.         return employee;  
    24.     }  
    25.     public void setEmployee(Set<Employee> employee) {  
    26.         this.employee = employee;  
    27.     }  
    28.       
    29.       
    30. }     


    最后测试HQL:

    Demo.java

    [java] view plain copy
     
    1. package star.july.d_hql;  
    2.   
    3. import java.util.List;  
    4. import java.util.Set;  
    5.   
    6. import org.hibernate.Query;  
    7. import org.hibernate.Session;  
    8. import org.hibernate.Transaction;  
    9. import org.junit.Test;  
    10.   
    11. import star.july.util.HibernateUtil;  
    12. /** 
    13.  * hql语法: 
    14.  *   1)单表查询 
    15.  *       1.1 全表查询 
    16.  *       1.2 指定字段查询 
    17.  *       1.3 排除重复记录 
    18.  *       1.4 条件查询(重点) 
    19.  *       1.5 分页查询 
    20.  *       1.6 聚合查询 
    21.  *       1.7 查询排序 
    22.  *       1.8 分组查询 
    23.  *       1.9 分组后筛选 
    24.  *        
    25.  *   2)多表查询 
    26.  *       1.1 内连接 
    27.  *       1.2 左外连接/右外连接    
    28.  *       * 
    29.  */        
    30. public class Demo {  
    31.     @Test  
    32.     public void test(){  
    33.         Session session = HibernateUtil.getSession();  
    34.         Transaction ts = session.getTransaction();  
    35.         try{  
    36.             ts.begin();  
    37.             //hql基本语法  
    38.             //1、创建一个Query对象  
    39.             //参数:需要执行的hql语句  
    40.             String hql = "select e from Employee e where id = 1";  
    41.             Query query = session.createQuery(hql);  
    42.             //2、执行查询  
    43.             //2、1封装所有  
    44.             List<Employee> emp = query.list();  
    45.             for(Employee e : emp){  
    46.                 System.out.println(e);  
    47.             }  
    48.               
    49.             //2、2 封装一个(第一个)  
    50.             Employee empl = (Employee)query.uniqueResult();  
    51.             System.out.println(empl);  
    52.               
    53.             ts.commit();  
    54.               
    55.         }catch(Exception e){  
    56.             e.printStackTrace();  
    57.             ts.rollback();  
    58.         }  
    59.     }  
    60.       
    61.       
    62.     //单表查询  
    63.     @Test  
    64.     public void test3(){  
    65.         Session session = HibernateUtil.getSession();  
    66.         Transaction ts = session.getTransaction();  
    67.         try{  
    68.             ts.begin();  
    69. //           *  1)单表查询  
    70. //           *       1.1 全表查询  
    71.         //  String hql = "from star.july.d_hql.Employee";  
    72.             //auto-import:自动到爆,自动在每个包下面搜索对应这个类的包,多个同名类的报会冲突  
    73. //          String hql = "select e from Employee e";  
    74.               
    75. //           *       1.2 指定字段查询  
    76.             //返回对象数组  
    77. //          String hql = "select e.name,e.title from Employee e";  
    78.               
    79. //           *       1.3 排除重复记录  
    80. //          String hql = "select distinct(e.gender) from Employee e";  
    81.               
    82. //           *       1.4 条件查询(重点)(where)  
    83.             //逻辑条件:and  or  
    84.             // 模糊查询:like: % _  
    85.             //比较查询: < > <= >= between and <>  
    86.             //判空查询: is null ,is not null, ='',<>'';  
    87. //          String hql = "select e from Employee e where name like '张%'";  
    88. //          String hql = "select e from Employee e where e.gender is null or e.gender=''";  
    89.               
    90. //           *       1.5 分页查询  
    91.         /*  String hql = "from Employee "; 
    92.             Query query = session.createQuery(hql); 
    93.             //设置开始读取行 
    94.             query.setFirstResult(0); 
    95.             //每页读取多少条信息 
    96.             query.setMaxResults(3);*/  
    97.               
    98. //           *       1.6 聚合查询  
    99.             //avg,count,max,min,uniqueResult  
    100. //          String hql = "select max(e.salary) from Employee e";  
    101.               
    102. //           *       1.7 查询排序  
    103.             //order by  
    104.             //desc:降序  asc:升序  
    105. //          String hql = "select e from Employee e order by id desc ";  
    106.               
    107.               
    108. //           *       1.8 分组查询  
    109. //          String hql = "select e from Employee e group by e.gender";  
    110.           
    111. //           *       1.9 分组后筛选  
    112.             String hql = "select e from Employee e  where e.gender is not null and e.gender<>'' group by e.gender having count(e.gender)>1";  
    113.               
    114.             Query query = session.createQuery(hql);  
    115.               
    116.               
    117.             //集合对象  
    118.             List<Object> e = query.list();  
    119.             for(Object emp : e){  
    120.                 System.out.println(emp);  
    121.             }  
    122.               
    123.               
    124.             //对象数组  
    125.         /*  List<Object[]> objects = query.list(); 
    126.             for(Object[] object : objects){ 
    127.                 for(Object obj:object ){ 
    128.                 System.out.print(obj); 
    129.                 } 
    130.                 System.out.println(); 
    131.             }   */        
    132.               
    133.               
    134.             //封装一个对象  
    135.             /*Object unique = query.uniqueResult(); 
    136.             System.out.println(unique);*/  
    137.               
    138.               
    139.               
    140.             ts.commit();  
    141.         }catch(Exception e){  
    142.             e.printStackTrace();  
    143.             ts.rollback();  
    144.         }  
    145.     }  
    146.       
    147.       
    148.     //多表查询  
    149.         @Test  
    150.         public void test2(){  
    151.             Session session = HibernateUtil.getSession();  
    152.             Transaction ts = session.getTransaction();  
    153.             try{  
    154.                 ts.begin();  
    155.                   
    156.                 /** 
    157.                  *步骤 
    158.                  *1、确定查询哪些对象 
    159.                  *2、确定擦汗寻哪些属性 
    160.                  *3、确定连接条件 
    161.                  *4、业务条件  
    162.                  */  
    163.                 //1、内连接查询  
    164.                 //效果:只有满足条件的数据才会被显示出来  
    165.                 //查询员工及其部门:显示员工名称,部门名称  
    166. //              String hql = "select e.name,d.deptName from Employee e , Dept d where e.dept.id=d.id";  
    167.                 //另一种写法  
    168. //              String hql = "select e.name,d.deptName from Employee e inner join e.dept d";  
    169.                   
    170.                   
    171.                 //左外连接  
    172.                 //效果:优先显示左表,右表的数据匹配显示,不匹配则显示null  
    173.                 //查询所有部门的员工(没有员工的部门也要显示出来)  
    174.                 String hql = "select d.deptName, e.name from Dept d left outer join d.employee e";  
    175.                   
    176.                 //右外连接  
    177. //              String hql = "select d.deptName,e.name from Employee e right outer join e.dept d";  
    178.                 Query query = session.createQuery(hql);  
    179.                   
    180.                 /*List<Object>  object = query.list(); 
    181.                 for(Object obj:object){ 
    182.                     System.out.println(obj); 
    183.                 }*/  
    184.                   
    185.                 List<Object[]> objects = query.list();  
    186.                 for(Object[] object:objects){  
    187.                     for(Object obj : object){  
    188.                         System.out.print(obj);  
    189.                     }  
    190.                     System.out.println();  
    191.                 }  
    192.                   
    193.                   
    194.                   
    195.                   
    196.                 ts.commit();  
    197.                   
    198.             }catch(Exception e){  
    199.                 e.printStackTrace();  
    200.                 ts.rollback();  
    201.             }  
    202.         }  
    203. }  

      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[]类型的,里面包含了查询出来的所有值,剩下的自个儿去处理就行了

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

      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中 传到前台。
          }

      (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()即可。
      复制代码
  • 相关阅读:
    以结构体为键值的map
    Luogu P1251 餐巾计划问题 (最小费用最大流、拆点)
    CodeForces
    CodeForces
    中缀表达式转后转表达式
    CodeForces
    Educational Codeforces Round 100
    2020年12月杂题选做
    2020年11月杂题选做
    CF542E Playing on Graph
  • 原文地址:https://www.cnblogs.com/linjiaxin/p/8067353.html
Copyright © 2020-2023  润新知