参考 https://blog.csdn.net/xunwei0303/article/details/80241340?utm_source=blogxgwz1
创建多个线程,每个线程处理一批数据。
1. 创建表(mysql)
CREATE TABLE TEST_BATCH_INSERT ( TEST_ID bigint PRIMARY key, TEST_NAME VARCHAR(100), AGE INT(5), CREATE_TIME DATETIME DEFAULT current_timestamp, UPDATE_TIME DATETIME DEFAULT current_timestamp ) comment '测试批量插入';
2. java bean
public class TestBatchInsertInfo { private Long testId; private String testName; private Integer age; private Date createTime; private Date updateTime; // 省略getter/setter }
3. dao
public interface ITestBatchInsertMapper { void batchInsert(List<TestBatchInsertInfo> list); }
4. mapper.xml
<insert id="batchInsert" parameterType="java.util.List"> INSERT INTO TEST_BATCH_INSERT ( TEST_ID, TEST_NAME, AGE, CREATE_TIME, UPDATE_TIME ) VALUES <foreach collection="list" item="log" index= "index" separator =","> ( #{log.testId, jdbcType=NUMERIC}, #{log.testName, jdbcType=VARCHAR}, #{log.age, jdbcType=NUMERIC}, sysdate(), sysdate() ) </foreach> </insert>
5. 多线程
public class TestBatchInsertThread implements Runnable { private ITestBatchInsertMapper testBatchInsertMapper; /** 数据集合 */ private List<TestBatchInsertInfo> list; /** 每个线程处理的起始数据 */ private CountDownLatch begin; /** 每个线程处理的结束数据 */ private CountDownLatch end; public TestBatchInsertThread() { } public TestBatchInsertThread(List<TestBatchInsertInfo> list, CountDownLatch begin, CountDownLatch end, ITestBatchInsertMapper testBatchInsertMapper) { this.list = list; this.begin = begin; this.end = end; this.testBatchInsertMapper = testBatchInsertMapper; } @Override public void run() { try { if (list != null && !list.isEmpty()) { testBatchInsertMapper.batchInsert(list); } // 执行完让线程直接进入等待 begin.await(); } catch (Exception e) { e.printStackTrace(); } finally { // 当一个线程执行完 了计数要减一不然这个线程会被一直挂起 end.countDown(); } } }
6. service
多线程处理的方法是 batchInsertByThread;
普通批量处理的方法是 batchInsert
@Service(value = "testBatchInsertService")
public class TestBatchInsertServiceImpl implements ITestBatchInsertService {
@Autowired
private ITestBatchInsertMapper testBatchInsertMapper;
@Override
@Transactional
public void batchInsertByThread(List<TestBatchInsertInfo> list) throws Exception {
if (list == null || list.isEmpty()) {
return;
}
// 一个线程处理300条数据
int count = 1000;
// 数据集合大小
int listSize = list.size();
// 开启的线程数
int runSize = (listSize / count) + 1;
// 存放每个线程的执行数据
List<TestBatchInsertInfo> newList = null;
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 创建两个个计数器
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(runSize);
for (int i = 0; i < runSize; i++) {
/* 计算每个线程执行的数据 */
if ((i + 1) == runSize) {
int startIdx = (i * count);
int endIdx = list.size();
newList = list.subList(startIdx, endIdx);
} else {
int startIdx = (i * count);
int endIdx = (i + 1) * count;
newList = list.subList(startIdx, endIdx);
}
TestBatchInsertThread thread = new TestBatchInsertThread(newList, begin, end, testBatchInsertMapper);
executor.execute(thread);
}
begin.countDown();
end.await();
executor.shutdown();
}
@Override
public void batchInsert(List<TestBatchInsertInfo> list) {
if (list == null || list.isEmpty()) {
return;
}
List<TestBatchInsertInfo> tempList = new LinkedList<>();
for (int i = 0; i < list.size(); i++) {
tempList.add(list.get(i));
if (i % 1000 == 0) {
testBatchInsertMapper.batchInsert(tempList);
tempList.clear();
}
}
testBatchInsertMapper.batchInsert(tempList);
}
}
7. junit4 测试方法
import java.util.LinkedList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.jieshun.springboot.mybatis.MybatisApplication; import com.jieshun.springboot.mybatis.bean.po.TestBatchInsertInfo; import com.jieshun.springboot.mybatis.service.ITestBatchInsertService; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = MybatisApplication.class/*, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT*/) public class TestBatchInsertService { @Autowired private ITestBatchInsertService testBatchInsertService; @Test public void batchInsertByThread() { long startTime = System.currentTimeMillis(); try { List<TestBatchInsertInfo> list = new LinkedList<>(); TestBatchInsertInfo info = null; for (int i = 0; i < 100301; i++) { Integer ig = i; info = new TestBatchInsertInfo(); info.setTestId(ig.longValue()); info.setTestName("test名称_" + i); info.setAge(i); list.add(info); } testBatchInsertService.batchInsertByThread(list); System.out.println("------Batch Insert Success------"); } catch (Exception e) { e.printStackTrace(); } System.out.println("耗时(ms):" + (System.currentTimeMillis() - startTime)); } @Test public void batchInsert() { long startTime = System.currentTimeMillis(); try { List<TestBatchInsertInfo> list = new LinkedList<>(); TestBatchInsertInfo info = null; for (int i = 0; i < 100301; i++) { Integer ig = i; info = new TestBatchInsertInfo(); info.setTestId(ig.longValue()); info.setTestName("test名称_" + i); info.setAge(i); list.add(info); } testBatchInsertService.batchInsert(list); System.out.println("------Batch Insert Success------"); } catch (Exception e) { e.printStackTrace(); } System.out.println("耗时(ms):" + (System.currentTimeMillis() - startTime)); } }
8. springboot 启动类
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * 应用启动类 * * @author * @date 2018年10月17日 * @since JDK 1.8 */ @SpringBootApplication @EnableTransactionManagement @ComponentScan(basePackages = { "com.jieshun.springboot.mybatis" }) @MapperScan(basePackages = { "com.jieshun.springboot.mybatis.dao" }) public class MybatisApplication { public static void main(String[] args) { SpringApplication.run(MybatisApplication.class, args); } }
相关推荐
mybaits 多线程 实现数据批量插入 (运用CountDownLatch实现闭锁) 1、mybatis批处理 2、数据分批量查询 3、数据分批量插入
java多线程处理大数据,可根据配置的线程数,任务去调度处理
shell的多线程,以及使用多线程编写shell脚本实现当前文件夹下批量插入MySQL。
易安卓E4A多线程大数据网络通讯TCP b1.4 支持大数据文件、图片、直接发送,支持双向,无需要用户分包组包,模块库自动智能处理,目前此模块是E4A唯一最强大通讯模块,也是安卓,JAVA中最强大通讯模块之一!
对大数据量的导出excel,用多线程,用倒数计数器对文件进行生成,使用poi,可以支持大数据量的生成,项目中使用的poi是3.1的,上传的是4.1的。
Socket 客户端代码封装、服务端代码封装,让使用Socket更简单。 同时服务端支持超过客户端连接(测试超过1万个同时连接稳定运行),Tasks多线程 队列处理 大数据拆分包处理
Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...
Java多线程读取大文本文件并批量插入MongoDB的代码,文本文件,csv文件,可以结合POI改造使其支持excel。 适合做大量文本数据或日志文件入库的场景,大文本被拆分成多个线程处理,速度快。 批量插入MongoDB,存在则...
多线程在.net中实现是非常容易的。 VB6本身无法实现多线程编程,但是通过第三方控件,也可以很完美的实现多线程。 本例实现的是在主界面开一个新的线程在后台完成数据查询并根据提供的每页显示的数据行数计算出总...
应用线程解决界面的假死状态,应用高级SQL语句执行快速导入、导出数据操作。
phpMyAdmin多线程批量破解工具是一款用于数据库密码强制破解的工具,了解它的朋友想必不用做过多的介绍就应该了解他他是做什么的。 之前朋友问我有木有phpMyAdmin批量破解工具, 我在网上搜索了一下并没有发现相关的...
01大数据面试复习----Java基础---集合类、多线程、JVM.zip
java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
主要给大家介绍C#.net中如何批量插入大量数据到数据库中,本文涉及到C#.net中批量插入数据到数据库中方面的内容,对C#.net批量插入数据到数据库中感兴趣的朋友可以参考下本
(转)VB6实现多线程数据库大数据查询 VB6本身无法实现多线程编程,但是通过第三方控件,也可以很完美的实现多线程。 本例实现的是在主界面开一个新的线程在后台完成数据查询并根据提供的每页显示的数据行数计算出总...
提供了批量ping IP检测连通性的功能,可支持单IP,多IP,从文件中导入IP列表功能。当IP数量较多时,启用多线程ping,提高ping测效率
FTP 多线程 批量 上传、建目录。 免费放出!快来下载吧!
多线程通信,QT5.11.1,多线程TCP服务器,多线程连接客户端。QThread
c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程...
delphi7多线程批量下载代码,线程稳定,可突破服务器限速 , 可拿来学习. 代码直接编译可用.