Hibernate(61)Hibernate的Criteria API如何使用?

8 阅读3分钟

Hibernate的Criteria API 是一种强类型、面向对象的查询语言,它允许开发者通过代码构建查询,而不是通过字符串编写SQL语句。Criteria API 提供了一种更灵活、更安全的方式来构建动态查询。以下是如何使用Hibernate的Criteria API的详细解释和代码示例。

1. 基本使用

1.1 设置实体类

首先,我们需要定义我们的实体类。假设我们有一个简单的Product类。

import javax.persistence.*;

@Entity
@Table(name = "product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @Column(name = "price")
    private Double price;

    // Getters and Setters
}

1.2 配置Hibernate

然后,我们需要配置Hibernate。在hibernate.cfg.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>

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

1.3 创建Criteria查询

以下是一个简单的使用Criteria API查询所有Product实体的例子:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import javax.persistence.criteria.Root;

import java.util.List;

public class HibernateCriteriaExample {
    private static final SessionFactory sessionFactory;

    static {
        try {
            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 void main(String[] args) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
            JpaCriteriaQuery<Product> criteria = builder.createQuery(Product.class);
            Root<Product> root = criteria.from(Product.class);
            criteria.select(root);

            List<Product> products = session.createQuery(criteria).getResultList();
            for (Product product : products) {
                System.out.println("Product Name: " + product.getName() + ", Price: " + product.getPrice());
            }

            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

2. 高级使用

2.1 添加查询条件

可以使用where子句来添加查询条件。例如,查询价格大于50的产品:

criteria.where(builder.gt(root.get("price"), 50.0));

完整示例:

HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
JpaCriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Product> root = criteria.from(Product.class);
criteria.select(root);
criteria.where(builder.gt(root.get("price"), 50.0));

List<Product> products = session.createQuery(criteria).getResultList();
for (Product product : products) {
    System.out.println("Product Name: " + product.getName() + ", Price: " + product.getPrice());
}

2.2 排序

可以使用orderBy子句来对查询结果排序。例如,按价格升序排序:

criteria.orderBy(builder.asc(root.get("price")));

完整示例:

HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
JpaCriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Product> root = criteria.from(Product.class);
criteria.select(root);
criteria.where(builder.gt(root.get("price"), 50.0));
criteria.orderBy(builder.asc(root.get("price")));

List<Product> products = session.createQuery(criteria).getResultList();
for (Product product : products) {
    System.out.println("Product Name: " + product.getName() + ", Price: " + product.getPrice());
}

2.3 分页

可以使用setFirstResultsetMaxResults方法来实现分页。例如,获取第2页,每页10条记录:

session.createQuery(criteria)
       .setFirstResult(10)
       .setMaxResults(10)
       .getResultList();

完整示例:

HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
JpaCriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Product> root = criteria.from(Product.class);
criteria.select(root);
criteria.where(builder.gt(root.get("price"), 50.0));
criteria.orderBy(builder.asc(root.get("price")));

List<Product> products = session.createQuery(criteria)
                                .setFirstResult(10)
                                .setMaxResults(10)
                                .getResultList();
for (Product product : products) {
    System.out.println("Product Name: " + product.getName() + ", Price: " + product.getPrice());
}

2.4 查询投影

可以使用select方法来选择特定的字段。例如,仅查询产品名称和价格:

criteria.select(builder.construct(ProductDTO.class, root.get("name"), root.get("price")));

需要一个DTO类来存储结果:

public class ProductDTO {
    private String name;
    private Double price;

    public ProductDTO(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    // Getters and Setters
}

完整示例:

HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
JpaCriteriaQuery<ProductDTO> criteria = builder.createQuery(ProductDTO.class);
Root<Product> root = criteria.from(Product.class);
criteria.select(builder.construct(ProductDTO.class, root.get("name"), root.get("price")));
criteria.where(builder.gt(root.get("price"), 50.0));
criteria.orderBy(builder.asc(root.get("price")));

List<ProductDTO> products = session.createQuery(criteria).getResultList();
for (ProductDTO product : products) {
    System.out.println("Product Name: " + product.getName() + ", Price: " + product.getPrice());
}

总结

  • 设置实体类:定义Hibernate实体类,并配置映射信息。
  • 配置Hibernate:在hibernate.cfg.xml中配置数据库连接等信息。
  • 创建Criteria查询:使用CriteriaBuilderCriteriaQuery创建查询对象。
  • 添加查询条件:使用where方法添加条件。
  • 排序和分页:使用orderBysetFirstResultsetMaxResults方法实现排序和分页。
  • 查询投影:使用select方法选择特定字段,并使用DTO类存储结果。

通过这些方法,可以灵活、动态地构建和执行Hibernate查询,充分利用Hibernate的强大功能来处理复杂的数据需求。希望这些详细的解释和代码示例能帮助您更好地理解和使用Hibernate的Criteria API。