论坛首页 Java版 Hibernate

hibernate中的动态增加和动态更新一点想法

浏览 785 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2008-05-19

      这两天把原来的hibernate又复习了一下,意外发现hibernate有一个动态增加和动态更新功能。就是说hibernate生成的sql语句只set,有变化的字段。这样确实会从一定程度上提高性能。

      可是动态更新的问题是查询和更新必须同时在一个相同的session中,否则hibernate无法判断这是不是一个相同的对象。可是实际上我们用更新基本上都是查询出来之后,在前台做一些从新的赋值,在放到一个专有的update方法里更新。这样动态update的功能意义不大了。怎么办呢?大家还记得吗HibernateSessionFactory中的session都是单例的这样,我们要DAO层的查询和更新不关闭session.close,将关闭session的任务交给业务逻辑层来完成不就解决了这个问题吗。

这是我的代码不知道这么做会不会有什么潜在问题,希望大家指教。还有动态update真会有性能提升吗?

<?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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="hibrenate.vo.Customer" table="customer" catalog="dept_development" dynamic-insert="true" dynamic-update="true">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="assigned" />
        </id>
        <many-to-one name="creditCard" class="hibrenate.vo.CreditCard" fetch="select">
            <column name="card_id" not-null="true" />
        </many-to-one>
        <property name="firstname" type="java.lang.String">
            <column name="firstname" not-null="true" />
        </property>
        <property name="lastname" type="java.lang.String">
            <column name="lastname" not-null="true" />
        </property>
        <property name="creattime" type="java.util.Date">
            <column name="creattime" length="0" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

 

package hibernate.dao;

import org.hibernate.Session;
import org.hibernate.Transaction;

import hibernate.HibernateSessionFactory;
import hibrenate.vo.Customer;

public class CustomerDao {
	//查询一个对象
	public Customer selectOne(Integer id)
	{
		Customer customer = null;
		Session session = HibernateSessionFactory.getSession();
		Transaction transaction =	session.beginTransaction();
		customer = (Customer) session.get(Customer.class, id);
		transaction.commit();
		//不关闭session
	//	HibernateSessionFactory.closeSession();
		return customer;
	}
	//更新一个对象
	public void update(Customer customer)
	{
		Session session = HibernateSessionFactory.getSession();
		Transaction transaction =	session.beginTransaction();
		session.update(customer);
		transaction.commit();
		//不关闭session
		//HibernateSessionFactory.closeSession();
		
	}
}



package hibernate.dao;

import hibernate.HibernateSessionFactory;
import hibrenate.vo.Customer;

public class Test{
	public static void main(String[] args) {
		CustomerDao  dao = new CustomerDao ();
		Customer customer = dao.selectOne(1);
		customer.setFirstname("张欣");
		dao.update(customer);
		//关闭Session
		HibernateSessionFactory.closeSession();
		
	}
}
 
   
最后更新时间:2008-05-20
《Hiberante In Action》上介绍说 除非表里含有大字段或者字段数超过50个以上 否则不建议开启“动态更新”和“动态插入”
因为update xxxxx及insert xxxxx语句默认都是SessionFactory建立时就生成好的
开启“动态”后就需要运行时现组装了 也需要挨个验证各属性是否改变
这些操作也会浪费一定的效率 会抵消“动态”的好处
   
0 请登录后投票
最后更新时间:2008-05-20
所以我也要和大家探讨的是如果项目中确实存在50个字段以上的表,这样做性能的提升大吗。更为关键的将查询和更新放在一起,最后用HibernateSessionFactory.closeSession();
这样会不会有问题。
   
0 请登录后投票
最后更新时间:2008-05-20
如果的确有50个字段以上 需要设置动态插入/更新
可以设置select-before-update = "true"
这样每只更新之前会执行一个select查询
然后自动对状态进行判断,来决定更新那些字段,生成update语句

楼主的方法我看也是可以的,只要能保证HibernateSessionFactory.closeSession();在每次请求后都能被调用。
   
0 请登录后投票
最后更新时间:2008-05-20
打倒小日本 的方法也不错但是我觉得设置select-before-update = "true",可是如果一个实体与另外一个实体有关联的话会不会有问题
   
0 请登录后投票
最后更新时间:2008-05-22
wang19841229 写道
打倒小日本 的方法也不错但是我觉得设置select-before-update = "true",可是如果一个实体与另外一个实体有关联的话会不会有问题

貌似这种方式不会提升太多的性能,控制不好的话,容易session 泄漏,
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐