遇到不常用的场景:在程序中调用存储过程,不建议这么调用。 假设数据库中存在存储过程GetSnowID,即获取最新的雪花id号。 Mybatis有两种方式调用:
- XML方式
- 注解方式 示例存储过程如下
CREATE PROCEDURE [dbo].[GetSnowID]
@resultBigint bigint output
AS
BEGIN
SET NOCOUNT ON
declare @aIn_date bigint
declare @irand int
set @irand = cast( floor(rand()*100000) as int)--10万以内随机数
set @aIn_date=DATEDIFF ( SECOND , '1970-01-01 08:00:00.000' , getdate() )-- 秒数
set @aIn_date = @aIn_date*1000 + datepart(ms,getdate())-- 毫秒数
SET @resultBigint = @aIn_date*100000+@irand
return 0
END
go
准备测试pojo
public class Snow {
private Long resultBigint;//返回值
public Long getResultBigint() {
return resultBigint;
}
public void setResultBigint(Long resultBigint) {
this.resultBigint = resultBigint;
}
}
下面我们以注解形式完成本次调用过程:
声明一个mapper方法:
/***
* 添加 调用存储过程的 (get snow id).
* 一定要加CALLABLE,标明是调用存储过程
* @param snow
*/
@Select("{call dbo.GetSnowID(#{resultBigint,mode=OUT,jdbcType=BIGINT})}")
@Options(statementType = StatementType.CALLABLE)
void getSnowID(Snow snow);
如果存储过程需要两个参数,一个入参,一个出参,则声明为Snow对象的两个属性,比如入参为时间戳Long型,则 @Select("{call dbo.GetSnowID(#{timestamp,mode=IN,jdbcType=BIGINT},#{resultBigint,mode=OUT,jdbcType=BIGINT})}")
按java的service实现如下:
public interface SnowService {
Long getSnowID();
}
public class SnowServiceImpl implements SnowService {
@Autowired
private SnowServiceMapper snowServiceMapper;
@Override
public Long getSnowID() {
Snow snow = new Snow();
snowServiceMapper.getSnowID(snow);
return snow.getResultBigint();
}
}
在Controller里直接调用该Service即可。或直接单元测试调用即可看到效果。
写在后面
如果是调用存储过程插入则为@Insert,修改@Update,删除@Delete,后面的{call 数据库名.存储过程名称(#{对象属性名称一,mode=IN/OUT,jdbcType=INT/BIGINT},#{对象属性名称二,mode=IN/OUT,jdbcType=INT/BIGINT}) }
Xml形式的我就记录一下吧~
<insert id="getSnowID" parameterType="xx.yy.Snow" statementType="CALLABLE">
${call call dbo.GetSnowID(#{resultBigint,mode=OUT,jdbcType=BIGINT})}
</insert>