Hibernate(32)什么是Hibernate的Criteria查询?

Hibernate的Criteria查询

Hibernate的Criteria查询是一种面向对象的查询方式,它允许开发者以编程方式构建查询,而不是直接编写HQL或SQL语句。它的主要特点包括:

  • 类型安全:编译时检查可以捕捉到错误。
  • 面向对象:使用Java对象和方法来构建查询。
  • 动态生成:可以在运行时动态生成查询,而不是在编译时固定查询。

使用Criteria查询

在Hibernate 5之前,Criteria API是通过org.hibernate.Criteria接口实现的。在Hibernate 5及之后,Criteria API被重新设计为JPA的Criteria API(javax.persistence.criteria)。

示例代码

实体类定义

继续使用之前定义的PersonAddress实体类。

Person类
java 复制代码
package com.example.domain;

import javax.persistence.*;

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private int age;

    public Person() {}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters 和 Setters

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Hibernate配置文件 hibernate.cfg.xml

xml 复制代码
<!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="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
        <property name="hibernate.connection.username">your_username</property>
        <property name="hibernate.connection.password">your_password</property>

        <!-- Hibernate 属性配置 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 映射类 -->
        <mapping class="com.example.domain.Person"/>
        <mapping class="com.example.domain.Address"/>
    </session-factory>
</hibernate-configuration>

HibernateUtil类

java 复制代码
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            // 从配置文件创建SessionFactory
            sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        } catch (Throwable ex) {
            // 记录启动失败的错误
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

使用Criteria查询示例

插入示例数据

java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class HibernateInsertData {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 插入示例数据
        insertSampleData(sessionFactory);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void insertSampleData(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Person person1 = new Person("John Doe", 30);
            Person person2 = new Person("Jane Doe", 28);

            session.save(person1);
            session.save(person2);
            transaction.commit();
            System.out.println("Inserted sample data");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

使用Criteria查询

查询所有Person记录
java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;

import javax.persistence.criteria.Root;
import java.util.List;

public class HibernateCriteriaQueryExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 使用Criteria查询所有Person记录
        queryAllPersons(sessionFactory);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void queryAllPersons(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        try {
            HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
            JpaCriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
            Root<Person> root = criteriaQuery.from(Person.class);
            criteriaQuery.select(root);

            List<Person> persons = session.createQuery(criteriaQuery).getResultList();
            System.out.println("Query all persons:");
            for (Person person : persons) {
                System.out.println(person.getName() + " - " + person.getAge());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}
使用条件查询

假设我们想查询年龄大于25岁的Person。

java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;

import javax.persistence.criteria.Root;
import javax.persistence.criteria.Predicate;
import java.util.List;

public class HibernateCriteriaConditionalQueryExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 使用Criteria条件查询
        queryPersonsByAge(sessionFactory, 25);

        // 关闭SessionFactory
        sessionFactory.close();
    }

    private static void queryPersonsByAge(SessionFactory sessionFactory, int age) {
        Session session = sessionFactory.openSession();
        try {
            HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
            JpaCriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
            Root<Person> root = criteriaQuery.from(Person.class);

            Predicate agePredicate = criteriaBuilder.greaterThan(root.get("age"), age);
            criteriaQuery.select(root).where(agePredicate);

            List<Person> persons = session.createQuery(criteriaQuery).getResultList();
            System.out.println("Query persons with age greater than " + age + ":");
            for (Person person : persons) {
                System.out.println(person.getName() + " - " + person.getAge());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

Criteria查询详细解释

  1. 插入示例数据 :向数据库中插入两个Person对象供查询使用。

    java 复制代码
    public class HibernateInsertData {
        public static void main(String[] args) {
            // 获取SessionFactory
            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    
            // 插入示例数据
            insertSampleData(sessionFactory);
    
            // 关闭SessionFactory
            sessionFactory.close();
        }
    
        private static void insertSampleData(SessionFactory sessionFactory) {
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            try {
                Person person1 = new Person("John Doe", 30);
                Person person2 = new Person("Jane Doe", 28);
    
                session.save(person1);
                session.save(person2);
                transaction.commit();
                System.out.println("Inserted sample data");
            } catch (Exception e) {
                if (transaction != null) {
                    transaction.rollback();
                }
                e.printStackTrace();
            } finally {
                if (session != null) {
                    session.close();
                }
            }
        }
    }
  2. 查询所有Person记录:使用Criteria查询所有Person记录。

    java 复制代码
    public class HibernateCriteriaQueryExample {
        public static void main(String[] args) {
            // 获取SessionFactory
            SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    
            // 使用Criteria查询所有Person记录
            queryAllPersons(sessionFactory);
    
            // 关闭SessionFactory
            sessionFactory.close();
        }
    
        private static void queryAllPersons(SessionFactory sessionFactory) {
            Session session = sessionFactory.openSession();
            try {
                HibernateCriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
                JpaCriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
                Root<Person> root = criteriaQuery.from(Person.class);
                criteriaQuery.select(root);
    
                List<Person> persons = session.createQuery(criteriaQuery).getResultList();
                System.out.println("Query all persons:");
                for (Person person : persons) {
                    System.out.println(person.getName() );
相关推荐
㳺三才人子5 小时前
初探 Flask
后端·python·flask·html
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Java爱好狂.6 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易6 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
装不满的克莱因瓶7 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
ltl7 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端
excel8 小时前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
卷毛的技术笔记9 小时前
Java后端硬核实战:用Spring AI Alibaba+Redis给LLM装上“超强记忆中枢”
java·人工智能·redis·后端·spring·ai·系统架构
IT_陈寒9 小时前
Java的Optional差点让我掉坑里,这几个坑你别踩
前端·人工智能·后端
子兮曰10 小时前
Harness 驾驭工程深度教程:从 AGENTS.md 到全链路 AI 编码基础设施
前端·后端·ai编程