You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Hibernate Criteria转换指定MySQL多表关联分页查询

把MySQL查询转成Hibernate Criteria实现

嘿,这就帮你把这条MySQL查询转换成Hibernate Criteria的实现~先得明确一下对应的实体类结构,毕竟Hibernate是面向对象的ORM框架,咱们先假设你已经有了和表对应的实体:State对应tbl_state,Country对应tbl_country,而且State实体里关联了Country对象(或者至少包含countryId字段)。下面分两种常见的API写法给你参考:

一、传统Hibernate Criteria API(适合Hibernate 3/4版本)

这个写法更贴近旧版的Hibernate风格,完全对应你的原SQL逻辑:

// 获取当前Session
Session session = sessionFactory.getCurrentSession();

// 创建State的Criteria查询,别名"s"对应原SQL里的"s"
Criteria criteria = session.createCriteria(State.class, "s");

// 关联tbl_country表,对应原SQL里的FROM tbl_state s,tbl_country c WHERE s.country_id=c.country_id
// 这里用INNER JOIN,和原SQL的隐式内联效果一致
criteria.createAlias("s.country", "c", JoinType.INNER_JOIN);

// 投影查询:选择State的所有字段 + Country的countryName,对应SELECT s.*,c.country_name
ProjectionList projections = Projections.projectionList();
// 把State的所有属性映射到"state"别名
projections.add(Projections.property("s"), "state");
// 把Country的countryName映射到"countryName"别名
projections.add(Projections.property("c.countryName"), "countryName");
criteria.setProjection(projections);

// 用DTO来接收组合结果,需要你自己定义一个StateCountryDTO类
criteria.setResultTransformer(Transformers.aliasToBean(StateCountryDTO.class));

// 按state_name排序,对应ORDER BY s.state_name
criteria.addOrder(Order.asc("s.stateName")); // 降序的话用Order.desc()

// 分页逻辑:对应LIMIT pagesize OFFSET pagesize * pagenum
int offset = pagesize * pagenum;
criteria.setFirstResult(offset); // 设置偏移量
criteria.setMaxResults(pagesize); // 设置每页条数

// 执行查询得到结果
List<StateCountryDTO> stateList = criteria.list();

对应的StateCountryDTO示例(用来接收混合结果):

public class StateCountryDTO {
    private State state; // 对应原SQL的s.*
    private String countryName; // 对应原SQL的c.country_name

    // 记得添加无参构造、全参构造,以及getter/setter方法
}

二、JPA CriteriaBuilder API(适合Hibernate 5+及JPA标准)

如果你的项目用的是较新的Hibernate版本,推荐用JPA标准的CriteriaBuilder写法,更符合现代ORM规范:

// 获取EntityManager
EntityManager em = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();

// 创建针对StateCountryDTO的查询
CriteriaQuery<StateCountryDTO> cq = cb.createQuery(StateCountryDTO.class);

// 定义查询根,对应原SQL的tbl_state s
Root<State> s = cq.from(State.class);
// 关联tbl_country,自动处理s.country_id = c.country_id的条件
Join<State, Country> c = s.join("country", JoinType.INNER);

// 选择需要的字段,直接构造DTO对象
cq.select(cb.construct(StateCountryDTO.class, s, c.get("countryName")));

// 按state_name排序
cq.orderBy(cb.asc(s.get("stateName")));

// 设置分页参数
int offset = pagesize * pagenum;
TypedQuery<StateCountryDTO> query = em.createQuery(cq);
query.setFirstResult(offset);
query.setMaxResults(pagesize);

// 执行查询
List<StateCountryDTO> stateList = query.getResultList();

几个注意点

  • 实体类的属性要和数据库字段正确映射:比如State的stateName要对应tbl_state的state_name,Country的countryName对应tbl_country的country_name,可以通过@Column注解配置。
  • 如果你的State实体没有关联Country对象,而是用countryId字段存储关联ID,那关联条件可以改成criteria.add(Restrictions.eqProperty("s.countryId", "c.countryId")),不过更推荐用实体关联,符合ORM的设计思想。
  • 分页的偏移量计算:如果你的pagenum是从1开始的(比如第1页、第2页),那偏移量应该改成pagesize * (pagenum - 1),避免跳过第一页数据。

内容的提问来源于stack exchange,提问作者ysk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:41:26