HIBERNATE知识复习记录4-HQL和QBC

  Hibernate中共提供了三种检索方式:HQL(Hibernate Query Language)、QBC、QBE(Query By Example)。

  HQL 是Hibernate Query Language的简写,即hibernate查询语言:HQL采用面向对象的查询方式。

  QBC(Query By Criteria) API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Expresson类组成,它支持在运行时动态生成查询语句。

  HQL 查询包括以下步骤:

  1. 获取Hibernate Session对象。
  2. 编写HQL语句
  3. 以HQL语句作为参数,调用Session的createQuery方法创建查询对象。
  4. 如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值。
  5. 调用Query对象的list()或uniqueResult()方法返回查询结果列表(持久化实体集)

  QBC检索步骤:

  1.调用Session的createCriteria()方法创建一个Criteria对象。

  2.设定查询条件。Restrictions类提供了一系列用于设定查询条件的静态方法

  这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。

  Criteria的add()方法用于加入查询条件。

  3.调用Criteria的list()方法执行查询语句。该方法返回List类型的查询结果,在

  List集合中存放了符合查询条件的持久化对象。

  下面列出我学习的代码。

  Department类

package oracle.hqlqbc;

import java.util.HashSet;
import java.util.Set;

public class Department {
    private Integer id;
    private String name;

    private Set<Employee> emps = new HashSet<>();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Department [id=");
        builder.append(id);
        builder.append(", name=");
        builder.append(name);
        builder.append(", empsSize=");
        builder.append(emps.size());
        builder.append("]");
        return builder.toString();
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Employee> getEmps() {
        return emps;
    }

    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }
}

  Employee类

package oracle.hqlqbc;

public class Employee {
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Employee [id=");
        builder.append(id);
        builder.append(", name=");
        builder.append(name);
        builder.append(", salary=");
        builder.append(salary);
        builder.append(", email=");
        builder.append(email);
        builder.append(", deptId=");
        builder.append(dept.getId());
        builder.append("]");
        return builder.toString();
    }

    private Integer id;
    private String name;
    private float salary;
    private String email;

    private Department dept;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getSalary() {
        return salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

    public Employee(float salary, String email, Department dept) {
        super();
        this.salary = salary;
        this.email = email;
        this.dept = dept;
    }

    public Employee() {
    }
}

  Department.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-29 2:43:46 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="oracle.test">
    <class name="Department" table="DEPARTMENT">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

        <set name="emps" table="EMPLOYEE" inverse="true" lazy="true">
            <key><column name="DEPT_ID" /></key>
            <one-to-many class="Employee" />
        </set>
    </class>
</hibernate-mapping>

  Employee.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-7-29 2:43:46 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="oracle.test">
    <class name="Employee" table="EMPLOYEE">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

        <property name="salary" type="float">
            <column name="SALARY" />
        </property>

        <property name="email" type="java.lang.String">
            <column name="EMAIL" />
        </property>

        <many-to-one name="dept" class="Department" fetch="join"><!-- join select subselect-->
            <column name="DEPT_ID" />
        </many-to-one>
    </class>

    <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
</hibernate-mapping>

  具体用法的例子:

package oracle.hqlqbc;

import java.util.Arrays;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import oracle.hqlqbc.Department;
import oracle.hqlqbc.Employee;

public class HibernateTest {
    private SessionFactory sessionFactory;

    private Session session;

    private Transaction transaction;

    @Before
    public void init()
    {
        System.out.println("init");

        // 1. 创建一个SessionFactory对象
        sessionFactory = null;
        Configuration configuration = new Configuration().configure();

        // before 4.0
//        sessionFactory = configuration.buildSessionFactory();

        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
                                                                      .buildServiceRegistry();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        // 2. 创建一个Session 对象
        session = sessionFactory.openSession();

        // 3. 开启事务
        transaction = session.beginTransaction();

    }

    @After
    public void destory()
    {
        System.out.println("destory");
        // 5. 提交事务
        transaction.commit();

        // 6. 关闭Session
        session.close();

        // 7. 关闭SesssionFactory
        sessionFactory.close();
    }

    @Test
    public void testNamedParameter()
    {
        String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";
        Query query = session.createQuery(hql);

        // 可以用命名参数
        query.setFloat("sal", 7000)
            .setString("email", "%A%");

        List<Employee> emps = query.list();
        System.out.println(emps.size());
    }

    @Test
    public void createTable()
    {

    }

    @Test
    public void testHQL()
    {
        // 1. 创建Query对象: 可以加 ORDER BY
        String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND dept = ? ORDER BY e.salary";
        Query query = session.createQuery(hql);

        // 2. 绑定参数
        // Query对象调用setXxx方法支持方法链的编程风格
        Department dept = new Department();
        dept.setId(80);
        // 可以用方法链
        query.setFloat(0, 6000).setString(1, "%A%");
        // 可用用实体
        query.setEntity(2, dept);

        // 3. 执行查询
        List<Employee> employees = query.list();
        System.out.println(employees.size());
    }

    /*
     * 分页查询
     */
    @Test
    public void testPageQuery()
    {
        String hql = "FROM Employee";
        Query query = session.createQuery(hql);

        int pageNo = 3;
        int pageSize = 5;

        List<Employee> emps = query.setFirstResult((pageNo - 1)* pageSize)
                                .setMaxResults(pageSize).list();
        System.out.println(emps);
    }

    /*
     * 命名查询
     */
    @Test
    public void namedQuery()
    {
        Query query = session.getNamedQuery("salaryEmps");
        List<Employee> emps = query.setFloat("minSal", 5000)
                                .setFloat("maxSal", 10000)
                                .list();
        System.out.println(emps.size());
    }

    /*
     * 投影查询1: 操作数组
     */
    @Test
    public void testPropertyQuery()
    {
        String hql = "SELECT e.email, e.salary FROM Employee e where e.dept = :dept";
        Query query = session.createQuery(hql);

        Department dept = new Department();
        dept.setId(80);

        List<Object[]> result = query.setEntity("dept", dept)
                                    .list();
        for(Object[] objs: result)
        {
            System.out.println(Arrays.asList(objs));
        }
    }

    /*
     * 投影查询2: 操作entity:使用构造器
     */
    @Test
    public void testPropertyQuery2()
    {
        String hql = "SELECT new Employee(e.salary, e.email, e.dept) FROM Employee e where e.dept = :dept";
        Query query = session.createQuery(hql);

        Department dept = new Department();
        dept.setId(80);

        List<Employee> result = query.setEntity("dept", dept).list();
        for(Employee emp: result)
        {
            System.out.println(emp.getId() + ", " + emp.getEmail() + ", " + emp.getSalary() + ", " + emp.getDept());
        }

    }

    /*
     * 报表查询: 可以使用聚合函数
     */
    @Test
    public void testGroupBy()
    {
        String hql = "SELECT min(e.salary), max(e.salary) FROM Employee e "
                + "group by e.dept having min(salary) > :minSal";
        Query query = session.createQuery(hql).setFloat("minSal", 5000);
        List<Object[]> result = query.list();

        for(Object[] objs: result)
        {
            System.out.println(Arrays.asList(objs));
        }
    }

    /*
     * HQL 会忽略配置文件中的fetch=join的设置,如果想用,就在代码中直接写
     * 迫切左外连接:返回department,注意去重
     */
    @Test
    public void testLeftJoinFetch()
    {
        String hql = "SELECT DISTINCT d FROM Department d INNER JOIN FETCH d.emps";
        Query query = session.createQuery(hql);

        // 集合去重
//        new ArrayList<>(new HashSet<>(Collection c));

        List<Department> depts = query.list();
        System.out.println(depts.size());

        for(Department dept: depts)
        {
            System.out.println(dept.getName() + ", " + dept.getEmps().size());
        }
    }

    /*
     * 默认返回对象数组,注意去重,
     */
    @Test
    public void testLeftJoin()
    {
        // 这样返回的Employee未被初始化
        String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
        Query query = session.createQuery(hql);

        /*List<Object[]> result = query.list();
        System.out.println(result);

        for(Object[] objs: result)
        {
            System.out.println(Arrays.asList(objs));
        }*/

        List<Department> depts = query.list();
        System.out.println(depts.size());
        for(Department dept: depts)
        {
            System.out.println(dept.getName());
        }
    }

    @Test
    public void testLeftJoinFetch2()
    {
        String hql = "SELECT e FROM Employee e INNER JOIN FETCH e.dept";
        Query query = session.createQuery(hql);

        List<Employee> emps = query.list();
        System.out.println(emps.size());

        for(Employee emp: emps)
        {
            System.out.println(emp.getName() + ", " + emp.getDept().getName());
        }
    }

    @Test
    public void testQBCQuery()
    {
        Criteria criteria = session.createCriteria(Employee.class);
        criteria.add(Restrictions.eq("email", "SKUMAR"));
        criteria.add(Restrictions.gt("salary", 5000f));
        Employee employee = (Employee) criteria.uniqueResult();
        System.out.println(employee);
    }

    @Test
    public void testQBCQuery2()
    {
        Criteria criteria = session.createCriteria(Employee.class);
        // 1. AND: 使用Conjunction表示,本身就是一个Criterion对象
        // 且其中还可以添加Criterion对象
        Conjunction conjunction = Restrictions.conjunction();
        conjunction.add(Restrictions.like("name", "a", MatchMode.ANYWHERE));

        Department dept = new Department();
        dept.setId(80);
        conjunction.add(Restrictions.eq("dept", dept));

        System.out.println(conjunction);

        // or
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(Restrictions.ge("salary", 6000));
        disjunction.add(Restrictions.isNotNull("email"));
        criteria.add(conjunction);
        criteria.add(disjunction);

        criteria.list();
    }

    @Test
    public void testQBCQuery3()
    {
        Criteria criteria = session.createCriteria(Employee.class);
        // 统计查询
        criteria.setProjection(Projections.max("salary"));

        System.out.println(criteria.uniqueResult());
    }

    @Test
    public void testQBCQuery4()
    {
        Criteria criteria = session.createCriteria(Employee.class);
        criteria.addOrder(Order.asc("salary"));
        criteria.addOrder(Order.desc("email"));

        int pageSize = 5;
        int pageNo = 3;
        criteria.setFirstResult((pageNo - 1) * pageSize)
            .setMaxResults(pageSize).list();
    }

    @Test
    public void testNativeSQL()
    {
        String sql = "INSERT INTO department VALUES(?, ?)";
        Query query = session.createSQLQuery(sql);
        query.setInteger(0, 280)
             .setString(1, "ATGUIGU")
             .executeUpdate();
    }

    @Test
    public void testHQLUpdate()
    {
        String hql = "DELETE FROM Department d where d.id = :id";
        session.createQuery(hql).setInteger("id", 280).executeUpdate();
    }
}

  好了,例子都在上面,自己也复习了一遍,有了一个初步的印象,本文仅供入门了解,更深入的内容查看相关文章学习。

原文地址:https://www.cnblogs.com/liunianfeiyu/p/8722154.html

时间: 2024-10-14 08:19:59

HIBERNATE知识复习记录4-HQL和QBC的相关文章

Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)

1.非集成Spring hibernate的检索方式,主要有以下五种. 1.导航对象图检索方式.(根据已经加载的对象,导航到其他对象.) 2.OID检索方式.(按照对象的OID来检索对象.) 3.HQL检索方式.(使用面向对象的HQL查询语言.) 4.QBC检索方式.(使用QBC(Qurey By Criteria) API来检索对象.) 5.本地SQL检索方式.(使用本地数据库的SQL查询语句.) 1.导航对象图检索方式 利用类与类之间的关系来检索对象.譬如我们要查找一份订单,就可以由订单对象

Hibernate —— HQL、QBC检索方式

一.HQL 检索方式 以双向的一对多来测试 HQL 检索方式.以 Department 和 Employee 为例. 建表语句: CREATE TABLE department ( dept_id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, dept_name VARCHAR(50) ); CREATE INDEX FK_8hf3vewo7w3v9doungcc51wwy ON department (dept_id); CREATE TABLE e

hibernate 的相关记录

清理 session 缓存 1. flush:使数据表中的记录和session缓存中的对象的状态保持一致,为了保存一致,则可能会发送相应的SQL 001. 在 Transaction 的 commit() 方法中:先调用 session 的 flush 方法,再提交事务 002. flash 方法可能会发送 SQL 语句,但是不会提交事务 003. 注意: 在未提交事务或显示调用 session.flush() 方法,也有可能会进行 flush 操作: 1. 执行 HQL 或 QBC 查询,会先

hibernate学习系列-----(4)hibernate基本查询上篇:HQL基本查询

紧接着上一篇,今天继续hibernate的学习总结,来聊一聊hibernate的基本查询方法,先说说HQL(hibernate Query Language):它是官方推荐的查询语言.在开始写代码之前,看看需要做哪些准备工作吧,首先,在我们的学生类中新增一个属性"clazz",其实不加也可以,接着,我们需要重写Student.java类中的toString()方法,代码如下: /** * 重写toString方法 */ @Override public String toString(

php高级进阶系列文章--第二篇(PHP基础知识复习)

php基础知识复习 本文中对于简单的知识点只会提及一下(例如什么控制结构什么的),对于较有难度的详细复习下(例如面向对象的反射等等) 再次申明,本系列文章不是从最基础的开始复习,对于零基础的可能不适用,本文的初衷是我要准备攻读源码,在攻读前将之前的知识牢固下,太过简单的就写在文中了 1,echo print echo 可以输出一个或者多个字符串 print 只可以输出一个字符串,返回值总为1 2,PHP7中的组合比较符 echo 1 <==> 1 // 0 echo 1 <==>

hibernate框架学习之数据查询(QBC)

lQBC(Query By Criteria)是一种Hibernate中使用面向对象的格式进行查询的计数 lQBC查询方式步骤 ?获取Session对象 ?初始化Criteria对象(使用Session对象创建) ?由Session对象创建 ?传入要查询的数据模型类 ?添加各种查询条件 ?执行查询返回结果(返回单条数据或集合数据) lQBC查询格式非常简单,更符合编程人员的习惯 ?Criteria对象用于由Session对象创建,传入要查询的PO类 ?Criteria c = s.createC

PE知识复习之PE新增节

PE知识复习之PE新增节 一丶为什么新增节.以及新增节的步骤 例如前几讲.我们的PE文件在空白区可以添加代码.但是这样是由一个弊端的.因为你的空白区节属性可能是只读的不能执行.如果你修改了属性.那么程序就可能出现问题.所以新增一个节可以实现我们的代码. 等等. 1.新增节的步骤 1.在最后一个节位置添加一个节.如果没有空白位置.自己需要给扩展头扩大.并且自己修正节的偏移. 2.修改文件头中节表个数. 3.添加的新节表修改节表的属性. 节.VirtualAddress .这个成员指定了这个节在内存

PE知识复习之PE的导出表

PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就需要依赖DLL.系统DLL就是Kerner32.dll user32.dll等等.这些都是PE文件. 什么是导出表: 导出表就是当前的PE文件提供了那些函数.给别人用. 举个例子: PE文件相当于一个饭店.那么菜单就是导出表. 导出表解盲: 有人认为exe可执行文件.没有导出表.而DLL有导出表.这

PE知识复习之PE的重定位表

PE知识复习之PE的重定位表 一丶何为重定位 重定位的意思就是修正偏移的意思.  如一个地址位 0x401234 ,Imagebase = 0x400000 . 那么RVA就是 1234.  如果Imagebase 变了成了0x300000, 那么修正之后就是 ImageBase + RVA = 0X300000+1234 = 0x301234. 首先我们知道.一个EXE文件.会调用很多DLL(PE) 有多个PE文件组成. exe文件启动的基址 (ImageBase) 是0x40000. 假设我