转自:https://www.jeejava.com/spring-data-jpa-batch-insertion/

Spring Data JPA Batch Insertion will show you how we can insert a large dataset into a database at once using Spring Data JPA. For this tutorial we will create a Spring Boot project in Eclipse. We will also see how Spring @Transactional annotation works. Spring transaction required in order to rollback the inserted data at any point if your application fails for any reason.

Sometimes we need to insert or update large number of records in the database. It’s not a good idea to insert multiple records into database one by one in a traditional approach. It will hit the application’s performance. Spring provides batch operations with the help of JpaRepository or CrudRepository, it inserts or updates records into database in one shot. You can also use JDBC API to insert multiple records or batch insertion into database but here we will use Spring JPA’s built-in functionality to get benefits of Spring API.

By default Spring does not save your data into database when you call save() method with multiple entities (a list of objects) passed as argument, hence you have to save entities one by one, which is time consuming and performance gets affected. For this there are few properties that need to be configured to let Spring Data JPA work on batch insertion into database. We will see how these properties set during creation of database configuration class below.

You may also like to read:

Batch Insert using Spring JdbcTemplate

Transaction Management in Spring

Hibernate UserType using Spring Data JPA

Spring EnableEncryptableProperties with Jasypt

Spring Data JPA Entity Auditing using EntityListeners

Spring Data JPA Entity Graph

Spring Data JPA CRUD Example

Prerequisites

The following configurations are required in order to run the application

Eclipse
JDK 1.8
Have gradle installed and configured
Spring dependencies in build.gradle script

Now we will see the below steps how to create a gradle based spring project in Eclipse to work on example Spring Data JPA Batch Insertion.

Creating and setting up the project

First you need to setup the gradle based project in Eclipse and we have to make sure using the below build script we will be able to build the blank project.

In this file notice we have applied required plugins and added required dependencies, such as spring-boot-starter-web, spring-boot-starter-data-jpa and oracle jdbc driver to interact with Java and database API.

Once you create below file, please try to build the project, you should be able to build the blank project.

  1. buildscript {
  2. ext {
  3. springBootVersion = '1.5.9.RELEASE'
  4. }
  5. repositories {
  6. mavenLocal()
  7. mavenCentral()
  8. }
  9. dependencies {
  10. classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  11. }
  12. }
  13.  
  14. apply plugin: 'java'
  15. apply plugin: 'org.springframework.boot'
  16.  
  17. sourceCompatibility = 1.8
  18. targetCompatibility = 1.8
  19.  
  20. repositories {
  21. mavenLocal()
  22. mavenCentral()
  23. }
  24.  
  25. dependencies {
  26. compile('org.springframework.boot:spring-boot-starter-web')
  27. compile("org.springframework.boot:spring-boot-starter-data-jpa")
  28. runtime("com.oracle.jdbc:ojdbc7:12.1.0.2")
  29. }

Creating application.properties file under classpath

Below is the application.properties file under classpath directory src/main/resources and you need to define database credentials to establish connection with database.

Also if you do not want server to run on default port then you may want to specify the server port using server.port key.

Here in Spring Data JPA Batch Insertion example, I am going to use Oracle database but you may use any database as per your requirements.

  1. #datasource
  2. spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
  3. spring.datasource.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect
  4. spring.datasource.url=jdbc:Oracle:thin:@//<host>:<port>/<service name>
  5. spring.datasource.username=<username>
  6. spring.datasource.password=<password>
  7.  
  8. server.port=9999
  9.  
  10. #disable schema generation from Hibernate
  11. spring.jpa.hibernate.ddl-auto=none

Creating database configuration class

Below is the configuration class that will be used to define various database related beans such as DataSource, EntityManagerFactory etc.

As we know JPA is a specification or Interface and someone has to provide its own implementation, so here we are using Hibernate as an implementation of JPA API.

As we have application.properties file in classpath, so we don’t need to load the properties file.

We have let Spring know where our Spring Data JPA Repository interfaces using the annotation @EnableJpaRepositories and we have also let Spring know where to look for Entity classes using the setter method factory.setPackagesToScan(“com.jeejava.entity”).

By default Spring does not work when you want to insert multiple records or entities using save() method of JpaRepository or CrudRepository and that’s why you need to set few properties into

LocalContainerEntityManagerFactoryBean as shown below in entityManagerFactory() method. You can change the batch size, here I have put 500.

By default Spring transaction works out of the box so you may not need to annotate the configuration class with @EnableTransactionManagement.

  1. package com.jeejava.config;
  2.  
  3. import javax.persistence.EntityManagerFactory;
  4. import javax.sql.DataSource;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.core.env.Environment;
  9. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  10. import org.springframework.jdbc.datasource.DriverManagerDataSource;
  11. import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  12. import org.springframework.orm.jpa.vendor.Database;
  13. import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
  14.  
  15. @Configuration
  16. @EnableJpaRepositories(basePackages = "com.jeejava.repository")
  17. public class DatabaseConfig {
  18.  
  19. @Autowired
  20. private Environment environment;
  21.  
  22. @Bean
  23. public DataSource dataSource() {
  24. DriverManagerDataSource ds = new DriverManagerDataSource();
  25. ds.setDriverClassName(environment.getRequiredProperty("spring.datasource.driverClassName"));
  26. ds.setUrl(environment.getRequiredProperty("spring.datasource.url"));
  27. ds.setUsername(environment.getRequiredProperty("spring.datasource.username"));
  28. ds.setPassword(environment.getRequiredProperty("spring.datasource.password"));
  29. return ds;
  30. }
  31.  
  32. @Bean
  33. public EntityManagerFactory entityManagerFactory(DataSource dataSource) {
  34. HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
  35. vendorAdapter.setDatabase(Database.ORACLE);
  36. LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
  37.  
  38. //Use these properties to let spring work on batch insertion
  39. Properties jpaProperties = new Properties();
  40. jpaProperties.put("hibernate.jdbc.batch_size", 500);
  41. jpaProperties.put("hibernate.order_inserts", true);
  42. jpaProperties.put("hibernate.order_updates", true);
  43. lemfb.setJpaProperties(jpaProperties);
  44.  
  45. factory.setJpaVendorAdapter(vendorAdapter);
  46. factory.setPackagesToScan("com.jeejava.entity");
  47. factory.setDataSource(dataSource);
  48. factory.afterPropertiesSet();
  49. return factory.getObject();
  50. }
  51. }

Creating entity class

This is the entity class that maps Java object to database table. This entity class represents a single row in database table. When you want to save multiple rows in database table then you pass a list of entity objects to JpaRepository or CrudRepository’s save() method in order to save multiple entities or objects and this basically happens through Spring Data JPA Batch Insertion configuration. We also save single object using the same save() method.

  1. package com.jeejava.entity;
  2.  
  3. import java.io.Serializable;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.Id;
  7. import javax.persistence.Table;
  8.  
  9. @Entity
  10. @Table(name = "EMPLOYEE")
  11. public class Employee implements Serializable {
  12.  
  13. private static final long serialVersionUID = 1L;
  14.  
  15. @Id
  16. @Column(name = "EMPLOYEE_ID")
  17. private Integer empId;
  18.  
  19. @Column(name = "EMPLOYEE_NAME")
  20. private String empName;
  21. //getters and setters
  22. }

Spring Data JPA Repository

Here is the Spring Data JPA Repository interface. Here JpaRepository takes two parameters Employee object, i.e., entity object and primary key, i.e., Integer. You may have Long, String or any other class object as a primary key as well.

  1. package com.jeejava.repository;
  2.  
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import com.jeejava.entity.Employee;
  5.  
  6. public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
  7. }

Creating Service class

This is the service class that interacts with data layer as well as controller layer and acts as a mediator between them. This class generally handles all business logic.

In this service we will see the example on Spring Data JPA Batch Insertion. Here notice how I am determining when to insert into database.

Here we iterate through list of employee objects and add to temporary Employee array list. Once we find counter equals to batch size(500) then we save those entity objects and at the same time we also clear the temp list because we don’t need those records in temp list any more.

Notice we have used @Transactional annotation in order to support Spring’s transaction management to rollback database insertion at any point of failures.

  1. package com.jeejava.service;
  2.  
  3. import java.util.List;
  4. import javax.annotation.Resource;
  5. import org.springframework.stereotype.Service;
  6. import com.jeejava.entity.Employee;
  7. import com.jeejava.repository.EmployeeRepository;
  8.  
  9. @Service
  10. public class EmployeeService {
  11. @Resource
  12. private EmployeeRepository employeeRepository;
  13. @Transactional
  14. public void saveEmployees(List<Employee> employees) {
  15. int size = employees.size();
  16. int counter = 0;
  17.  
  18. List<Employee> temp = new ArrayList<>();
  19.  
  20. for (Employee emp : employees) {
  21. temp.add(emp);
  22.  
  23. if ((counter + 1) % 500 == 0 || (counter + 1) == size) {
  24. employeeRepository.save(temp);
  25. temp.clear();
  26. }
  27. counter++;
  28. }
  29. }
  30. }

Spring REST Controller

The Spring REST Controller class is resposible for handling requests and responses from clients. This holds all the REST services end-points. Using these end-points we would be able to get the JSON response.

Here we have only one end-point called /employees/save that saves a list of employees into database when you hit the URL http://localhost:9999/employees/save from REST client or Postman with a list of employee objects in JSON format as a body parameter.

  1. package com.jeejava.controller;
  2.  
  3. import java.util.List;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.http.HttpStatus;
  6. import org.springframework.http.ResponseEntity;
  7. import org.springframework.web.bind.annotation.GetMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import com.jeejava.entity.Employee;
  10. import com.jeejava.service.EmployeeService;
  11.  
  12. @RestController
  13. public class EmployeeRestController {
  14.  
  15. @Autowired
  16. private EmployeeService employeeService;
  17.  
  18. @PostMapping("/employees/save")
  19. public ResponseEntity<Void> saveEmployees(@RequestBody List<Employee> employees) {
  20. employeeService.saveEmployees(employees);
  21. return new ResponseEntity<Void>(HttpStatus.OK);
  22. }
  23. }

Here is the application main class that is enough to start up the application in Spring Boot.

  1. package com.jeejava.application;
  2.  
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5.  
  6. @SpringBootApplication(scanBasePackages = "com.jeejava")
  7. public class Application {
  8.  
  9. public static void main(String[] args) {
  10. SpringApplication.run(Application.class, args);
  11. }
  12. }

Once you run the above main class and application gets start up, hit the URL http://localhost:9999/employees/save from REST client or Postman with list of employee objects as json and you should get the JSON response with OK.

You may also like to read:

Batch Insert using Spring JdbcTemplate

Transaction Management in Spring

Hibernate UserType using Spring Data JPA

Spring EnableEncryptableProperties with Jasypt

Spring Data JPA Entity Auditing using EntityListeners

Spring Data JPA Entity Graph

Spring Data JPA CRUD Example

That’s all. Hope you found idea on Spring Data JPA Batch Insertion.

Thanks for reading.

Spring Data JPA Batch Insertion的更多相关文章

  1. spring data jpa开启批量插入、批量更新

    spring data jpa开启批量插入.批量更新 原文链接:https://www.cnblogs.com/blog5277/p/10661096.html 原文作者:博客园--曲高终和寡 *** ...

  2. Spring Boot:整合Spring Data JPA

    综合概述 JPA是Java Persistence API的简称,是一套Sun官方提出的Java持久化规范.其设计目标主要是为了简化现有的持久化开发工作和整合ORM技术,它为Java开发人员提供了一种 ...

  3. 快速搭建springmvc+spring data jpa工程

    一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...

  4. spring boot(五):spring data jpa的使用

    在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...

  5. 转:使用 Spring Data JPA 简化 JPA 开发

    从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...

  6. 深入浅出学Spring Data JPA

    第一章:Spring Data JPA入门 Spring Data是什么 Spring Data是一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得对数据的访问变得方便快捷,并支持map ...

  7. spring data jpa 调用存储过程

    网上这方面的例子不是很多,研究了一下,列出几个调用的方法. 假如我们有一个mysql的存储过程 CREATE DEFINER=`root`@`localhost` PROCEDURE `plus1in ...

  8. Spring Data JPA 学习记录1 -- 单向1:N关联的一些问题

    开新坑 开新坑了(笑)....公司项目使用的是Spring Data JPA做持久化框架....学习了一段时间以后发现了一点值得注意的小问题.....与大家分享 主要是针对1:N单向关联产生的一系列问 ...

  9. Spring Boot with Spring Data JPA (1) - Concept

    What's Spring Data JPA? According to Pivotal, Spring Data JPA, part of the larger Spring Data family ...

随机推荐

  1. linux 安装ssh以及ssh用法与免密登录

    想要免费登录就是把本地机器的id_rsa_pub的内容放到远程服务器的authorized_keys里面 一.配置yum和hosts文件 配置hosts文件: 命令:vi /etc/hosts 在文件 ...

  2. [转帖]Ipvsadm参数详解(常用命令)

    Ipvsadm参数详解(常用命令) 2013年11月29日 12:41:40 怀素1980 阅读数:15901   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  3. 用stringstream可以用来分割空格、tab、回车换行隔开的字符串:

    #include <iostream> #include <sstream> #include <vector> using namespace std; int ...

  4. java中解决小数精度问题

    public class TestDouble { public static void main(String[] args) { Double d1 = 0.1; Double d2 = 0.2; ...

  5. 《笔记》Apache2 mod_wsgi的配置

    接手了一台古老的服务器的还使用的是mod_wsgi,所以需要配置一下.其实这里有点怀念,记得当年自己折腾第一个app的时候,还是个什么都不懂的菜鸡.当时用django搜方案的时候,还不知道有uwsgi ...

  6. vue事件綁定

    事件綁定可以是一個句子,一個函數名稱,也可以是一個函數. 事件修飾符,按鍵修飾符.

  7. 四、K8S

    一.查看日志 journalctl -xeu kubelet

  8. easyui combobox 在datagrid中动态加载数据

    场景:datagrid 中用编辑框修改数据,有一个列使用的combobox  在可编辑的时候需要动态绑定数据,这个数据是在根据其他条件可变的 思路:在每次开启编辑框的时候动态绑定数据, datagri ...

  9. 解析xml文件 selectSingleNode取不到节点

    今天在做批量生成XML的时候,碰到一个情况 解析xml文件 selectSingleNode一直返回NULL. XML的格式开头有一句这个<CE401Message xmlns="ht ...

  10. SpringMVC中对多部件类型解析---文件(图片)上传

    加入上传图片jar包 commons-io-2.4.jar commons-fileupload-1.3.jar 在页面form中提交enctype="multipart/form-data ...