首页 > 解决方案 > 如何使用 Spring 数据快速添加/删除多对多关系中的对象

问题描述

我的问题是这个。我有 2 个对象称为SeedRecordAffiliateLink。两者之间都具有多对多关系。Affiliatelinks 基于一组关键字与种子记录链接,用户可以使用这些关键字来表征affiliatelink 产品。例如。如果affiliatelink产品对tomatocucumber和有用。然后在创建 AffiliateLink 对象期间,它会链接到所有具有这些关键字之一作为特征的种子记录。因此,例如,如果特定种子记录的列的值为,则关联链接将被添加到其集合中。bellpepperClimbing plantCropNametomato

如果数据集很小,这一切都很好,但是如果有超过 2000 个种子记录,其中 200 个具有特征,则将关联链接添加到正确的种子记录可能会变得非常滞后tomato。我JpaRepository将不得不保存 200 次才能将附属链接与所有正确的种子记录相关联。这可能需要几分钟!

与其向数据库发送 200 个小保存查询,我认为如果我可以将所有保存操作放在一个大查询中,事情会分配得更快。但我不知道 Spring Data 是否可行。删除操作与保存操作一样滞后。有谁知道更有效的方法来做到这一点?

谢谢你。

标签: javamysqlspringspring-data-jpaspring-data

解决方案


好吧,我已经设法将使用所有不同的 jparepository 保存方法的时间从 5 秒减少到 10 秒,而使用 JDBC 批量插入则将时间缩短到 1.5 到 2 秒!

如果有人感兴趣,这是我的代码:

@Autowired
private DataSource dataSource;

    if (!affiliateLinkOwners.isEmpty()) {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);
            PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO seedrecord_affiliatelink (SEEDRECORD_ID, AFFILIATE_ID) VALUES (?,?)");
            for(long id: affiliateLinkOwners)
                    {
                        preparedStatement.setLong(1,id);
                        preparedStatement.setLong(2,affiliateLink.getId());
                        preparedStatement.addBatch();
                    }

            preparedStatement.executeBatch();
            connection.commit();
            preparedStatement.close();
            connection.close();
            log.info(affiliateLinkOwners +"");
            log.info("the id is " + affiliateLink.getId());
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }

继承自自动装配的数据源本身:

@Bean(destroyMethod = "close")
public DataSource seedDataSource(){
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setDriverClassName(driver);
    hikariConfig.setJdbcUrl(dataBaseUrl); 
    hikariConfig.setUsername(userName);
    hikariConfig.setPassword(password);
    hikariConfig.setMaximumPoolSize(5);
    hikariConfig.setConnectionTestQuery("SELECT 1");
    hikariConfig.setPoolName("springHikariCP");
    hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", "true");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", "250");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048");
    hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", "true");
    HikariDataSource dataSource = new HikariDataSource(hikariConfig);
    return dataSource;
}

编辑:我只将种子记录的 ID 和附属 ID 插入可连接


推荐阅读