执行insert的基础是先插入数据,而插入数据依赖于insert语句。先来看看insert语句的设置:
- id:它和Mapper的命名空间组合在一起是唯一的,供MyBatis调用
- parameterType:可以给出类的全命名,也可以给出别名,但是别名必须是MyBatis内部定义或者自定义的。
- flushCache:是否刷新缓存,可以配置true/false,为true时,插入时会刷新一级缓存和二级缓存,否则不刷新。
- timeout:超时时间,单位为秒。
- useGeneratedKeys:是否启用JDBC的getGeneratedKeys方法来取出数据库内部生成的主键。
- keyProperty:唯一标识的属性,MyBatis会通过getGeneratedKeys的返回值,或者通过insert语句的selectkey子元素设置它的键值。
- keyColumn:通过生成的键值设置表中的列名。
MyBatis在执行完一条insert语句后,会返回一个整数表示其影响的纪录行。
写一条SQL插入语句,这是一条最简单的插入语句,代码如下:
<insert id="insertRole" parameterType="role">
insert into role(role_name,note) values (#{roleName},#{note})
</insert>
分析一下这段代码:
- id标识出这条SQL,结合命名空间让MaBatis能够找到它。
- parameterType代表传入参数类型
没有配置的属性将采用默认值,这样就完成了一个角色的插入。
主键回填
上述代码展示了最简单的插入语句,但是它并没有插入id列,因为MySQL中的表格采用了自增主键,MySQL数据库会为该记录生成对应的主键。有时候还可能需要继续使用这个主键,用以关联其他事务,因此有时候把它取到是十分有必要的。
JDBC中的Statement对象在执行插入的SQL后,可以通过getGeneratedKeys方法获取数据生成的主键,这样便能达到获取之间的功能。在insert语句中有一个开关属性useGeneratedKeys,用来控制是否打开这个功能,它的默认值是false。当打开了这个开关后,还要配置其属性keyProperty或者keyColumn,告诉系统把生成的主键放入哪个属性中,如果存在多个主键,就要用(,)隔开。
于是我们对代码进行了修改,代码如下:
<insert id="insertRole" parameterType="role"
useGeneratedKeys="true" keyProperty="id">
insert into role(role_name,note) values (#{roleName},#{note})
</insert>
自定义主键
有时候逐渐可能依赖于某些规则,比如取消角色表(role)的id的自增规则,而将其规则修改为:
- 当角色表记录为空时,id设置为1.
- 当角色表记录不为空时,id设置为当前id+2。
MyBatis对这样的场景也提供了支持,他主要依赖于selectKry元素进行支持,它允许自定义键值的生成规则。代码如下:
<insert id="insertRole" parameterType="role">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
select if(max(id)==null,1,max(id)+2) from role
</selectKey>
insert into role(role_name,note) values (#{roleName},#{note})
</insert>