MyBatis使用foreach批量插入一个含List<实体>成员变量的实体类



MyBatis使用foreach批量插入一个实体类数据,其中这个实体类包含一个List的成员变量。
在这里插入图片描述


即一个student类,里面含有一个hobby的成员变量,这个hobby由于可以有很多,所以用一个list来存。这个使用的数据可能是name=张三,hobby={跑步 ,唱歌,游泳},最终存到数据库里面就是三条数据,分别是张三-跑步,张三-唱歌,张三-游泳。



该测试背景是基于自己工作时代码,当时测试没有成功,于是被迫使用常规方式——根据list成员变量的长度去循环插入数据。(最终放弃使用foreach最重要的一个原因是,我报错然后询问有经验的前辈原因,他跟我说foreach不能这样用)

但是根据我自己搭建的Demo来看,其实是可行的。




废话少说,先上一个基础版代码

一、List<String>

成员变量list集合内只有一个变量,此处为一个String类型的变量

1、新建实体类POJO

对应的实体类成员变量

@Repository
public class OutEntity {
    
    
	private String name;

	private String age;

	private List<Integer> intEntities;
}

2、新建数据库表

第一阶段只需要使用name、age、intentity三个字段

请添加图片描述

CREATE TABLE `testmysql`.`Untitled`  (
  `name` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `intentity` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `intname` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
  `intage` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;



3、编写对应的SQL和mapper

@Repository
public interface MobianMapper {
    
    
	public int saveOutEntity(OutEntity outEntity);
}
<insert id="saveOutEntity" parameterType="pers.mobian.testtransactional.pojo.OutEntity">
    
    insert into outentity (name,age,intentity) values
    <foreach collection="intEntities" separator="," item="items">
        (
        #{name},
        #{age},
        #{items}
        )
    </foreach>
</insert>

4、编写配置文件

# mysql基本配置
serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/testmysql?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# 自己mapper文件的位置
mybatis.mapper-locations=classpath*:mapper/**/*Mapper.xml



5、构建数据,开始测试

需要连接数据库测试,配置文件自行

@Test
public void test3() {
    
    

    OutEntity outEntity = new OutEntity();
    
    // 1、构建外层对象数据
    outEntity.setAge("2");
    outEntity.setName("mobian");

    // 2、构建list集合成员变量
    List<Integer> list =new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    outEntity.setIntEntities(list);

    mobianMapper.saveOutEntity(outEntity);
}

6、测试结果

请添加图片描述

数据插入测试成功,这也是我当时百度到的案例。




但是我自己业务场景,是下面这种。

二、List<IntEntity>

1、修改实体类

将放在List集合中Integer类型的参数修改为一个实体类型

@Repository
public class IntEntity {
    
    
	private String intName;

	private String intAge;
}
@Repository
public class OutEntity {
    
    
	private String name;

	private String age;

	private List<IntEntity> intEntities;
}

2、修改数据库表结构

还是之前的表,因为之前在新建表时把对应的字段已经添加好了,intname、intage

请添加图片描述


3、修改对应的SQL

这里的#{intName}、#{intAge}是有问题的,后面会再处理,注意!!!

<insert id="saveOutEntity" parameterType="pers.mobian.testtransactional.pojo.OutEntity">
    insert into outentity (name,age,intname,intage) values
    <foreach collection="intEntities" separator="," item="items">
        (
        #{name},
        #{age},
        #{intName},
        #{intAge}
        )
    </foreach>

</insert>



4、修改测试数据,再次测试

设置的数据格式

OutEntity(name=mobian, age=3,
intEntities=[IntEntity(intName=5, intAge=7),
IntEntity(intName=9, intAge=8),
IntEntity(intName=0, intAge=0)])

@Test
public void test3() {
    
    

    OutEntity outEntity = new OutEntity();
    outEntity.setAge("3");
    outEntity.setName("mobian");
    // 组装list成员变量
    List<IntEntity> list =new ArrayList<IntEntity>();
    IntEntity intEntity = new IntEntity("5","7");
    IntEntity intEntity2 = new IntEntity("9","8");
    IntEntity intEntity3 = new IntEntity("0","0");
    list.add(intEntity);
    list.add(intEntity2);
    list.add(intEntity3);
    outEntity.setIntEntities(list);

    mobianMapper.saveOutEntity(outEntity);
}



很不幸,测试失败

// 报错信息
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'intName' in 'class pers.mobian.testtransactional.pojo.OutEntity'
    
atorg.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77) 
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy66.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy67.saveOutEntity(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

请添加图片描述



在公司代码编写的时候,我就因为这个错误,然后打住了,换一个方式处理了。

错误信息意思:intName参数在OutEntity实体类中没有get方法,可是我想我的intName参数在IntEntity中,OutEntity实体类里面肯定没有呀,然后我再一想,这里的错误应该是.xml文件中在识别这个#{intName}标志位的时候,使用反射的方式去调用OutEntity实体类中的方法getIntName,然后找不到对应的方法,然后报错。

但是我们指定的intName应该指定到IntEntity实体类中,然后我将对应的intName修改为item.intName





三、再次修改

于是我将#{intName}修改为#{items.intName},插入测试成功

<insert id="saveOutEntity" parameterType="pers.mobian.testtransactional.pojo.OutEntity">
    
    insert into outentity (name,age,intname,intage) values
    <foreach collection="intEntities" separator="," item="items">
        (
        #{name},
        #{age},
        #{items.intName},
        #{items.intAge}
        )
    </foreach>

</insert>



最终插入数据库的数据效果:

请添加图片描述


查看日志中对应的SQL格式:

请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_44377709/article/details/119986801
今日推荐