mybatis批量操作
一.MyBatis+Oracle用foreach标签实现批量插入数据以及主键自增
1.批量插入操作:
1 <insert id="batchInsert" parameterType="list"> 2 insert into S_DATUM_PAGE(PAGE_ID,ENTRY_ID,DATUM_ID,CONTENT_LENGTH, 3 CREATED_TIME,NAME_TIME,IMAGE_FORMAT,PAGE_ORDER,PATH) 4 VALUES 5 <foreach collection="list" item="item" separator=";"> 6 (#{item.pageId},#{item.entryId},#{item.datumId},#{item.contentLength}, 7 #{item.createdTime}, 8 #{item.nameTime},#{item.imageFormat},#{item.pageOrder},#{item.path}) 9 </foreach> 10 </insert>
2.批量插入自增操作
<insert id="batchInsert" parameterType="list" useGeneratedKeys="false" > insert into S_DATUM_PAGE (PAGE_ID,ENTRY_ID,DATUM_ID,CONTENT_LENGTH,CREATED_TIME,NAME_TIME,IMAGE_FORMAT,PAGE_ORDER,PATH) SELECT PAGE_ID_SEQ.NEXTVAL,a.* FROM ( <foreach collection="list" item="item" separator="union all"> SELECT #{item.entryId},
#{item.datumId},
#{item.contentLength},
#{item.createdTime}, #{item.nameTime},
#{item.imageFormat},
#{item.pageOrder},
#{item.path} FROM dual </foreach> ) a </insert>
3.关于主键自增:
因为Oracle不像MySQL有主键自动增长的功能,Oracle要实现主键自增有其中一种做法是采用序列(Sequence)来实现的,自己创建一个序列,然后在xml文件中调用它。运行通过。在Oracle的版本中,有几点需要注意的:
1>.SQL中没有VALUES;
2>.<foreach>标签中的(select ..... from dual);
3>.<foreach>标签中的separator的属性为"UNION ALL",将查询合并结果集。
4>.最重要的一点就是一定要在insert标签中加入useGeneratedKeys="false",如果不加则会报如下错误:
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束
5>.MyBatis 插入空值时,需要指定JdbcType ,否则会报错。
二、JdbcType介绍
数据库列字段都是有类型的,不同的数据库有不同的类型。为了表示这些数据类型,Java源码是采用枚举来定义的:
- public enum JDBCType implements SQLType {
- TINYINT(Types.TINYINT),
- SMALLINT(Types.SMALLINT),
- INTEGER(Types.INTEGER)
- }
枚举变量也是有类型的,也是有值的,正如整数变量是整数类型,也有值大小一样,上述枚举变量值的定义是通过Types来描述刻画的。
- public class Types {
- public final static int TINYINT = -6;
- public final static int SMALLINT = 5;
- public final static int INTEGER = 4;
- }
MyBatis包含的JdbcType类型,主要有下面这些,大致了解一下即可:
BIT、FLOAT、CHAR 、TIMESTAMP 、 OTHER 、UNDEFINEDTINYINT 、REAL 、VARCHAR 、BINARY 、BLOB NVARCHAR、SMALLINT 、DOUBLE 、LONGVARCHAR 、VARBINARY 、CLOB、NCHAR、INTEGER、 NUMERIC、DATE 、LONGVARBINARY 、BOOLEAN 、NCLOB、BIGINT 、DECIMAL 、TIME 、NULL、CURSOR
上述JdbcType类型和Java类型的对应关系,可以参照下面的列表,不过不同数据库的JdbcType多少有些出入,请注意即可。
- JDBC Type Java Type
- CHAR String
- VARCHAR String
- LONGVARCHAR String
- NUMERIC java.math.BigDecimal
- DECIMAL java.math.BigDecimal
- BIT boolean
- BOOLEAN boolean
- TINYINT byte
- SMALLINT short
- INTEGER INTEGER
- BIGINT long
- REAL float
- FLOAT double
- DOUBLE double
- BINARY byte[]
- VARBINARY byte[]
- LONGVARBINARY byte[]
- DATE java.sql.Date
- TIME java.sql.Time
- TIMESTAMP java.sql.Timestamp
- CLOB Clob
- BLOB Blob
- ARRAY Array
- DISTINCT mapping of underlying type
- STRUCT Struct
- REF Ref
- DATALINK java.net.URL
JdbcType类型的作用
在Mybatis明文建议在映射字段数据时需要将JdbcType属性加上,这样相对来说是比较安全的。
- <insert id="saveRole">
- insert into role values (
- #{roleId},
- #{name},
- #{remarks},
- #{orderNo},
- #{createBy,jdbcType=VARCHAR},
- #{createDept,jdbcType=VARCHAR},
- #{createTime,jdbcType=DATE},
- #{updateBy,jdbcType=VARCHAR},
- #{updateTime,jdbcType=DATE}
- )
- </insert>
这样,保证了前四种是不能为空的前提下,而后面几项为空时也不至于程序报错。如果createBy为空,插入的时候mybatis不知道具体转换成什么jdbcType类型,通常会使用一个默认设置,虽然默认配置一般情况下不会出错,但是遇到个别情况还是会有问题的。Mybatis经常出现的:无效的列类型: 1111 错误,就是因为没有设置JdbcType造成的。
本文引用自:
https://blog.csdn.net/qq_37630354/article/details/82792288