首页 > 其他分享 >MyBatis使用foreach批量插入一个含List<实体>成员变量的实体类

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

时间:2023-01-19 11:04:53浏览次数:40  
标签:实体类 name List age IntEntity list OutEntity foreach intName


文章目录

  • ​​一、List<String>​​
  • ​​二、List<IntEntity>​​
  • ​​三、再次修改​​


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

MyBatis使用foreach批量插入一个含List<实体>成员变量的实体类_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三个字段

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

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、测试结果

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

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


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

二、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

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



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)

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


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

错误信息意思: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>


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

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



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

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


标签:实体类,name,List,age,IntEntity,list,OutEntity,foreach,intName
From: https://blog.51cto.com/u_15942107/6019938

相关文章

  • ArrayList类的常用方法
    ArrayList类的常用方法packageheima01;importjava.util.ArrayList;/*ArrayList常用方法:publicbooleanremove(Objecto):删除指定的元素,返回删除是否成功publicE......
  • JDK 1.8 LinkedList 关键代码分析 重要属性和add
       /**   *有序(输入有序),不唯一    *底层实现是双向链表   *易修改,不易查询    */publicclassLinkedList<E>   extendsAbstractSequenti......
  • JDK 1.8 ArrayList源码分析 关键代码
    /***1.ArrayListAbstractList中实现了List接口冗余,作者已经承认*2.RandomAccess可以随机访问,标记接口***/publicclassArrayList<E>extendsAbstractList<E> ......
  • ​直播平台搭建,动态设置ListView的高度的两种方法
    ​直播平台搭建,动态设置ListView的高度的两种方法解决方法一如下:首先考虑到如果要实现界面的滚动,需要使用ScrollView控件,该方法就是使用ScrollView控件实现ListView高度......
  • listener
    listener表示监听器。Javaweb三大组件(servlet、filter、listener)之一。监听器就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时,自动执行......
  • vector与list使用用法代码示例
    今天在分析amr解码时,发现用到了vector和list。考虑到这两种容器类使用的场景很多,想把他们的使用方法分享给读者。所以我单独抽离一部分单独编译,具体代码如下:#include<std......
  • ArrayList和LinkedList的区别
    ArrayList:基于动态数组。连续内存存储,适合下标访问(随机访问)。扩容机制:因为数组长度固定,超出长度存数据时需要新建数组,将老数组数据拷贝到新数组,如果不是尾部插入数据还会涉......
  • Java 8 中 List 转 int[]
    原文地址:List(或ArrayList)转换为int[]数组终于搞懂了importjava.util.ArrayList;importjava.util.List;//list转为数组publicclassMain{publicstaticv......
  • List和Set的区别
    list:按对象进入顺序保存对象,是有序的,对象可重复,允许多个null元素,可以使用迭代器Iterator取出元素进行遍历,也可以使用get(index)进行下标访问set:是无序的,对象不可重复,最多......
  • 手写笔记3:谈谈Iterator和ListIterator、ConcurrentHashMap
    ......