/** * 堆代码 duidaima.com * 先保存通知消息,在批量保存用户通知记录 */ @Transactional(rollbackFor = Exception.class) @Override public boolean saveNotice(Notify notify, String receiveUserIds) { long begin = System.currentTimeMillis(); notify.setCreateTime(new Date()); notify.setCreateBy(ShiroUtil.getSessionUid()); if (notify.getPublishTime() == null) { notify.setPublishTime(new Date()); } boolean insert = save(notify); List<NotifyRecord> collect = new ArrayList<>(); List<String> receiveUserList = fillNotifyRecordList(notify, receiveUserIds, collect); notifyRecordService.saveBatch(collect); long end = System.currentTimeMillis(); System.out.println(end - begin); ... return insert; } /** * 根据用户id,组装用户通知记录集合,返回200条记录 */ public List<String> fillNotifyRecordList(Notify notify, String receiveUserIds, List<NotifyRecord> collect) { List<String> noticeRecordList = new ArrayList<>(200); ... // 组将两百条用户通知记录 return noticeRecordList; }如上代码,我有一个 saveNotice() 方法用于保存通知消息以及用户通知记录。执行逻辑如下:
3.批量保存用户通知记录集合
-- slow sql 5542 millis. INSERT INTO oa_notify_record ( notifyId, receiveUserId, receiveUserName, isRead, createTime ) VALUES ( ?, ?, ?, ?, ? )[225,"fcd90fe3990e505d07c90a238f75e9c1","niuwawa",false,"2023-10-30 23:54:04"] 5681再结合 mybatis free log 插件打印完整 sql 如下图,
public static void main(String[] args) { Connection conn = null; PreparedStatement statement = null; try { // 堆代码 duidaima.com // 数据库连接 String url = "jdbc:mysql://*************?autoReconnect=true&nullCatalogMeansCurrent=true&failOverReadOnly=false&useUnicode=true&characterEncoding=UTF-8"; String user = "******"; String password = "************"; // 添加批处理参数 // url = url + "&rewriteBatchedStatements=true"; // 加载驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); // 创建连接 conn = DriverManager.getConnection(url, user, password); // 创建预编译 sql 对象 statement = conn.prepareStatement("UPDATE table_test_demo set code = ? where id = ?"); long a = System.currentTimeMillis(); // 计时 // 这里添加 100 个批处理参数 for (int i = 1; i <= 100; i++) { statement.setString(1, "测试1"); statement.setInt(2, i); statement.addBatch(); // 批量添加 } long b = System.currentTimeMillis(); // 计时 System.out.println("添加参数耗时:" + (b-a)); // 计时 int[] r = statement.executeBatch(); // 批量提交 statement.clearBatch(); // 清空批量添加的 sql 命令列表缓存 long c = System.currentTimeMillis(); // 计时 System.out.println("执行sql耗时:" + (c-b)); // 计时 } catch (Exception e) { e.printStackTrace(); } finally { // 主动释放资源 try { if (statement != null) { statement.close(); } if (conn != null) { conn.close(); } } catch (SQLException throwables) { throwables.printStackTrace(); } } }statement.addBatch() 将 sql 语句打包到一个容器中
statement.clearBatch() 清空容器,为下一次打包做准备