将数据批量插入数据库

核心代码展示:

@Component
public class AsyncExecutorPoolConfig {
    private static final Logger LOG = LoggerFactory.getLogger(AsyncExecutorPoolConfig.class);

    @Value("${peroninfo.async.log.queueSize:30000}")
    private int queueSize;

    @Value("${peroninfo.async.log.queueSize:200}")
    private int batchSize;

    @Value("${peroninfo.async.log.queueSize:10}")
    private int threadPoolSize;

    /**
     * 批量执行标志
     */
    private volatile boolean runBatch = false;

    private ExecutorService threadPool;

    private ArrayBlockingQueue<Count> blockingQueue;

    private final CountManagementService countManagementService;

    @Autowired
    public AsyncExecutorPoolConfig(CountManagementService countManagementService) {
        this.countManagementService = countManagementService;
    }

    @PostConstruct
    public void init() {
        blockingQueue = new ArrayBlockingQueue<>(queueSize);
        threadPool = Executors.newFixedThreadPool(threadPoolSize);
    }

    @PreDestroy
    public void destroy() {
        //  批量保存日志
        batchSave();

        // 关闭线程池
        if (threadPool != null) {
            threadPool.shutdown();
        }
    }

    /**
     * 添加到异步日志队列中
     *
     * @param
     */
    public void put(Count count) {
//        // 如果队列满了,主动调用批量方法
        if (blockingQueue.size() >= queueSize) {
            runBatch();
        }
        try {
            blockingQueue.put(count);
        } catch (InterruptedException e) {
            LOG.warn("Interrupted!", e);
        }
    }

    @Scheduled(cron = "${peroninfo.async.log.cron:0/5 * * * * ?}")
    public void runBatch() {
        if (runBatch) {
            LOG.info("batchSave Is already running.");
            return;
        }

        runBatch = true;
        try {
            // 批量保存日志
            batchSave();

        } catch (Throwable e) {
            runBatch = false;
            throw e;
        }

        runBatch = false;
    }

    /**
     * 批量保存日志
     */
    private void batchSave() {
        List<Count> buffer = new ArrayList<>(batchSize);

        do {
            // 获取日志对象
            Count poll = blockingQueue.poll();
            if (poll == null) {
                break;
            }
            buffer.add(poll);

            if (buffer.size() >= batchSize) {
                // 保存日志
                save(buffer);
                // 构建新的日志缓冲
                buffer = new ArrayList<>(batchSize);
            }

        } while (true);

        // 保存日志
        save(buffer);
    }

    /**
     * 保存日志
     *
     * @param buffer 日志缓冲
     */
    private void save(List<Count> buffer) {
        if (buffer.size() > 0) {
            threadPool.execute(() -> countManagementService.saveLog(buffer));
        }
    }

}

service接口类:

public interface CountManagementService extends IService<Count> {

    void saveLog(List<Count> buffer);

}

实现类:

@Override
public void saveLog(List<Count> buffer) {
    try (SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false)) {
        // 保存主表 RuleflowExecuteLog
        for (Count tbPersonInterfacelog : buffer) {
            // insert
            sqlSession.insert("cc.xx.dao.CountMapper.saveCount", tbPersonInterfacelog);
        }
        // 提交事务
        sqlSession.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

cc.xx.dao.CountMapper.saveCount:

public interface CountMapper extends MyMapper<Count> {

    int saveCount( Count count);

}

插入语句实现:

<insert id="saveCount" parameterType="cc.xx.domain.Count">

insert into tableA () values ()

</insert>

### 使用Python执行批量插入数据库 为了高效地向数据库插入大量数据,可以采用多种方法。一种常见的方式是利用`pandas`库读取CSV文件并将其转换为适合批量插入数据结构[^1]。 #### 方法一:使用 `pandas.DataFrame.to_sql` 通过Pandas DataFrame对象可以直接调用`.to_sql()`函数实现批量入操作: ```python import pandas as pd from sqlalchemy import create_engine engine = create_engine('sqlite:///example.db') # 替换为目标数据库连接字符串 df = pd.read_csv('data.csv') df.to_sql(name='table_name', con=engine, if_exists='append', index=False) ``` 这种方法适用于大多数关系型数据库管理系统(RDBMS),并且能够自动处理大部分类型的字段映射问题。 #### 方法二:使用 `executemany()` 对于更细粒度控制的情况,可以通过SQLAlchemy或其他ORM框架提供的API手动构建参数化查询,并传递给`execute_many()`或类似的批处理接口完成多条记录的同时提交: ```python import sqlite3 conn = sqlite3.connect(':memory:') cursor = conn.cursor() values = [ ('value1_col1', 'value1_col2'), ('value2_col1', 'value2_col2'), ] query = "INSERT INTO table_name (column1, column2) VALUES (?, ?)" cursor.executemany(query, values) conn.commit() ``` 此方式允许开发者更好地管理事务边界以及错误恢复逻辑,在面对大规模并发场景时表现尤为突出[^3]。 当涉及到复杂嵌套的对象序列化成JSON格式存储于特定列内,则需先将这些对象转储为字典形式再进一步加工成为合法的JSON串[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值