我被Session.find()的方法困扰了好几天,今天才看到新的Hibernate里没有了Session.find()方法。
现在转载在此,方便你我。
查询性能往往是系统性能表现的一个重要方面,查询机制的优劣很大程度上决定了系统的整体性能。这个领域往往也存在最大的性能调整空间。
hibernate2中Session.find()对应于3中的session.createQuery().list();
hibernate2中Session.iterate()对应于3中的session.createQuery().iterate();
find和iterate区别:
find方法通过一条Select SQL实现了查询操作,而iterate方法要执行多条Select SQL.
iterate第一次查询获取所有符合条件的记录的id,然后再根据各个id从库表中读取对应的记录,这是一个典型的N+1次的查询问题,如果符合条件记录有10000条,就需要执行10001条Select SQL,可想性能会如何的差。
那为什么要提供iterator方法,而不只是提供高效率的find方法?
原因1.与hibernate缓存机制密切相关
find方法实际上是无法利用缓存的,它对缓存只写不读。
find方法只执行一次SQL查询,它无法判断缓存中什么样的数据是符合条件的,也无法保证查询结果的完整性。而iterate方法,会首先查询所有符合条件记录的id,然后根据id去缓存中找,如果缓存中有该id,就返回,没有可以根据id再去数据库查询。
String hql = "from TUser where age > ?";
List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);
顺序执行,iterate方法只会执行一次SQL查询,就是查找id,然后根据id就可以从缓存中获得数据。
String hql = "from TUser where age > ?";
List userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
userList = session.find(hql, new Integer(18), Hibernate.INTEGER);
缓存是不起作用的。
如果目标数据读取相对较为频繁,通过iterate这种机制,会减少性能损耗。
原因2.内存使用上的考虑
find方法将一次获得的所有记录并将其读入内存。如果数据量太大,可能会触发OutOfMemoryError,从而导致系统异常。解决方案之一就是结合iterate方法和evict方法逐条对记录进行处理,将内存消化保持在一个可以接受的范围之内。如:
String hql = "from TUser where age > ?";
Iterator it = session.iterate(hql, new Integer(18), Hibernate.INTEGER);
while(it.hasNext()) {
TUser user = (TUser)it.next();
//将对象从一级缓存中删除
session.evict(user);
//二级缓存可以设定最大缓存量,达到后自动对较老数据进行废除,但也可以通过编
//码移除,这样有助于保持数据有效性。
sessionFactory.evict(TUser.class, user.getID());
}
分享到:
相关推荐
本文将详细介绍Hibernate持久层中的一些核心方法,包括`session.load`, `session.find`, `session.iterator`, `session.save`, `session.update`, `session.saveorupdate`。 1. `session.load()`: - `load()`方法...
... 3、将redisson-all-3.11.2.jar和redisson-tomcat-8-3.11.2.jar 拷贝到${catalina.base}\lib下 4、在原有tomcat\context.xml下 添加 以下代码(参考 <Manager className="org.redisson.tomcat....
Hibernate的`Session`接口提供了`createSQLQuery()`方法,允许我们直接编写SQL语句。例如: ```java Session session = sessionFactory.openSession(); SQLQuery query = session.createSQLQuery("SELECT * FROM...
这里假设Session["A"]是一个List类型的列表,通过调用`Find()`方法找到匹配的对象,然后使用`Remove()`方法将其从列表中移除。 5. **设置键值为null** - **功能**:将某个特定的键值设置为null也是一种有效的删除...
3. **数据查询与更新**:在同一个Session中,我们可以通过Session的`find()`方法查询数据。在示例中,`session.find("from User")`执行了一个HQL(Hibernate Query Language)查询,返回了User表的所有记录。然后,...
- `get`方法和`find`方法的行为相似,它们都会直接从数据库中检索数据。 - `load`方法的执行则更为复杂,它首先检查Session的持久化上下文(persistent Context)中是否存在缓存,如果有则直接返回。如果不存在且...
- 临时状态->持久化状态:通过Session.save()、Session.load()、Session.get()或Session.find()。 - 持久化状态->游离状态:Session.close()或Session.evict()。 - 游离状态->持久化状态:Session.update()、Session...
- **查询数据**:使用`session.createQuery()`或者`session.find()`方法查询出需要删除的数据。 - **执行删除操作**:对查询结果进行遍历,并执行删除操作。 - **提交事务**:使用`transaction.commit()`提交事务...
List<String> names = session.find("select user.name from User as user where age = 25"); ``` 这个查询只返回年龄为 25 的用户的名字。注意,`as user` 是一个别名,使得我们在查询语句中可以更简洁地引用 `...
List<Message> msgList = mDao.findAll(); if(null == u.getUname()){ response.sendRedirect("jspPages/login.jsp"); }else{ HttpSession session = request.getSession(); session.setAttribute("userName",...
Iterator<Customer> customers = session.find("from Customer c where c.age > 0").iterator(); while (customers.hasNext()) { Customer customer = customers.next(); customer.setAge(customer.getAge() + 1);...
Page<MyEntity> pageResult = repository.findAll(pageable); List<MyEntity> content = pageResult.getContent(); long totalElements = pageResult.getTotalElements(); int totalPages = pageResult....
session := engine.NewSession() err := session.Create(&user).Error if err != nil { // 处理错误 } session.Close() ``` 查询数据也非常直观: ```go var users []User session := engine.Where("age > ?", 20...
- 通过`Session.find()`方法返回的列表中的对象。 - 调用`Session.update()`或`Session.saveOrUpdate()`方法,使得处于游离状态的对象变为持久化状态。 - **游离状态(Detached)** - 特征:不再由`Session`管理...
- **增加**:使用`session.save(entity)`或`session.persist(entity)`方法。 - **删除**:调用`session.delete(entity)`。 - **更新**:先调用`session.update(entity)`,再提交事务。 - **查询**:可以使用HQL...
`session.find("from User")` 使用 HQL 查询所有 `User` 对象。遍历结果集,并选择第一个用户作为更新的目标。 ```java updated.setName("justin"); session.flush(); ``` 这一部分展示了如何更新已存在的记录。...
使用HQL进行查询,如`session.find()`或`session.createQuery()`执行HQL查询。例如,`session.createQuery("from Customer")`将返回Customer类的所有实例。 - **QBC(Query By Criteria)查询** QBC是一种基于API...
本篇文章将深入探讨如何实现自己的Hibernate框架,特别是Session方法的实现,这对于理解ORM的工作原理及优化数据库访问逻辑具有重要意义。 首先,我们需要了解Hibernate的核心概念——Session。在Hibernate中,...
Session 对象提供了多种查询方法,如 `load`、`get`、`createQuery` 和 `find` 等。 - **`load` 方法**:用于根据主键加载对象。如果找不到对应的记录,将会抛出 `org.hibernate.ObjectNotFoundException` 异常。 ...
`Session`对象是与数据库交互的主要接口,提供了多种查询方法,如`find()`、`load()`、`query()`等。在这个例子中,我们使用`find()`方法执行HQL查询。 **2. Hibernate Query Language (HQL)** HQL是一种面向对象...