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; ENDsqlMap.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; ENDsqlMap.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的值被交换了。