Mybatis Oracle数据库批量插入数据及新增一条数据返回其主键ID

近期在项目中用到了这些批量操作,记录一下自己对这些代码的理解。

第一种、批量插入数据表中没有主键(包括Mapper映射文件和映射接口)

1.1  Mapper.xml 映射文件 (此处示例使用的是oracle)
    <mapper namespace="com.mxx.demo.mapper.DmDsVestRlatMapper">
    	<!-- 通用查询映射结果 -->
    	<resultMap id="BaseResultMap" type="com.mxx.demo.entity.DmDsVestRlatEntity">
    		<result column="DM_DS_ID" property="dmDsId" />
    		<result column="VEST_TYPE_CODE" property="vestTypeCode" />
    	</resultMap>
    	<!-- 增加数据集合和归属类型的关系(union all: 是把多个归属类型结果当作临时表并起来插入到数据库中) -->
    	<insert id="addDmDsVestRlatInfo" parameterType="list">
    		insert into DM_DS_VEST_RLAT (DM_DS_ID, VEST_TYPE_CODE)
    		<!--dmDsId和vestTypeCode都是DmDsVestRlatEntity实体中的属性值 -->
    		<foreach collection="list" item="item" index="index" separator="union all">
    			( select #{item.dmDsId}, #{item.vestTypeCode} from dual)
    		</foreach>
    	</insert>
    </mapper>
    
1.2   Mapper接口如下:
public interface DmDsVestRlatMapper {
    // @Param注解的值要和foreach中的collection属性值一致(也就是都要是此处写的list)
    int addDmDsVestRlatInfo(@Param("list") List<DmDsVestRlatEntity> list); 
}

foreach属性值简单解释(只是本人的理解,如有错误之处请指正):

  1. collection属性值要和接口方法中的@Param注解值一致;
  2. item:表示循环体中的具体对象(例:有个List<User`>,那么item就可以看作代表User对象,item.age就类似User.age );具体说明:在 list 和数组中item代表其中的对象,在 map 中是 value,该参数为必选。(它是每一个元素进行迭代时的别名)
  3. index:在 list 和数组中,index 是元素的序号;在 map 中,index 是元素的 key。
  4. separator:表示foreach中sql语句以什么作为分隔符;
  5. open:表示该语句以什么开始;open:表示该语句以什么开始;
  6. close:表示该语句以什么结束

第二种、批量插入数据不需要返回主键

1.1 Mapper.xml映射文件代码

<insert id="addDwDsDetail" parameterType="list">
insert into DW_DS_DETAIL (
    ID,DW_DS_ID, DATA_ELE_ID, DATA_ELE_ORDER_FLAG)
    select SEQ_DW_DS_DETAIL.NEXTVAL, cd.* from(
  <foreach collection="list" item="item" index="index" separator="union all">
		select 
		    #{item.dwDsId}, 
		    #{item.dataEleId}, 
		    #{item.dataEleOrderFlag}
		from dual
  </foreach>
  ) cd
</insert>

1.2 Mapper映射接口方法
int addDwDsDetail(@Param("list") List<DwDsDetailEntity> list);

第三种、 一次新增一条数据,返回新插入的数据主键ID:

 1.1 Mapper.xml映射文件代码(这种情况适合返回新插入的数据主键ID):
    <!--Oracle数据库必须要使用 useGeneratedKeys、 keyProperty、selectKey 这3个属性,
          Mysql数据库使用useGeneratedKeys、 keyProperty即可-->
    <insert id="addDmDsInfo" parameterType="com.mxx.demo.entity.DmDsMgrEntity" 
    useGeneratedKeys="true" keyProperty="id">
    	   <!--  获取序列值,并赋值到对象的id字段,此处是用oracle进行的操作 -->
    	<selectKey keyProperty="id" order="BEFORE"  resultType="Long" keyColumn="id">
    		 SELECT SEQ_DM_DS_MGR.nextval from dual
    	</selectKey>
    	 insert into DM_DS_MGR  
    	 <trim prefix="(" suffix=")" suffixOverrides="," >
    		 <if test="id != null and id != '' ">ID,</if>
    		 <if test="dsEnglishName != null and dsEnglishName != '' ">DS_ENGLISH_NAME,</if>
    		 <if test="dsChineseName != null and dsChineseName != '' ">DS_CHINESE_NAME,</if>
    		 <if test="dsChineseNamePym != null and dsChineseNamePym != '' ">DS_CHINESE_NAME_PYM,</if>
    		 <if test="createDate != null">CREATE_DATE,</if>
    		 <if test="createUserId != null and createUserId != '' ">CREATE_USER_ID</if>
    	 </trim> 
    	 <trim prefix="values (" suffix=")" suffixOverrides="," >
    	     <if test="id != null and id != '' ">#{id},</if>
    		 <if test="dsEnglishName != null and dsEnglishName != '' ">#{dsEnglishName},</if>
    		 <if test="dsChineseName != null and dsChineseName != '' ">#{dsChineseName},</if>
    		 <if test="dsChineseNamePym != null and dsChineseNamePym != '' ">#{dsChineseNamePym},</if>
    		 <if test="createDate != null ">SYSDATE,</if>
    		 <if test="createUserId != null and createUserId != '' ">#{createUserId}</if>
    	 </trim>
    </insert> 
    	
   1.2 Mapper映射接口方法 : 
    public interface DmDsMgrMapper { 
         int addDmDsInfo(DmDsMgrEntity  entity);  
    }
     
   1.3 service层调用mapper层方法后如何获取主键ID值
   // 假设已经将Mapper接口dmDsMgrMapper注入到service层了
   public ResultMessage addDmDsInfo(DmDsMgrEntity entity) {
      // 主键ID在配置文件中指定了为INPUT模式,此处不用关注ID的值
     /**
      *主键类型  AUTO:"数据库ID自增",
      *  INPUT:"用户输入ID",
      *  ID_WORKER:"全局唯一ID (数字类型唯一ID)",
      *  UUID:"全局唯一ID *UUID";
      *  -- mybatis-plus.global-config.db-config.id-type=INPUT
      *  -- mybatis-plus.global-config.db-config.db-type=ORACLE
      */
       int addDmDsNum = dmDsMgrMapper.addDmDsInfo(entity);
       // 当mapper层方法执行成功后我们直接用entity.getId()就可以取到新增数据的主键ID了
       System.out.println("返回的主键 :"+ entity.getId() );
   }

第四种、 批量插入数据后批量返回主键

注:批量插入数据后利用mybatis返回主键这个操作对数据库有两点要求:
(1)数据库主键值为自增类型;
(2)数据库提供的jdbc驱动要支持返回批量插入的主键值;
到目前为止能完美支持以上2点要求的仅有mysql数据库,mysql中支持主键自增,oracle通过序列来维护主键 不符合上述的第一点要求,所以mysql数据库支持使用mybatis批量插入数据后批量返回主键,而oracle等其他数据库需要其他方法才能实现。

一. mysql支持批量插入数据批量返回主键:
 1.1 Mapper接口类: (mysql返回主键示例)
 num addUser(@Param("list") List<User> list);
 
 1.2 Mapper.xml文件
 <!-- sql中不用写id -->
 <insert id="addUser" useGeneratedKeys="true" keyProperty="id"> 
 	insert into 表名 (user_name, user_password, user_email) values
 	<foreach collection="list" item="item" separator=",">
 	  (#{item.userName}, #{item.userPassword},#{item.userEmail})
 	</foreach >
 </insert>
 
 1.3 service层调用此方法后获取新增的主键
 public void addUser() {
     List<User> list = new ArrayList<User>();
     for(int i = 0; i < 2; i++) {
      		User user = new User();
      		user.setUserName("test"+i);
      		user.setUserPassword(i);
      		user.setUserEmail("XXXX");
      		list.add(user);
     }
     int num = userMapper.addUser(list);
     for(User user : list) {
            // 会循环打印出返回的主键
			System.out.println(user.getId());
      }     
 }
二. oracle通过mybatis无法批量返回主键需要通过其他方法返回

方法一:先单独调用序列获取主键,把主键值塞到相应的实体类中,再进行批量insert操作;
方法二:通过for循环在程序中遍历插入,这样每次可以单独获取主键(适合小批量数据);

附 :
mysql批量新增数据sql:
insert into 表名(name, password, email) 
values ('AA', '123', '0000'),('BB', '456', '1111'),...

Oracle批量新增数据sql:
未涉及表主键:
insert into 表名(name, password, email) 
select 'AA', '123', '0000' from dual union all 
select 'BB', '456', '1111' from dual
或
涉及表主键:
insert into 表名(id,name, password)
selecy seq_user.nextval,a.* from 
(select 'AA', '123' from dual union all 
select 'BB', '456' from dual) a 

若有错误和不足请指正~~~

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: MyBatis可以使用批量插入来实现批量新增数据,而在Oracle数据库中,可以通过使用序列来自动生成主键,然后将主键值插入到相关的表中。 在MyBatis中,通常使用`insertBatch`语句来实现批量新增,可以通过定义一个`List`来作为参数,每个元素代表一个要新增的对象,然后使用#{属性名}来引用相应的属性值。在执行批量新增时,也可以设置`batch`元素的`size`属性来指定批处理的大小,以优化性能。 此外,为了在新增数据返回主键值,可以使用`selectKey`语句来获取生成的主键值。在Oracle中,可以通过设置`selectKey`语句的`order`属性为`BEFORE`来让它在新增数据之前获取主键值,然后将主键值设置到相应的对象中。 例如,以下是一个使用MyBatisOracle批量新增返回主键的示例: ``` <insert id="insertBatch" parameterType="java.util.List"> <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long"> SELECT SEQ_ID.NEXTVAL FROM DUAL </selectKey> insert into USER (ID, NAME, AGE) values (#{id}, #{name}, #{age}) </insert> ``` 在上述示例中,`insertBatch`语句插入一个`List`中包含的多个`User`对象,通过`selectKey`语句获取自动生成的主键值并设置到相应的对象中。 总之,通过结合MyBatisOracle的相关特性,可以实现批量新增返回主键的功能,以提高数据插入的性能和效率。 ### 回答2: MyBatis是一种JAVA持久层框架,使用MyBatis可以让程序员将数据库查询语句和JAVA代码相分离,很大程度上减少了编程量和维护成本。Oracle是一种常用的关系型数据库管理系统,是企业应用的首选。 在MyBatis Oracle批量新增数据时,我们需要使用Oracle的SEQUENCE(序列)来生成主键。SEQUENCE是Oracle的一种内部对象,能够生成一个唯一的数字序列,可以用于自动分配主键。我们需要在MyBatis XML配置文件中定义一个带有“selectKey”标签的insert语句,这个标签会让MyBatis在执行insert语句之前先查询SEQUENCE,然后将取得的结果作为主键插入到数据库中。 具体操作流程如下: 1. 创建一个Sequence。 CREATE SEQUENCE seq_test MINVALUE 1 MAXVALUE 999999999999999999999999999 START WITH 1 INCREMENT BY 1 CACHE 20; 2.在MyBatis XML配置文件中定义一个insert语句,并在该语句下面用“selectKey”标签来声明取得主键的方式。其中,“order”属性表示主键生成的顺序,可以选择“before”或“after”;“keyProperty”属性表示主键生成后存储在哪一个对象属性中,一般情况下是实体类的主键属性;“resultType”属性表示主键类型。 <insert id="batchInsert" parameterType="java.util.List"> <foreach collection="list" item="item" separator=";"> insert into table_test (id, name) values(seq_test.nextval, #{item.name}) </foreach> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long"> SELECT seq_test.currval FROM DUAL </selectKey> </insert> 3.在Java代码中调用该insert语句,并将数据存储在List中。 List<TestEntity> testList = new ArrayList<>(); for (int i = 0; i < 10; i++) { TestEntity test = new TestEntity(); test.setName("name_" + i); testList.add(test); } testMapper.batchInsert(testList); 4.执行以上代码后,MyBatis会根据insert语句将数据批量插入数据库中,并通过SEQUENCE生成主键。在insert语句执行完之后,MyBatis会自动查询主键并将其存储在实体类的主键属性中。我们可以通过遍历List来获取新插入数据主键值: for (TestEntity test : testList) { System.out.println(test.getId()); } 总之,MyBatisOracle的配合使用可以实现批量新增返回主键的操作。使用Oracle的SEQUENCE可以保证主键值的唯一性,MyBatis的XML配置文件中使用selectKey标签可以获取新插入数据主键值。 ### 回答3: 在 MyBatis 中,可以通过使用批量插入操作来实现在 Oracle 数据库中批量新增返回主键值。 实现步骤如下: 1. 首先需要在 mapper.xml 文件中定义一个 insertList 节点,用于批量插入数据: ``` <insert id="insertList" parameterType="java.util.List"> <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long"> SELECT SEQ.nextval as id FROM dual </selectKey> insert into table_name (id, col1, col2, col3) values (#{id}, #{col1}, #{col2}, #{col3}) </insert> ``` 其中,keyProperty 属性指定主键的属性名称,order 属性指定主键生成的顺序,resultType 属性指定主键数据类型(这里使用了 Long 类型)。 2. 在 Java 代码中,通过 sqlSession 的 insert 方法来执行批量新增操作: ``` List<Data> dataList = ...; // 构造待插入的数据列表 for (Data data : dataList) { sqlSession.insert("insertList", data); } sqlSession.commit(); // 提交事务 ``` 在执行插入操作时,MyBatis 会自动调用 selectKey 节点中指定的 SQL 语句来生成主键值,并将其赋值给对应的属性。最终,主键值会被映射回 Java 对象中,以便后续使用。 需要注意的是,在 Oracle 数据库中,使用批量插入操作时,需要将 autoCommit 属性设置为 false,以确保所有插入操作都在同一事务中执行。 总结:通过 MyBatis批量插入操作,我们可以很方便地实现在 Oracle 数据库中批量新增返回主键值的功能。在实现过程中,需要注意正确配置 mapper.xml 文件,并将 autoCommit 属性设置为 false,以确保操作在同一事务中执行。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值