在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数;如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能
针对Sequence主键而言,在执行insertsql前必须指定一个主键值给要插入的记录,如Oracle、DB2,可以采用如下配置方式:
<insert id="AltName.insert"parameterType="com.a.AltName">
<selectKeyresultType="long" keyProperty="id"order="BEFORE">
SELECTSEQ_TEST.NEXTVAL FROM DUAL
</selectKey>
insert intoaltname(primaryName,alternateName,type)values(#{primaryName,jdbcType=VARCHAR},#{alternateName,jdbcType=VARCHAR},#{type,jdbcType=VARCHAR})
</insert>
针对自增主键的表,在插入时不需要主键,而是在插入过程自动获取一个自增的主键,比如MySQL,可以采用如下配置方式:
<insert id="AltName.insert"parameterType="AltName">
<selectKeyresultType="long" keyProperty="id"order="AFTER">
SELECTLAST_INSERT_ID() <!-- 该方法LAST_INSERT_ID()与数据库连接绑定,同属统一会话级别,不会发生上述MSSQL Server的函数问题。-->
</selectKey>
insert into ...
</insert>
<insert id="insert"parameterType="cn.softsea.model.DicCity"useGeneratedKeys="true" keyProperty="id">
insert into ...
</insert>
MS SQL Server配置:
<!-- Microsoft SQL Server IDENTITY Column -->
<insert id="insertProduct-MS-SQL"parameterClass="com.domain.Product">
<![CDATA[insert into PRODUCT (PRD_DESCRIPTION) values(#description#)]]>
<selectKey resultClass="int" keyProperty="id" type="post">
<![CDATA[SELECT @@IDENTITY AS ID ]]>
<!-- 该方法不安全 应当用SCOPE_IDENTITY()但这个函数属于域函数,需要在一个语句块中执行。-->
</selectKey>
</insert>
述MSSQL Server配置随是官网提供的配置,但实际上却恰恰隐患重重!按下述配置,确保获得有效主键。
<!-- Microsoft SQL Server IDENTITY Column 改进-->
<insert id="insertProduct-MS-SQL"parameterClass="com.domain.Product">
<selectKey resultClass="int"keyProperty="id">
<![CDATA[insert into PRODUCT (PRD_DESCRIPTION) values(#description#)
SELECT SCOPE_IDENTITY() AS ID ]]>
</selectKey>
</insert>
<insert id="insert"parameterType="cn.softsea.model.DicCity" >
<selectKeyresultType="java.lang.Integer" keyProperty="id"order="AFTER" >
SELECT @@IDENTITY
</selectKey>
insert into ...
</insert>
一旦配置了<selectKey>,就可以在执行插入操作时获取到新增记录的主键。
编写SQL映射文件mapper.xml
<select id="proHello" statementType="CALLABLE">
<![CDATA[
{call pro_hello (#{p_user_name,mode=IN,jdbcType=VARCHAR},#{result,mode=OUT,jdbcType=VARCHAR})}
]]>
</select>
Map<String, String> param = new HashMap<String, String>();
param.put("p_user_name", "zhangsan");
String returnValue = (String) SqlSession.selectOne("User.proHello", param);
System.out.println("message=" + param.get("p_user_name"));
System.out.println("result=" + param.get("result"));
System.out.println("returnValue=" + returnValue);