踩坑1
今天使用mybaits尝试插入批量数据的时候,测试类中显示没问题,但是在navicate中显示一直没插进去
@Test
public void insertMoreByListTest() throws IOException {
SqlSession sqlSession = MybatisUtils.openSqlSession();
DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
Emp emp1 = new Emp(null, "shan", 20, "男", 1, null);
Emp emp2 = new Emp(null, "shan111", 20, "男", 1, null);
List<Emp> emps = Arrays.asList(emp1, emp2);
System.out.println(emps);
mapper.insertMoreByList(emps);
}
疑惑了很久,最后发现是忘记提交事务了。。。
注意点
foreach批量插入数据时,collections是传入的参数list,item是list中的元素类型,separator表示分隔符类型
<!--int insertMoreByList(List<Emp> emps)-->
<insert id="insertMoreByList">
insert into emp(id, name, age, sex, dept_id) values
<foreach collection="emps" item="emp" separator=",">
(#{emp.id} , #{emp.name}, #{emp.age}, #{emp.sex}, #{emp.deptId})
</foreach>
</insert>
如果这么写会报错
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.apache.ibatis.binding.BindingException: Parameter 'emps' not found. Available parameters are [arg0, collection, list]
原因是因为传递一个 List 实例或者数组作为参数对象传给 MyBatis时,MyBatis 会自动将它包装在一个 Map 中,用名称作为 key,List 实例将会以 “list” 作为 key,而数组实例将会以 “array” 作为 key
解决办法
- 把xml中的foreach中的collection改成了list,其他的都没改,没有报错,也可以正常新增数据
- 在方法参数前面加上你遍历的集合的名称,比如你在foreach的collection中写的是emps,那么你就在传入的list参数前面加上一个注解@Param(“emps”),
即int insertMoreByList(@Param("emps") List<Emp> emps);
<!--int insertMoreByList(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreByList">
insert into emp(id, name, age, sex, dept_id) values
<foreach collection="emps" item="emp" separator=",">
(#{emp.id} , #{emp.name}, #{emp.age}, #{emp.sex}, #{emp.deptId})
</foreach>
</insert>
踩坑2
在mapper中写sql插入数据时,我使用的这种写法,导致报错
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'emp' in 'class com.shy.mybatis.pojo.Emp'
在网上看到的说法有很多,我排除了这些方法,最后发现是xml注释有问题
- 1.实体类中没得get/set方法。
- 2.实体类名与数据库类名不符
- 3.实体类名与xml中的property名不符
- 4.xml中column名与property名不符
我这么写的时候,会把这些注释里的横线也加上去,也就是SQL给我拼成了三条,找了挺久的错误…
### SQL: -- insert into emp(name, age, sex, dept_id) values ( ?, ?,?,?) insert into emp value (?, ?, ?,?,?) -- insert into emp value (?, ?, ?,?,?)
注意点
在插入数据的时候,可能会想当然的使用#{emp.id}
之类的
<!--int insertEmp(Emp emp);-->
<insert id="insertEmp" parameterType="Emp">
insert into emp value (#{emp.id}, #{emp.name}, #{emp.age},#{emp.sex},#{emp.deptId})
</insert>
There is no getter for property named 'emp' in 'class com.shy.mybatis.pojo.Emp'
这时候会报错,因为mybatis不知道emp是什么,错误地以为emp是Emp中的属性
<!--int insertEmp(Emp emp);-->
<insert id="insertEmp" parameterType="Emp">
insert into emp value (#{emp.id}, #{emp.name}, #{emp.age},#{emp.sex},#{emp.deptId})
</insert>
解决方法:
- 不需要明确指出
#{emp.id}, #{emp.name}
之类的,mybatis自动会取parameterType="Emp"
中的属性。
<!--int insertEmp(Emp emp);-->
<insert id="insertEmp" parameterType="Emp">
insert into emp(name, age, sex, dept_id) values ( #{name}, #{age},#{sex},#{deptId})
</insert>
- 使用@Param进行参数绑定,明确告诉mybatis传进来的参数是什么,这里就明确告诉mybaits传入的参数是emp,此时就可以明确指出
#{emp.id}, #{emp.name}
之类的,注意不是Emp,parameterType中的Emp是表示传入参数的类型
<!--int insertEmp(@Param(value="emp") Emp emp);-->
<insert id="insertEmp" parameterType="Emp">
insert into emp value (#{emp.id}, #{emp.name}, #{emp.age},#{emp.sex},#{emp.deptId})
</insert>