Hibernate基于配置文件(二十)Hibernate进行批处理

Hibernate中的批处理,实质上是对JDBC的批处理进行配置

 

要使用批处理插入数据,id生成策略不能是native策略,可以是uuid或者hilo


批量数据获取
    属性:hibernate.jdbc.fetch_size
    *MYSQL不支持,ORACLE支持

批量数据提交(极大的提高了批量执行的效率)
    属性:hibernate.jdbc.batch_size
    *MYSQL支持,ORACLE支持

    步骤(理解):
        1.id生成策略不能是native
            [native依赖数据库生成id,每save()就会执行插入,否则无法生成id,所以无法进行批量插入]
            可选策略:uuid/hilo  在内存中生成id,这样才能在commit的时候进行批量提交操作
       
        2.关闭二级缓存,否则对象都被放入二级缓存中,有可能造成内存溢出,另外还影响速度
       
        3.hibernate.cfg.xml中配置batch_size参数
       
        4.MYSQL数据库需要修改url,加上 rewriteBatchedStatements=true
   
        5.即时flush clear [及时清除一级缓存中的数据,每插入多少条记录便清除一次]
       
        6.为了不影响批量插入的速度,关闭sql打印<property name="show_sql">false</property>
       
        7.<property name="hibernate.jdbc.batch_size">50</property>
            每50条进行一次批量插入,然后根据此参数在程序中定义清空缓存的时机
            可设置为50的倍数,那么每插入4次后,就清空一次缓存,防止内存溢出
                if(i%200==0) {
                    session.flush();//强制将内存中的持久化对象更新到数据库中
                    session.clear();//清空缓存中的持久化对象,防止内存溢出
                }

package org.leadfar.hibernate.model;

import java.util.Date;



public class ContactPerson {
	private int id;
	private String name;
	private int age;	
	private Date birthday;
	private Group group;
	
	private int versionNumber;
	
	public ContactPerson() {
	}
	
	public ContactPerson(String name) {
		this.name = name;
	}
	public ContactPerson(int id,String name) {
		this.id = id;
		this.name = name;
	}
	public ContactPerson(int id,int age,String name) {
		this.id = id;
		this.age = age;
		this.name = name;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Group getGroup() {
		return group;
	}
	public void setGroup(Group group) {
		this.group = group;
	}

	

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public int getVersionNumber() {
		return versionNumber;
	}

	public void setVersionNumber(int versionNumber) {
		this.versionNumber = versionNumber;
	}
	
	
}

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="org.hibernate.auction">
		<class name="org.leadfar.hibernate.model.ContactPerson" table="t_person">

		<id name="id">
			<!-- 批量插入数据,可以使用hilo策略(不依赖数据库生成id值)-->
			<generator class="hilo"/>
		</id>
		<!-- 版本标识,用于解决并发访问 -->
		<version name="versionNumber"></version>
		
		<property name="name"/>
		<property name="age"></property>
		<property name="birthday" type="date"></property>
		
		<many-to-one name="group" column="gid" fetch="join"></many-to-one>
		
	</class>
	
</hibernate-mapping>

 

 

测试

	public void save_person() throws Exception {
		Configuration cfg = new Configuration().configure();
		
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		long begin = System.currentTimeMillis();
		
		Session session = sfactory.openSession();
		
		try {
			session.beginTransaction();
			
			for(int i=0;i<100000;i++) {
				ContactPerson cp = new ContactPerson();
				cp.setAge(1);
				cp.setName("x");
				session.save(cp);
				if(i%200==0) {
					session.flush();
					session.clear();
				}
			}
			
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			session.close();
		}
		long end = System.currentTimeMillis();
		System.out.println("耗时:"+(end-begin)+"ms");
	}

 

你可能感兴趣的:(Hibernate)