按照惯例还是以一个简单的实例开始。笔者已经习惯如此,学习一个新的东西首先就是要学会如何使用,那么最快速的方法便是直接照例去改。这也就是我们程序员所说的改代码的能力,俗语中的触类旁通更是此道理。能改,到如何改,再到如何更好(不断的思考、重构)是一个层次或者等级提升的过程。
实例:
本实例完成以下功能:查询某个用户(根据手机号码查)从某个时间开始的通话时长,按分钟计算
存储过程:
/*
*calls表存储了所有用户的通话记录
*/
DELIMITER $$
USE `exampledb` $$
DROP PROCEDURE IF EXISTS `calls_duration` $$
CREATE DEFINER = `root` @`localhost` PROCEDURE `calls_duration` (
IN calltime VARCHAR (20),
IN mobnum VARCHAR (20)
)
BEGIN
SELECT
caller_id AS 'caller',
SUM(duration) / 60 AS 'duration'
FROM
exampledb.calls
WHERE call_start > calltime
AND caller_id LIKE mobnum
GROUP BY caller_id ;
END $$
DELIMITER ;
映射文件:
<sqlMap namespace="calls">
<typeAlias alias="caller" type="com.huan.model.Caller"/>
<parameterMap id="callsMap" class="java.util.HashMap">
<parameter property="calltime" jdbcType="varchar" javaType="java.lang.String" mode="IN" />
<parameter property="mobnum" jdbcType="varchar" javaType="java.lang.String" mode="IN"/>
</parameterMap>
<resultMap id="callres" class="caller">
<result property="callerid" column="caller"/>
<result property="duration" column="duration"/>
</resultMap>
<procedure id="calls_duration" parameterMap="callsMap" resultMap="callres">
{call calls_duration(?,?)}
</procedure>
</sqlMap>
测试代码:
public class SqlMapUtil{
public static SqlMapClient getVoipSwitchSqlMapClient() {
SqlMapClient sqlmapclient = null;
try {
sqlmapclient = SqlMapClientBuilder.buildSqlMapClient(Resources
.getResourceAsReader("com/huan/sqlmap/SqlMapVoipSwitch.xml"));
} catch (IOException e1) {
e1.printStackTrace();
}
return sqlmapclient;
}
}
/
/
SqlMapClient client = SqlMapUtil.getVoipSwitchSqlMapClient();
Map parameterMap = new HashMap();
parameterMap.put("calltime", "2012-09-01 00:00:00");
parameterMap.put("mobnum", "18687752225");
try {
Caller caller = (Caller)client.queryForObject("calls.calls_duration", parameterMap);
System.out.println(caller.getDuration());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
POJO:
public class Caller{
private String caller;
private double duration;
public void setCaller(String caller){
this.caller = caller;
}
public String getCaller(){
return this.caller;
}
public void setDuration(double duration){
this.duration = duration;
}
public double getDuration(){
return this.duration;
}
}
OK,以上就是iBATIS调用存储过程的基本步骤及代码。这里我们发现映射文件里存储过程的出参和入参是两个map。在iBATIS里SQL语句里的出参和入参是可以自由定义的,既可以是JAVA里的基本数据类型也可以是引用类型,也可以是复杂的诸如Map、Set这样的数据类型。而笔者发现对于存储过程的调用iBATIS要求出参和入参必须是Map类型,如上例所示按道理讲返回类型完全可以是Caller对象,读者可以自己去试,这样是读不到所得结果的。由此我们得出了一个结论:ibatis 调用存储过程默认返回的是map类型,即便是一个值也是被放在了map里。那么入参也是同理。这里我们还要注意的一点是,在iBATIS的映射文件里parameterMap和resultMap里的参数名字必须和存储过程的入参名字以及查询(本例只是个负责查询的存储过程)出的名字一一对应,不然很有可能会发生错误。
PS:对代码格式的解释
笔者不知道为什么总是在代码前出现ITEYE编辑器里的HTML代码,因此读者在看的时候很有可能就看到诸如:
<span style="font-size: x-small;">
这样的代码。特此声明与笔者无关,笔者不想浪费大家的时间不想影响大家的视觉效果,但只能这样。如有方法去除或者彻底避免此情况的发生请告知笔者,非常感谢!
如需转载请务必保留原出处,谢谢配合!