Hibernate4-10 检索方式

本文详细介绍了Hibernate中HQL查询语言的基本功能与实现步骤,包括基本查询、分页查询、命名查询、投影查询及报表查询等多种查询方式,并通过示例代码展示了如何在实际应用中使用这些查询方式。

  Hibernate提供的检索对象的方式主要有导航对象图检索、OID检索、HQL检索、QBC检索和本地SQL检索共五种方式,具体说明如下:

  • 导航对象图检索:根据已经加载的对象导航到其他对象;
  • OID检索方式:按照对象的OID来检索对象;
  • HQL检索方式:使用面向对象的HQL查询语言;
  • QBC检索方式:使用QBC(Query By Criteria) API来检索对象,其封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口;
  • 本地SQL检索方式:使用本地数据库的SQL查询语句。

1. HQL检索方式

  HQL(Hibernate Query Language)是面向对象的查询语言,与SQL查询语言相似;在Hibernate所提供的各种检索方式中,HQL是使用最广的一种检索方式。

1.1 基本功能
  • 在查询语句中设定各种查询条件
  • 支持投影查询,即仅检索出对象的部分属性
  • 支持分页查询
  • 支持连接查询
  • 支持分组查询, 允许使用HAVING和GROUP BY关键字
  • 提供内置聚集函数,如sum()、min()和max()
  • 支持子查询
  • 支持动态绑定参数
  • 能够调用用户定义的SQL函数或标准的SQL函数
1.2 实现步骤
  • 调用Session对象的createQuery()方法创建Query对象,其需传入一个HQL查询语句(可以包含命名参数);
  • 动态绑定参数;
  • 调用Query(支持方法链编程风格)对象的相关方法执行查询语句。
1.3 绑定参数

这里写图片描述

1.4 分页查询
  • setFirstResult(int firstResult)方法:设定从哪一个对象开始检索,参数用于指定该对象在查询结果中的索引位置,索引位置的起始值为0;默认情况下,Query接口对象从查询结果中的第一个对象开始检索;
  • setMaxResults(int maxResults):设定一次最多检索出的对象数目,默认情况下,Query和Criteria接口检索出查询结果中所有的对象。
1.5 命名查询
  • 配置: Hibernate允许在映射文件中使用query元素(与class元素并列)定义HQL查询语句;
  • 查询:在程序中通过Session对象的getNamedQuery()方法获取查询语句所对应的Query对象。
1.6 投影查询

  基本概念: 投影查询结果中仅包含实体的部分属性,其通过SELECT关键字来实现。
  查询结果: Query接口的list()方法返回的集合中包含的是数组类型的元素,每个对象数组代表查询结果的一条记录。
  注意事项: 可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,使程序代码能完全运用面向对象的语义来访问查询结果集;
  注意事项: 可以通过DISTINCT关键字来保证查询结果不会返回重复元素。

1.7 报表查询

  基本概念: 报表查询用于对数据分组和统计,HQL查询语句利用GROUP BY关键字对数据分组,用HAVING关键字为分组数据设定约束条件。
  聚集函数: 在HQL查询语句中可以调用count()、min()、max()、sum()和avg()等聚集函数。

1.8 迫切左外连接

这里写图片描述

1.9 迫切内连接

这里写图片描述

1.10 关联级别运行时的检索策略

  如果在HQL中没有显式指定检索策略,将使用映射文件配置的检索策略;HQL查询会忽略映射文件中设置的迫切左外连接检索策略,如果希望HQL采用迫切左外连接策略,就必须在HQL查询语句中显式的指定;若在HQL查询语句中显式指定了检索策略,就会覆盖映射文件中配置的检索策略。


2 QBC检索与本地SQL检索方式

  QBC查询是通过使用Hibernate提供的Query By Criteria API来查询对象,其封装了SQL语句的动态拼装,为查询提供了更加面向对象的功能接口。
  而本地SQL查询主要用来完善HQL所不能涵盖的查询特性,如插入操作。


附录:测试代码

HibernateTest.java:
package com.qiaobc.hibernate.hql;

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

public class HibernateTest {

    private Session session = null;
    private Transaction transaction = null;
    private SessionFactory sessionFactory = null;

    @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();
    }

    // 1. HelloWorld测试
    @Test
    public void testHQL() {

        // 基于位置的参数
        // String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ?";
        // Query query = session.createQuery(hql);
        // query.setFloat(0, 12012).setString(1, "%4%");

        // 1. 创建Query对象
        // 基于名字的参数
        String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email AND e.dept = :dept ORDER BY e.salary";
        Query query = session.createQuery(hql);

        // 2. 绑定参数
        Department dept = (Department) session.get(Department.class, 1005);
        query.setFloat("sal", 12012).setString("email", "%3%")
                .setEntity("dept", dept);

        // 3. 开始查询
        List<Employee> emps = query.list();
        System.out.println(emps);

    }

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

        int pageNo = 4; // 页码数
        int pageSize = 3;   // 每页记录数

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

        System.out.println(emps);
    }

    /**
     * 3. 命名查询
     * <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minsal AND e.salary < :maxsal]]></query>
     */
    @Test
    public void testNamedQuery() {
        Query query = session.getNamedQuery("salaryEmps");
        List<Employee> emps = query.setFloat("minsal", 12009).setFloat("maxsal", 12012).list();
        System.out.println(emps);
    }

    /**
     * 4. 投影查询 
     */
    @Test
    public void testFieldQuery1() {
        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(1006);
        // 查询结果为数组
        List<Object[]> result = query.setEntity("dept", dept).list();

        for(Object[] objs : result) {
            System.out.println(Arrays.asList(objs));
        }
    }
    @Test
    public void testFieldQuery2() {
        // 查询结果为Employee对象的集合
        String hql = "SELECT new Employee(e.salary, e.email) FROM Employee e "
                + "WHERE e.dept = :dept";
        Query query = session.createQuery(hql);

        Department dept = new Department();
        dept.setId(1006);
        List<Employee> result = query.setEntity("dept", dept).list();
        System.out.println(result);
    }

    /**
     * 5. 报表查询
     */
    @Test
    public void testGroupBy() {
        String hql = "SELECT min(e.salary), max(e.salary)"
                + "FROM Employee e "
                + "GROUP BY e.dept "
                + "HAVING min(e.salary) > :minsal";
        Query query = session.createQuery(hql);

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

    /**
     * 6. 迫切左外连接
     */
    @Test
    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();
//      depts = new ArrayList<>(new LinkedHashSet<>(depts)); // 去重
        System.out.println(depts);
    }

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

        // 2. 添加查询条件:在QBC中查询条件使用Criterion来表示
        // Criterion可以通过Restrictions的静态方法得到
//      criteria.add(Restrictions.eq("email", "qiaobc2012@163.com"));
//      criteria.add(Restrictions.eq("salary", 12012F));

        // 1). AND : Conjunction本身就是一个Criteria对象,且其中还可以添加Criterion对象
        Conjunction conjunction = Restrictions.conjunction();
        conjunction.add(Restrictions.like("name", "3", MatchMode.ANYWHERE));
        Department dept = new Department();
        dept.setId(1003);
        conjunction.add(Restrictions.eq("dept", dept));
        // 条件1:(name like %3% and dept=Department [id=1003, name=null])
        System.out.println(conjunction);

        // 2). OR
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(Restrictions.like("name", "3", MatchMode.ANYWHERE));
        disjunction.add(Restrictions.eq("dept", dept));
        // 条件2:(name like %3% or dept=Department [id=1003, name=null])
        System.out.println(disjunction);

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

        criteria.list();    // 查询条件为:条件1 + 条件2

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

        // 统计查询:Projections
//      criteria.setProjection(Projections.max("salary"));
//      System.out.println(criteria.list());

        // 添加排序:Order
//      criteria.addOrder(Order.asc("salary"));
//      criteria.addOrder(Order.desc("email"));

        // 添加翻页:setFirstResult()方法
    }

    // HQL支持查询和删除修改操作,但不支持插入操作
    @Test
    public void testNativeSQL() {
        String sql = "INSERT INTO departments VALUE(?, ?)";
        Query query = session.createSQLQuery(sql);

        query.setInteger(0, 1008).setString(1, "qiaobei").executeUpdate();
    }

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

}
Department.java:
package com.qiaobc.hibernate.hql;

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 + ", name=" + name + "]";
    }

}
Employee.java:
package com.qiaobc.hibernate.hql;

public class Employee {

    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) {
        super();
        this.salary = salary;
        this.email = email;
    }

    public Employee() {
        super();
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", salary=" + salary
                + ", email=" + email + ", dept=" + dept + "]";
    }

}
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-2-24 20:06:22 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.qiaobc.hibernate.hql">

    <class name="Department" table="DEPARTMENTS">

        <id name="id" type="java.lang.Integer">
            <column name="DEPT_ID" />
            <generator class="native" />
        </id>

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

        <set name="emps" table="EMPLOYEES" inverse="true">
            <!-- 当前表在EMPLOYEES表中的外键 -->
            <key column="DEPARTMENT_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-2-24 20:06:22 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.qiaobc.hibernate.hql">

    <class name="Employee" table="EMPLOYEES">

        <id name="id" type="java.lang.Integer">
            <column name="EMP_ID" />
            <generator class="native" />
        </id>

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

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

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

        <many-to-one name="dept" class="Department" column="DEPARTMENT_ID"></many-to-one>

    </class>

    <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minsal AND e.salary < :maxsal]]></query>

</hibernate-mapping>
hibernate.cfg.xml:
<?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>

        <!-- 配置连接数据库的基本信息 -->
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql:///hibernate</property>

        <!-- 配置Hibernate的基本信息 -->
        <!-- 配置Hibernate所使用的数据库方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>

        <!-- 执行操作时是否在控制台打印SQL语句 -->
        <property name="show_sql">true</property>

        <!-- 执行操作时是否对SQL语句进行格式化 -->
        <property name="format_sql">true</property>

        <!-- 执行操作时自动生成数据表的具体策略 -->
        <property name="hbm2ddl.auto">update</property>

        <!-- 1). 配置数据库的事务隔离级别为:READ UNCOMMITED -->
        <property name="hibernate.connection.isolation">1</property>

        <!-- 2). 配置数据库的事务隔离级别为:READ COMMITED -->
        <property name="hibernate.connection.isolation">2</property>

        <!-- 3). 配置数据库的事务隔离级别为:REPEATABLE READ -->
        <property name="hibernate.connection.isolation">4</property>

        <!-- 4). 配置数据库的事务隔离级别为:SERIALIZEABLE -->
        <property name="hibernate.connection.isolation">8</property>

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

        <!-- 指定所关联的对象关系映射文件 -->
        <mapping resource="com/qiaobc/hibernate/hql/Employee.hbm.xml"/>
        <mapping resource="com/qiaobc/hibernate/hql/Department.hbm.xml"/>


    </session-factory>
</hibernate-configuration>
标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值