iBatis sqlMap文件中非查询语句的元素:
1.<insert>
属性:id,parameterMap,parameterClass
插入数据,对应SqlMapClient的insert方法。
2.<update>
属性:id,parameterMap,parameterClass
更新数据,对应SqlMapClient的update方法。
3.<delete>
属性:id,parameterMap,parameterClass
删除,对应SqlMapClient的delete方法。
4.<procedure>
属性:id,parameterMap,parameterClass,resultClass,resultMap,xmlResultName
调用存储过程,可以用SqlMapClient任意方法执行。
一.插入数据:
1.通过内联参数映射:
xml:
<insert id="insertStu" parameterClass="StudentBean">
insert into student (
Sno,
Sname,
Ssex,
Sage,
Sdept
)
values (
#sno:CHAR#,
#sname:VARCHAR#,
#ssex:CHAR#,
#sage:NUMBER#,
#sdept:CHAR#
)
</insert>
Java:
StudentBean stuBean = new StudentBean();
stuBean.setSage("99");
stuBean.setSdept("CS");
stuBean.setSname("测试");
stuBean.setSsex("男");
stuBean.setSno("2001");
sqlMapClient.insert("insertStu", stuBean);
在某列被设置为允许为空时,#里面字段名后面加冒号和类型才是必须的,其他时候可以忽略,原因在下面提到。
2.通过外部参数映射:parameterMap
xml:
<sqlMap>
<typeAlias alias="StudentBean" type="com.bean.StudentBean"/>
<parameterMap id="StudentMap" class="StudentBean">
<parameter property="sno" jdbcType="CHAR" />
<parameter property="sname" jdbcType="VARCHAR" />
<parameter property="ssex" jdbcType="CHAR" />
<parameter property="sage" jdbcType="NUMBER" />
<parameter property="sdept" jdbcType="CHAR" />
</parameterMap>
<insert id="insertStu" parameterMap="StudentMap">
insert into student (
Sno,
Sname,
Ssex,
Sage,
Sdept
)
values (
?,
?,
?,
?,
?
)
</insert>
</sqlMap>
Java代码不变。注意xml中parameterMap的property顺序要和insert中的一致。通常只有当某列被设置为允许为空时,jdbcType属性才是必须的。原因是:JDBC使用如下方法把空值发送到数据库:setNull(int, int),如果没有明确高度iBatis使用何种数据类型,iBatis将默认使用java.sql.Types.OTHER作为第二个参数传入,一些数据库驱动不允许这样,会导致错误。
内联参数只是创建参数映射的一个简化操作,iBatis会在sql语句第一次执行时自动创建参数映射。
<update>,<delete>使用方法和insert类似。
二.数据的批量更新
调用SqlMapClient的startBatch()方法。
Java代码:
StudentBean stuBean = new StudentBean();
sqlMapClient.startBatch();
for (int i = 9000; i < 9005; i++) {
stuBean.setSage("99");
stuBean.setSdept("CS");
stuBean.setSname("测试");
stuBean.setSsex("男");
stuBean.setSno(""+i);
sqlMapClient.insert("insertStu", stuBean);
}
sqlMapClient.executeBatch();
要注意的是,在调用executeBatch后,以上的所有插入操作才会成功,不调用这句话,sql并没有被真正执行。多个更新操作可以放在batch块中以提高性能。
三.执行存储过程
1.IN
定义存储过程时,IN 表示传递给存储过程的参数。
下面MYSQL存储过程接受2个参数,返回较大的一个。
CREATE PROCEDURE cyh.max_num(IN a INT, IN b INT)
BEGIN
DECLARE c int;
IF a > b THEN SET c=a;
ELSE SET c=b;
END IF;
SELECT c;
END
sqlMap.xml:
<parameterMap id="proc_map" class="hashmap">
<parameter property="a" />
<parameter property="b" />
</parameterMap>
<procedure id="proc" parameterMap="proc_map" resultClass="int">
{call max_num(?,?)}
</procedure>
Java:
Map map = new HashMap();
map.put("a", 10);
map.put("b", 120);
Integer max = (Integer) sqlMapClient.queryForObject("proc", map);
System.out.println(max);
输出:
120
2.OUT
OUT表示从存储过程传出的参数
改动一下上面的存储过程:
这次存储过程不返回较大值,而是把比较后的大数放在OUT参数中,
CREATE PROCEDURE cyh.max_num(IN a INT, IN b INT, OUT c INT)
BEGIN
IF a > b THEN SET c=a;
ELSE SET c=b;
END IF;
END
sqlMap.xml:
<parameterMap id="proc_map" class="hashmap">
<parameter property="a" mode="IN"/>
<parameter property="b" mode="IN"/>
<parameter property="c" mode="OUT"/>
</parameterMap>
<procedure id="proc" parameterMap="proc_map">
{call max_num(?,?,?)}
</procedure>
Java:
Map map = new HashMap();
map.put("a", 10);
map.put("b", 120);
sqlMapClient.queryForObject("proc", map);
System.out.println(map.get("c"));
3.INOUT
INOUT是传递给存储过程,并且可以被其修改的参数,有点像C语言的函数传址调用。
MYSQL存储过程:交换2个参数的值
CREATE PROCEDURE cyh.swap(INOUT a INT, INOUT b INT)
BEGIN
DECLARE tmp INT;
SET tmp = a;
SET a = b;
SET b = tmp;
END
sqlMap.xml:
<parameterMap id="proc_map" class="hashmap">
<parameter property="a" mode="INOUT"/>
<parameter property="b" mode="INOUT"/>
</parameterMap>
<procedure id="proc" parameterMap="proc_map">
{call swap(?,?)}
</procedure>
Java:
Map map = new HashMap();
map.put("a", 10);
map.put("b", 120);
sqlMapClient.queryForObject("proc", map);
System.out.println(map.get("a"));
System.out.println(map.get("b"));
输出:
120
10
可以看到,a和b的值被交换了。