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

时间:2023-03-08 23:48:09
Hibernate中的HQL的基本常用小例子,单表查询与多表查询
  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

  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

  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

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

Dept.java

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

最后测试HQL:

Demo.java

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