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 分页
可以使用setFirstResult和setMaxResults方法来实现分页。例如,获取第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查询:使用
CriteriaBuilder和CriteriaQuery创建查询对象。 - 添加查询条件:使用
where方法添加条件。 - 排序和分页:使用
orderBy、setFirstResult和setMaxResults方法实现排序和分页。 - 查询投影:使用
select方法选择特定字段,并使用DTO类存储结果。
通过这些方法,可以灵活、动态地构建和执行Hibernate查询,充分利用Hibernate的强大功能来处理复杂的数据需求。希望这些详细的解释和代码示例能帮助您更好地理解和使用Hibernate的Criteria API。