Hibernate
一、Hibernate 的查询方式
1.1 SQL#
全称 Structured Query Language。
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
违背了 hibernate 的跨平台优点,不易维护,不面向对象。
1.2 HQL#
全称 Hibernate Query Language。
@Override
public SysUser findUserByLoginName(String loginName) {
String hql = "from SysUser as u where u.loginName = ?";
List<SysUser> users = getHibernateTemplate().find(hql, loginName); // loginName 对应 '?' 符号
return users.isEmpty() ? null : users.get(0);
}
1.3 QBC#
全称 Query By Criteria。
QBC 查询的基本步骤
这种方式比较面向对象方式,重点是有三个描述条件的对象:
Restrictions
、Order
、Projections
。使用 QBC 查询,一般需要以下三个步骤:- 使用 Session 实例的 createCriteria() 方法创建 Criteria 对象;
- 使用工具类 Restrictions 的方法为 Criteria 对象设置查询条件,Order 工具类的方法设置排序方式,Projections 工具类的方法进行统计和分组;
- 使用 Criteria 对象的 list() 方法进行查询并返回结果。
Restrictions、Order、Projections的常用方法
QBC 的查询示例和基本理解
Criteria c = s.createCriteria(Admin.class); c.add(Restrictions.eq("NAME", "Jack")); c.add(Restrictions.eq("PASSWORD", "123456")); List<Admin> list = c.list();
// 分页查询前 10 条 Criteria criteria = session.createCriteria(Customer.class); criteria.addOrder(Order.asc("NAME")); criteria.setFirstResult(0); criteria.setMaxResults(10); List result = criteria.list()
org.hibernate.Criteria
实际上是个条件附加的容器,如果想要设定查询条件,则要使用 org.hibernate.criterion.Restrictions 的各种静态方法传回org.hibernate.criterion.Criterion
实例,传回的每个 org.hibernate.criterion.Criteria 实例代表着一个条件,你要使用org.hibernate.Criteria 的 add() 方法加入这些条件实例。示例:
// 查找 age 等于(eq)20或(or)age为空(isNull)的User Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") )); List users = criteria.list(); // 实际上产生的对应的 sql: Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=? or this_.age is null)
复合查询
复合查询就是在原有的查询基础上再进行查询。
// 查询“包含学生姓名为 Bob”的班级 Criteria criteria = session.createCriteria(Clazz.class); Criteria criteriaInner = criteria.createCriteria(Student.class); criteriaInner.add(Restrictions.eq("NAME", "Bob")); List clazzList = criteria.list();
如果是 DetachedCriteria,则是根据关联属性的名称,而非 Class,如:
Member member = MemberHelper.getCurrentLoginMember(); DetachedCriteria criteria = DetachedCriteria.forClass(Picture.class); DetachedCriteria collectCriteria = criteria.createCriteria("collectRecordList"); collectCriteria.add(Restrictions.eq("member", member)); List<Picture> pictureList = Picture.listByCriteria(criteria, page, Order.desc("updateDate"));
Hibernate 中 Criteria 方式的基本使用流程
- Criteria 创建
- 条件添加
- 结果返回
二、DetachedCriteria
2.1 是什么?#
父接口 CriteriaSpecification
,其下有子接口 Criteria 和实现类DetachedCriteria,Criteria 和 DetachedCriteria 均可使用Criterion 和 Projection 设置查询条件。可以设置 FetchMode(联合查询抓取的模式),设置排序方式。对于 Criteria 还可以设置 FlushModel(冲刷 Session 的方式)和 LockMode(数据库锁模式)。
2.2 与 Criteria 的区别#
Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样,Criteria是在线的,所以它是由Hibernate Session进行创建的;而 DetachedCriteria 是离线的,创建时无需 Session,它通过两个静态方法 forClass(Class) 或 forEntityName(Name) 进行 DetachedCriteria 的实例创建。
Spring 的框架提供了 getHibernateTemplate ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结果。
所以它也称为离线条件查询,即建立一个 DetachedCriteria 对象,将查询的条件等指定好,然后在 session.beginTransaction() 后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。
2.3 基本使用#
/* 查询 id = 1 且在今天或今天之前出生的 user 的名单 */
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
int id = 1;
dc.add(Restrictions.eq("id", id));
Date age = new Date();
dc.add(Restrictions.le("birthday", age));
Session session = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(session);
List users = c.list();
DetachedCriteria 并没有像 Criteria 一样有 list() 的方法来返回 List,所以需要以此获取一个可执行的 Criteria,达到真正执行查询的目的。
org.hibernate.criterion
Class DetachedCriteria
getExecutableCriteria
public Criteria getExecutableCriteria(Session session)
Get an executable instance of Criteria, to actually run the query.
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· Supergateway:MCP服务器的远程调试与集成工具
· C# 13 中的新增功能实操