hibernate检索方式(HQL 检索方式,QBC 检索方式,本地 SQL 检索方式)

hibernate有五种检索方式,这儿用 单向的一对多的映射关系 例子,这儿有后三种的方式;

导航对象图检索方式: 根据已经加载的对象导航到其他对象

OID 检索方式: 按照对象的 OID 来检索对象

HQL 检索方式: 使用面向对象的 HQL 查询语言

QBC 检索方式: 使用 QBC(Query By Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句, 提供了更加面向对象的查询接口.

本地 SQL 检索方式: 使用本地数据库的 SQL 查询语句

建立封装数据库中数据属性的封装类:n-1;

n的一端封装类:

package com.atguigu.hibernate.entities;

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;
    }

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

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

    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }
    @Override
    public String toString() {
        return "Department [id=" + id + "]";
    }

}

1的一端封装的类:

package com.atguigu.hibernate.entities;

public class Employee {
    private Integer id;
    private String name;
    private float salary;
    private String email;

    private Department dept;

    public Employee() {
        super();
    }

    public Employee(String name, float salary, String email,
            Department dept) {
        super();
        this.name = name;
        this.salary = salary;
        this.email = email;
        this.dept = 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;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + "]";
    }

}

在该包下自动生成对用的关系映射文件,只需进行一些修改;

单向的n-1映射关联关系,1的一端,关系映射文件;

<?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 2016-9-26 8:08:56 by Hibernate Tools 3.4.0.CR1 -->

<hibernate-mapping package="com.atguigu.hibernate.entities">

    <class name="Employee" table="LL_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">
            <column name="DEPT_id" />
        </many-to-one>

    </class>

    <!-- 在映射文件中定义命名查询语句 ,书写的位置不在class范围内,注意书写的位置-->
        <query name="salaryemp"><![CDATA[from Employee e where e.salary >:minSal and e.salary <:maxSal]]></query>
</hibernate-mapping>

单向的n-1映射关联关系,n的一端,关系映射文件;

<?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 2016-9-26 8:08:56 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.atguigu.hibernate.entities">

    <class name="Department" table="LL_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="LL_EMPLOYEE" inverse="true" lazy="true">
            <key>
                <column name="DEPT_ID" />
            </key>
            <one-to-many class="Employee" />
        </set>

    </class>
</hibernate-mapping>

在src目录下建立hibernate的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

    <!-- Hibernate 连接数据库的基本信息 -->
    <property name="connection.username">lxn123</property>
    <property name="connection.password">lxn123</property>
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl1</property>

    <!--  -->
    <!-- Hibernate 的基本配置 -->
    <!-- Hibernate 使用的数据库方言 ,是oracle书籍库的基本方言-->
    <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

    <!-- 运行时是否打印 SQL -->
    <property name="show_sql">true</property>

    <!-- 运行时是否格式化 SQL -->
    <property name="format_sql">true</property>

    <!-- 生成数据表的策略 -->
    <property name="hbm2ddl.auto">update</property>

    <!-- 设置 Hibernate 的事务隔离级别 -->
    <property name="connection.isolation">2</property>

    <!-- 删除对象后, 使其 OID 置为 null -->
    <property name="use_identifier_rollback">true</property>

    <!-- 配置 C3P0 数据源,不是开发 这儿就不配置了 -->

    <!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 -->
    <property name="hibernate.jdbc.fetch_size">100</property>

    <!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 -->
    <property name="jdbc.batch_size">30</property>

    <!-- 需要关联的 hibernate 映射文件 .hbm.xml -->
    <mapping resource="com/atguigu/hibernate/entities/Department.hbm.xml"/>
    <mapping resource="com/atguigu/hibernate/entities/Employee.hbm.xml"/>

    </session-factory>
</hibernate-configuration>

建立测试类,进行测试方法;

package com.atguigu.hibernate.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
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.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 com.atguigu.hibernate.entities.Department;
import com.atguigu.hibernate.entities.Employee;

public class HqlTest {

    private static SessionFactory sessionFactory;
    private static Session session;
    private static Transaction transaction;

    @Before
    public void init(){
        Configuration configuration=new Configuration().configure();
        ServiceRegistry serviceRegistry=
                    new ServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .buildServiceRegistry();
        sessionFactory=configuration.buildSessionFactory(serviceRegistry);

        session=sessionFactory.openSession();
        transaction=session.beginTransaction();
    }

    @After
    public void destroy(){
        transaction.commit();
        session.close();
        sessionFactory.close();
    }

    @Test
    //hql也可以进行曾删改的操作
    public void testHQLUpdate(){
        String hql = "DELETE FROM Department d WHERE d.id = :id";

        session.createQuery(hql).setInteger("id", 280)
                                .executeUpdate();
    }

    @Test
    //本地 SQL 检索
    public void testNativeSQL(){
        String sql = "INSERT INTO ll_department VALUES(?, ?)";
        Query query = session.createSQLQuery(sql);

        query.setInteger(0, 280)
             .setString(1, "ATGUIGU")
             .executeUpdate();
    }

    @Test
    //QBC检索, 添加排序,添加翻页方法
    public void testQBC4(){
        Criteria criteria = session.createCriteria(Employee.class);

        //1. 添加排序
        criteria.addOrder(Order.asc("salary"));
        criteria.addOrder(Order.desc("email"));
        List<Employee> empss=criteria.list();
        System.out.println(empss);

        //2. 添加翻页方法
        int pageSize = 5;
        int pageNo = 3;
        List<Employee> emps=criteria.setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize)
                .list();
        System.out.println(emps);
    }

    @Test
    //QBC检索,统计查询
    public void testQBC3(){
        Criteria criteria = session.createCriteria(Employee.class);

        //统计查询: 使用 Projection 来表示: 可以由 Projections 的静态方法得到
        criteria.setProjection(Projections.max("salary"));

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

    @Test
    //QBC检索,AND  OR
    public void testQBC2(){
        Criteria criteria = session.createCriteria(Employee.class);

        //1. AND: 使用 Conjunction 表示
        //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); 

        //2. OR
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(Restrictions.ge("salary", 6000F));
        disjunction.add(Restrictions.isNull("email"));

        criteria.add(disjunction);
        criteria.add(conjunction);

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

    @Test
    //QBC检索
    public void testQBC(){
        //1. 创建一个 Criteria 对象
        Criteria criteria = session.createCriteria(Employee.class);

        //2. 添加查询条件: 在 QBC 中查询条件使用 Criterion 来表示
        //Criterion 可以通过 Restrictions 的静态方法得到
        //eq,是等于,gt是大于
        criteria.add(Restrictions.eq("email", "SKUMAR"));
        criteria.add(Restrictions.gt("salary", 5000F));

        //3. 执行查询
        Employee employee = (Employee) criteria.uniqueResult();
        System.out.println(employee);
    }

    @Test
    //内连接
    public void testinnerjoin(){
        String hql = "SELECT e FROM Employee e INNER JOIN e.dept";
        Query query = session.createQuery(hql);

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

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

    @Test
    //迫切内连接
    public void testinnerjoinfetch(){

        String hql = "FROM Department d INNER JOIN FETCH d.emps";
        Query query = session.createQuery(hql);

        List<Department> depts = query.list();
        //取消重复的行
        depts = new ArrayList<>(new LinkedHashSet(depts));
        System.out.println(depts.size()); 

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

    @Test
    //左外连接,DISTINCT取消重复的行
    public void testLeftJoin(){
        String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
        Query query = session.createQuery(hql);

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

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

//        List<Object []> result = query.list();
//        result = new ArrayList<>(new LinkedHashSet<>(result));,取消重复的行
//        System.out.println(result);
//
//        for(Object [] objs: result){
//            System.out.println(Arrays.asList(objs));
//        }
    }

    //迫切左外连接LEFT JOIN FETCH,DISTINCT是取消重复的行
    public void testLeftJoinFetch(){
        String hql="select distinct d from Department d left join fetch d.emps";
        Query query=session.createQuery(hql);

        List<Department> depts=query.list();

        //取消重复的行,set集合中没有重复的值
        depts=new ArrayList<>(new LinkedHashSet<>(depts));
        System.out.println(depts.size());

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

    }

    //报表查询,即在sql是分组查询,只查询部分属性
    public void testGroupBy(){
        String hql="select min(e.salary),max(e.salary) "
                + "from Employee e group by e.dept having min(salary)>:de";

        Query query=session.createQuery(hql).setFloat("de", 5000);

        //数组的形式
        List<Object []> result=query.list();
        for(Object [] emp:result){
            System.out.println(Arrays.asList(emp));
        }
    }

    //投影查询,即查询部分属性
    public void testFieldQuery2(){

        String hql="select new Employee(e.name,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.getName()+","+emp.getSalary()+","+emp.getEmail()+","+emp.getDept());
        }
    }

    @Test
    //投影查询,即查询部分属性
    public void testFieldQuery(){
        String hql="select e.email,e.salary,e.dept 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 [] emps:result){
            System.out.println(Arrays.asList(emps));
        }
    }

    //在映射文件中定义命名查询语句方式的命名查询,在映射文件中要配置的。。。
    //此查询方法,只能查询到在此范围内的个数,不能查询到具体的属性值
    public void  testNamedQuery(){
        Query query =session.getNamedQuery("salaryemp");

        List<Employee> emps=
                query.setFloat("minSal", 5000)
                    .setFloat("maxSal", 10000)
                    .list();
        System.out.println(emps.size());
    }

    //分页查询,此查询只能查询到,对应的id
    @Test
    public void testPageQuery(){
        String hql="from Employee";
        Query query=session.createQuery(hql);

        //第三页
        int pageNo=3;
        //每页的大小为5
        int pageSize=5;

        /*
         * setFirstResult(int firstResult): 设定从哪一个对象开始检索,
         * 参数 firstResult 表示这个对象在查询结果中的索引位置, 索引位置的起始值为 0.
         * 默认情况下, Query 从查询结果中的第一个对象开始检索
         *
         * setMaxResults(int maxResults): 设定一次最多检索出的对象的数目.
         * 在默认情况下, Query 和 Criteria 接口检索出查询结果中所有的对象
         * */
        List<Employee> emps=
                query.setFirstResult((pageNo-1)*pageSize)
                .setMaxResults(pageSize).list();
        System.out.println(emps);
    }

    //基于命名参数的查询
    //此查询方法,只能查询到在此范围内的个数,不能查询到具体的属性值
    public void testHQLNamedParameter(){
        //1. 创建 Query 对象
        //基于命名参数.
        String hql="from Employee e where e.salary > :sal and e.email like :ema";
        Query query = session.createQuery(hql);

        //2. 绑定参数。setFloat,setString,都为设置属性的类型
        query.setFloat("sal", 7000).setString("ema", "%A%");

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

    //此查询方法,只能查询到在此范围内的个数,不能查询到具体的属性值
    public void testHql(){

        //1. 创建 Query 对象
        //基于位置的参数.hql是面向对象的,所以,书写表名时 为封装属性的类名;
        String hql="FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND e.dept = ? "
                + "ORDER BY e.salary";
        Query query=session.createQuery(hql);

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

        //3. 执行查询
        List<Employee> emp=query.list();
        System.out.println(emp.size());
    }
}
时间: 2024-10-12 15:08:29

hibernate检索方式(HQL 检索方式,QBC 检索方式,本地 SQL 检索方式)的相关文章

[原创]java WEB学习笔记92:Hibernate学习之路-- -QBC 检索和本地 SQL 检索:基本的QBC 查询,带 AND 和 OR 的QBC,统计查询,排序,分页

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

QBC检索和本地SQL检索

细说QBC:QBC(Query By Criteria) 查询:这种方式比较面向对象方式,因为是面向对象,所以查询时参数名就是所查询的类的属性名并不是数据库的表的列名重点是有三个描述条件的对象:Restrictions,Order,Projections.使用QBC查询,一般需要以下三个步骤: 1. 使用Session实例 的createCriteria()方法创建Criteria对象 , 2. 并使用add()方法添加设置查询条件,工具类Restrictions的方法为Criteria对象设置

Hibernate(十五):QBC检索和本地SQL检索

QBC检索 QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口. 1)通过Critera实现具有条件的查询 1 @Test 2 public void testCriteria00() { 3 // 1.创建criteria对象 4 Criteria criteria = session.createCriteria(Employee.class); 5 6 // 2.添加过

Hibernate之QBC检索和本地SQL检索

QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口 本地SQL查询来完善HQL不能涵盖所有的查询特性. ====================代码区====================== 测试类 1 package com.yl.hibernate.test; 2 3 4 import java.util.ArrayList; 5 import java.util.A

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(7)

Hibernate 提供了以下几种检索对象的方式 (1)导航对象图检索方式:  根据已经加载的对象导航到其他对象 (2)OID 检索方式:  按照对象的 OID 来检索对象 (3)HQL 检索方式: 使用面向对象的 HQL 查询语言 (4)QBC 检索方式: 使用 QBC(Query By Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句, 提供了更加面向对象的查询接口. (5)本地 SQL 检索方式: 使用本地数据库的 SQL 查询语句 HQL(Hiber

Hibernate 查询方式(HQL/QBC/QBE)汇总

作为老牌的 ORM 框架,Hibernate 在推动数据库持久化层所做出的贡献有目共睹. 它所提供的数据查询方式也越来越丰富,从 SQL 到自创的 HQL,再到面向对象的标准化查询. 虽然查询方式有点眼花缭乱,配置使用起来也稍微有点复杂. 但是丝毫掩盖不了它迷人的地方,本篇博客试着汇总 Hibernate 所有的查询方式. 萝卜青菜各有所爱,工作中可以根据自己的喜好选择其中的几种进行编程. 1. HQL 方式,参数使用问号占位(4.1 版本中已被废弃) public List<UserPO>

Hibernate查询方式---HQL方式

这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多.条件查询.分页查询.连接查询.嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象.其它的,包括一些查询函数(count(),sum()等).查询条件的设定等,全都跟SQL语法一样.###注意:     在hql中关键字不区分大小写,但是属性和类名区分大小写示例1: static void query(String name){ Session s=null; try{ s=Hiber

SQL 检索所有存储过程中是否包含某字符

--将text替换成你要查找的内容 select name from sysobjects o, syscomments s where o.id = s.id and text like '%text%' and o.xtype = 'P' --将text替换成你要查找的内容 SELECT ROUTINE_NAME, ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE '%text%