hibernate保存十万级数据量的批量保存操作,

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/java_niucheng/article/details/80318514

图一是我导入的第一张表,最大数据量也就2万多条,hibernate关闭二级缓存勉强能够导入,导入图二的7万多条数据时,就会在执行hibernate的save()停在2万多条.


具体配置:

1.修改spring的管理hibernate的配置

<bean id="webDataSource" class="com.alibaba.druid.pool.DruidDataSource"  
 </span>init-method="init" destroy-method="close">  
 </span><property name="url" value="${web.jdbc.connection.url}" />  
 </span><property name="username" value="${web.jdbc.connection.username}" />  
 </span><property name="password" value="${web.jdbc.connection.password}" />  
 </span><!-- 配置初始化大小、最小、最大 -->  
 </span><property name="initialSize" value="1" />  
 </span><property name="minIdle" value="1" />  
 </span><property name="maxActive" value="20" />  
 </span><!-- 配置获取连接等待超时的时间 -->  
 </span><property name="maxWait" value="6000000" />  
 </span><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
 </span><property name="timeBetweenEvictionRunsMillis" value="60000" />  
 </span><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
 </span><property name="minEvictableIdleTimeMillis" value="300000" />  
 </span><!-- 验证连接有效与否的SQL,不同的数据配置不同 -->  
 </span><property name="validationQuery" value="SELECT 'x'" />  
 </span><property name="testWhileIdle" value="true" />  
 </span><property name="testOnBorrow" value="false" />  
 </span><property name="testOnReturn" value="false" />  
 </span><!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  
 </span><property name="poolPreparedStatements" value="false" />  
 </span><property name="maxPoolPreparedStatementPerConnectionSize" </span>value="50" />  
 </span><!-- 配置监控统计拦截的filters -->  
 </span><property name="filters" value="stat" />  
</bean>  
<bean id="webSessionFactory"  
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
<property name="dataSource" ref="webDataSource" />  
 <<property name="hibernateProperties">  
 <props>  
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
     <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>  
     <prop key="jdbc.use_scrollable_resultset">false</prop>  
     <prop key="hibernate.hbm2ddl.auto">none</prop>  
     <prop key="hibernate.show_sql">false</prop>
     <prop key="hibernate.format_sql">false</prop>  
     <prop key="hibernate.jdbc.fetch_size">50</prop><!-- 每次从数据库中读取的记录条数,mysql不支持, -->  
     <prop key="hibernate.jdbc.batch_size">500</prop><!-- 批量删除,批量更新和批量插入的时候的批次大小 -->  
     <prop key=" hibernate.cache.use_second_level_cache">false</prop>  <!-- 关闭hibernate耳机缓存 -->
             
</props>  
</property>  
<property name="mappingLocations">  
<list>  
         <value>classpath:com/greatchn/htykj/db/po/*.hbm.xml</value>  
</list>  
</property>  
</bean>  
<bean id="webTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
    <property name="sessionFactory" ref="webSessionFactory" />  
</bean>  
<!-- 配置JDBC模板 -->  
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
<property name="dataSource" ref="webDataSource"></property>  
</bean>  
<!-- 配置HIBERNATE模板 -->  
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">  
<property name="sessionFactory" ref="webSessionFactory" />  
</bean>  
<tx:annotation-driven transaction-manager="webTransactionManager" proxy-target-class="true" /> 

把hibernate的批量操作设置为:500,关闭hibernate的二级缓存.

注意:做海量数据批量操作一定要关闭显示执行的sql语句.(我导入7万多条数据,停在2万条有一个原因就是这个).


@Controller层: 因为数据量太大,把查询查询到List分成10000条一份,分批次执行保存方法

zwPzfls是查询的到74711条的数据,

		int p = 0;
		if (zwPzfls.size() % 10000 == 0) {
			p = zwPzfls.size() / 10000;
		} else {
			p = zwPzfls.size() / 10000 + 1;
		}

		List zwPzflstemp = new ArrayList();
		System.out.println("共" + p + "批");
		for (int k = 1; k <= p; k++) {
			if (k == p) {
				System.out.println("第" + k + "批的10000条开始");
				for (int l = (k - 1) * 10000; l < zwPzfls.size(); l++) {
					ZwPzfl fl = zwPzfls.get(l);
					zwPzflstemp.add(fl);
					if (l == zwPzfls.size() - 1) {
						htykj2Service.saveZwpzfl(zwPzflstemp);
						zwPzflstemp.clear();
					}
				}
				System.out.println("第" + k + "批的10000条结束");
			} else {
				System.out.println("第" + k + "批的10000条开始");
				for (int l = (k - 1) * 10000; l < k * 10000; l++) {
					ZwPzfl fl = zwPzfls.get(l);
					zwPzflstemp.add(fl);
					if (l == k * 10000 - 1) {
						htykj2Service.saveZwpzfl(zwPzflstemp);
						zwPzflstemp.clear();
					}

				}
				System.out.println("第" + k + "批的10000条结束");
			}
		}	

@Service层:

	public void saveZwpzfl(List<ZwPzfl> pzflList) throws Exception{
		baseDao2Htykj.savePzflList(pzflList);
	}

@Dao层:

关键点:每一千条刷新并写入数据库  ,并清除seesion

	public void savePzflList(List<?> list) {
		
		try {
			Session session = this.webSessionFactory.getCurrentSession();
			//Transaction tx= session.beginTransaction(); 
			 for (int i = 0; i < list.size(); i++) {
				 ZwPzfl pzflList = (ZwPzfl) list.get(i);
				 pzflList.getId();
//				 System.out.println("::::::::::::::::::这个分录的id::::::::::::::::::"+ pzflList.getId() );
//				 System.out.println(".......执行进度:::......"+i);
				 
	                session.save(list.get(i));
	                if(i%1000 == 0){   //每一千条刷新并写入数据库  
	                    session.flush();  
	                    session.clear();  
	                }
	                
	            }
			// session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			closeSession();
		}
		
	}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页