eclipse学习(第三章:ssh中的Hibernate)——12.Hibernate进行批量处理数据

1 前言

本文参考自https://www.w3cschool.cn/hibernate/b2qo1ieh.html

2 项目处理

2.1 jar包拉取

在这里插入图片描述

2.2 新建一个classes_test表

在这里插入图片描述

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for classes_test
-- ----------------------------
DROP TABLE IF EXISTS `classes_test`;
CREATE TABLE `classes_test` (
  `id` varchar(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `student_number` int(11) DEFAULT NULL,
  `teacher` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.3 创建hibernate.cfg.xml

hibernate.cfg.xml,这里主要是弄一个批量处理的那个属性

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<!--mysql的驱动包 -->
		<property name="connection.driver_class">
			com.mysql.cj.jdbc.Driver
		</property>
		<!--数据库连接地址,这里数据库以参数形式传入,以;分隔不同参数-->
		<property name="connection.url">
			jdbc:mysql://localhost:3306/student?serverTimezone=UTC
		</property>
		<!--数据库账号-->
		<property name="connection.username">
			root
		</property>
		<!--数据库密码-->
		<property name="connection.password">
			root
		</property>
		<!--数据库连接池-->
		<property name="connection.pool_size">
			10
		</property>
		<!--日志文件中是否展示sql-->
		<property name="show_sql">
			true
		</property>
		<!--设置Hibernate SQL方言-->
		<property name="dialect">
			org.hibernate.dialect.MySQLDialect
		</property>
	<!-- 其实这个hibernate.hbm2ddl.auto参数的作用主要用于:自动创建|更新|验证数据库表结构。如果不是此方面的需求建议set value="none"。 -->
	<!-- create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。 -->
	<!-- create-drop : 每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。-->
	<!-- update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。 -->
	<!-- validate : 每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。-->
		<property name="hbm2ddl.auto">
			update
		</property>
		
<!-- 		批量处理:查数据一次多少条 -->
		<property name="hibernate.jdbc.fetch_size">5</property>  
<!-- 		批量处理:修改数据一次多少条 -->
		<property name="hibernate.jdbc.batch_size">5</property>  
		
		<mapping class="com.czx.batch.pojo.ClassesTest"/>
	</session-factory>
</hibernate-configuration>

2.4 创建ClassesTest

ClassesTest

package com.czx.batch.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "classes_test")
public class ClassesTest {
	
	@Id 
//	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column
	private String id;
	
	@Column
	private String name;
	
	@Column(name = "student_number")
	private Integer studentNumber;
	
	@Column(name = "teacher")
	private String teacher;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getStudentNumber() {
		return studentNumber;
	}

	public void setStudentNumber(Integer studentNumber) {
		this.studentNumber = studentNumber;
	}

	public String getTeacher() {
		return teacher;
	}

	public void setTeacher(String teacher) {
		this.teacher = teacher;
	}

	public ClassesTest(String id, String name, Integer studentNumber, String teacher) {
		this.id = id;
		this.name = name;
		this.studentNumber = studentNumber;
		this.teacher = teacher;
	}

	public ClassesTest() {
	}

	@Override
	public String toString() {
		return "ClassesTest [id=" + id + ", name=" + name + ", studentNumber=" + studentNumber + ", teacher=" + teacher
				+ "]";
	}

	
}

2.5 创建BatchManagement

BatchManagement 。
批量处理有三种办法:
第一种是绕过了hibernate的api,不用它了,转而使用jdbc的方法去进行批量处理,这里的示例是批量修改,自己填充些数据处理就可。
第二种是运用存储过程。
第三种是Hibernate API 来进行常规的批量处理。这里要小心如果数据量过大的话,我们是无法一次性处理完的。我们可以通过flush方法来实现提交到数据库,flush方法强制让内存的数据与数据库同步,默认是在事务提交commit的时候flush。clear是清空session中的缓存,这样一来就不会过多的占用session缓存空间导致效率降低,而且我们的本意也不是存在session中。如果有开启2级缓存的话记得关闭掉。

package com.czx.batch;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.czx.batch.pojo.ClassesTest;

public class BatchManagement {
	
	private static SessionFactory sessionFactory;
	
	public static void main(String[] args) {
		try {
			sessionFactory = new Configuration().configure().buildSessionFactory();
		}catch (Exception e) {
			System.out.println("初始化sessionFactory失败:"+e);
			throw new ExceptionInInitializerError(e);
		}
		
		BatchManagement batchManagement = new BatchManagement();
		//使用jdbc的api处理
//		batchManagement.batchSaveClasses01();
		
		//分段插入
		batchManagement.batchSaveClasses03();
		
	}
	
	

	
	//使用JDBC的api来实现,绕过hibernate的api,这是最快的,性能也还好。这里是批量增加
	public void batchSaveClasses01() {
		String URL = "jdbc:mysql://127.0.0.1:3306/Student?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
		String USER = "root";
		String PASSWORD = "root";
		try {

			Class.forName("com.mysql.cj.jdbc.Driver");
			Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
			Integer studentNumber = 3;
			String sql="update classes_test set student_number = student_number +1 where student_number > ?";
			PreparedStatement statement = conn.prepareStatement(sql);
			statement.setInt(1, studentNumber);
			statement.executeUpdate();
		
			statement.close();	
			conn.close();					
		} catch (ClassNotFoundException e) {			
			e.printStackTrace();
		}catch (SQLException e) {			
			e.printStackTrace();
		}		

	}
	
	
	//运用存储过程我暂时不太会,先记录一下好了。
	
	//优化Hibernate,程序上采用分段插入及时清除缓存的方法
	public void batchSaveClasses03() {
		Session session = sessionFactory.openSession();
		Transaction transaction = null;
		
		try {
			transaction = session.beginTransaction();
			for(int i = 1; i <= 15; i++) {
			ClassesTest classes = new ClassesTest(i+"", "name"+i, i, "teacher"+i);
			session.save(classes);
			if(i % 5 == 0) {
				session.flush();
				session.clear();
				}
			}
			transaction.commit();
		}catch (Exception e) {
			// TODO: handle exception
		}finally {
			session.close();
		}
	}
}

中途遇到的小异常

注意clear和close不一样,由于之前一直写的是close,所以clear没选到,一直报错,很难受,最后终于发现了。

项目地址

基本上看上面就能懂了,实在不懂再下载看看吧。
https://gitee.com/mrchen13427566118/ssh_hibernate_learn.git里面的ssh_hibernate_batch项目。
打开方式看https://blog.csdn.net/weixin_43987277/article/details/116936221里面的第三点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值