当前位置: 首页 > 知识库问答 >
问题:

针对Oracle的MyBatis批量插入/更新

焦兴为
2023-03-14

我最近开始学习使用myBatis。我现在面临这样一个场景,我需要通过WebService不断获取一个新的对象列表,然后对于这个列表,我需要通过myBatis将每个对象插入/更新到oracle DB表中。

棘手的是,我不能每次都简单地进行批量插入,因为有些对象可能已经存在于数据库中,对于这些记录,我需要更新它们的字段,而不是新的插入。

我目前的解决方案可能非常愚蠢,使用Java,从webservice构建对象列表,循环遍历每个对象,执行myBatis选择,如果它不是null(数据库中已经存在),则执行myBatis更新;否则,请为此新对象执行myBatis插入。

功能实现了。但是我的技术主管说它效率很低,因为使用Java和一个接一个地插入/更新做一个for循环会消耗大量的系统资源。他建议我通过传递一个对象列表来使用myBatis进行批量插入。

在myBatis中批量插入很简单,但是,因为我不是纯粹的插入(对于现有的记录,我需要进行更新),我不认为批量插入在这里是合适的。我在谷歌上搜索了一段时间,意识到也许我需要使用“合并”而不是“插入”(对于甲骨文)。

我在myBatis中搜索出的合并示例仅适用于一个对象,而不是批处理。因此,我想知道专家是否可以为我提供一些关于如何在MyBatis中进行批量合并的例子(编写映射器的正确方法)?

共有3个答案

彭宏义
2023-03-14

oracle中,如果你想同时执行多个语句,你必须把你的语句放在“开始”和“结束”块中。因此,请尝试添加属性Foreach如下。这肯定行得通。


<foreach collection="customerList" item="object" open="begin" close=";end;" separator=";">
    UPDATE customer SET isActive = #{object.isactive}
    WHERE  customerId= #{object.customerId}
</foreach>
汤飞
2023-03-14

在我的情况下也有同样的情况。我使用循环来检查这个记录是否存在于数据库中,然后根据我将这个对象添加到两个数组列表中进行插入或更新。然后使用批处理进行插入,并在循环之后进行更新以列出。

这里是例。根据不同的情况更新

1] 这是更新

<foreach collection="attendingUsrList" item="model"  separator=";">
    UPDATE parties SET attending_user_count = #{model.attending_count}
    WHERE  fb_party_id = #{model.eid}  
</foreach>

2] 这是插页

<insert id="insertAccountabilityUsers" parameterType="AccountabilityUsersModel" useGeneratedKeys="false">
    INSERT INTO accountability_users 
        (
            accountability_user_id, accountability_id, to_username,
            record_status, created_by, created_at, updated_by, updated_at
        ) 
    VALUES
    <foreach collection="usersList" item="model" separator=","> 
        (           
            #{model.accountabilityUserId}, #{model.accountabilityId}, #{model.toUsername}, 
            'A', #{model.createdBy}, #{model.createdAt}, #{model.updatedBy}, #{model.updatedAt}     
        )
    </foreach>
</insert>

在dao方法中声明为

void insertAccountabilityUsers(@Param("usersList") List<AccountabilityUsersModel> usersList);

使现代化

这是我的批处理会话代码

public static synchronized SqlSession getSqlBatchSession() {
    ConnectionBuilderAction connection = new ConnectionBuilderAction();
    sf = connection.getConnection();
    SqlSession session = sf.openSession(ExecutorType.BATCH);
    return session;
}

SqlSession session = ConnectionBuilderAction.getSqlSession(); 

实际上我已经给出了这个问题的完整例子

丌官向荣
2023-03-14

接受的答案不是处理批处理操作的推荐方式。它不显示真正的批处理语句,因为在打开会话时应使用批处理执行器模式。请参阅这篇文章,其中一位代码贡献者建议批处理更新(或插入)的正确方法是以批处理模式打开会话,并为单个记录反复调用更新(或插入)。

以下是对我有用的:

public void updateRecords(final List<GisObject> objectsToUpdate) {
    final SqlSession sqlSession = MyBatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
    try {
        final GisObjectMapper mapper = sqlSession.getMapper(GisObjectMapper.class);
        for (final GisObject gisObject : objectsToUpdate) {
            mapper.updateRecord(gisObject);
        }
        sqlSession.commit();
    } finally {
        sqlSession.close();
    }
}

不要在更新/插入中使用foreach,并确保它只更新/插入单个记录。根据公认的答案(无效字符、语句未结束等),我遇到了无法解决的oracle错误。正如链接的帖子所指出的,被接受的答案中显示的更新(或插入)实际上只是一个巨大的sql语句。

 类似资料:
  • 问题内容: 我最近开始学习使用myBatis。现在面对这样的情况,我需要通过WebService不断获取新的对象列表,然后对于该列表,我需要通过以下方式将每个对象插入/更新到oracle DB表中: myBatis。 棘手的部分是,我不能每次都简单地进行批量插入,因为某些对象可能已经存在于数据库中,对于这些记录,我需要更新它们的字段而不是新插入。 我当前的解决方案可能非常愚蠢,使用Java,从We

  • 请让我知道,如何使用带注释的映射器在mybatis中执行批插入/更新。

  • 本文向大家介绍Oracle + Mybatis实现批量插入、更新和删除示例代码,包括了Oracle + Mybatis实现批量插入、更新和删除示例代码的使用技巧和注意事项,需要的朋友参考一下 前言 Mybatis是web工程开发中非常常用的数据持久化的框架,通过该框架,我们非常容易的进行数据库的增删改查。数据库连接进行事务提交的时候,需要耗费的资源比较多,如果需要插入更新的数据比较多,而且每次事务

  • 我正在写一个数据挖掘程序,可以批量插入用户数据。 当前SQL只是一个普通的批量插入: 如果发生冲突,如何进行更新?我试过: 但它抛出

  • 问题内容: 有没有办法像在MySQL服务器上那样批量执行查询? 将无法使用,因为如果该字段已经存在,它将直接忽略该字段并且不插入任何内容。 将无法工作,因为如果该字段已经存在,它将首先对其进行处理,然后再次进行处理,而不是对其进行更新。 可以使用,但不能批量使用。 因此,我想知道是否可以批量发出这样的命令(一次不止一次发送)。 问题答案: 您 可以 使用INSERT … ON DUPLICATE

  • 问题内容: 我不确定是否在批量索引编制中正确使用了该操作。 我的要求是: 网址是: 我想我错过了文档中的某些内容,但仍然找不到如何进行此操作的方法。 我想要 在索引中创建以上文档,或者如果存在则对其进行更新。 问题答案: 如果您通过批量API将索引中的记录添加为 那么如果该ID已经存在于索引中,您将获得一个异常。如果要添加或 替换 文档(取决于文档是否存在),则应按以下方式进行请求 如果已经存在具