当我尝试从数据库中删除条目时,使用
session.delete(object)
然后我可以执行以下操作:
1)如果该行存在于数据库中,则将执行两个SQL查询:一个选择,然后一个删除
2)如果数据库中不存在该行,则仅执行选择查询
但是同样,更新不是这种情况。无论是否存在数据库行,都只会执行更新查询。
请让我知道为什么这种行为用于删除操作。这不是性能问题,因为遇到了两个查询而不是一个查询?
编辑:
我正在使用hibernate3.2.5
样例代码:
SessionFactory sessionFactory = new Configuration().configure("student.cfg.xml").buildSessionFactory(); Session session = sessionFactory.openSession(); Student student = new Student(); student.setFirstName("AAA"); student.setLastName("BBB"); student.setCity("CCC"); student.setState("DDD"); student.setCountry("EEE"); student.setId("FFF"); session.delete(student); session.flush(); session.close();
cfg.xml
<property name="hibernate.connection.username">system</property> <property name="hibernate.connection.password">XXX</property> <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521/orcl</property> <property name="hibernate.jdbc.batch_size">30</property> <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property> <property name="hibernate.cache.use_query_cache">false</property> <property name="hibernate.cache.use_second_level_cache">false</property> <property name="hibernate.connection.release_mode">after_transaction</property> <property name="hibernate.connection.autocommit">true</property> <property name="hibernate.connection.pool_size">0</property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property>
hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.infy.model.Student" table="STUDENT"> <id name="id" column="ID"> <generator class="assigned"></generator> </id> <property name="firstName" type="string" column="FIRSTNAME"></property> <property name="lastName" type="string" column="LASTNAME"></property> <property name="city" type="string" column="CITY"></property> <property name="state" type="string" column="STATE"></property> <property name="country" type="string" column="COUNTRY"></property> </class>
原因是为了删除对象,Hibernate要求对象处于持久状态。因此,hibernate首先获取对象(选择),然后将其删除(删除)。
为什么Hibernate需要首先获取对象?原因是可能启用了Hibernate拦截器(http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/events.html),并且对象必须通过这些拦截器传递以完成其生命周期。如果直接在数据库中删除行,则拦截器将不会运行。
另一方面,可以使用批量操作在单个SQL DELETE语句中删除实体:
Query q = session.createQuery("delete Entity where id = X"); q.executeUpdate();