一、返回select結果集
1、創建存儲過程
DELIMITER // DROP PROCEDURE IF EXISTS proc_queryUser; CREATE PROCEDURE proc_queryUser( IN user_name VARCHAR(50) CHARACTER SET utf8 ) BEGIN SET @exeSql = CONCAT('SELECT id,username,sex,birthday,address ', 'from t_user where username like \'',user_name,'%\' order by id'); -- 打印sql -- SELECT @exeSql; -- 預定義一個語句,並將它賦給stmtsql PREPARE stmtsql FROM @exeSql; EXECUTE stmtsql; -- 釋放一個預定義語句的資源 DEALLOCATE PREPARE stmtsql; END // DELIMITER ;
2、存儲過程調用
SET @user_name='小'; CALL proc_queryUser(@user_name);
3、在UserMapper.java中添加接口方法
/**調用存儲過程查詢用戶**/ public List findUserByProc(String user_name); /**調用存儲過程查詢用戶**/ public List findUserByProc1(Map map);
4、在UserMapper.xml中添加如下配置項:
<!-- 調用存儲過程 --> <!-- 第一種方式,參數使用parameterType --> <select id="findUserByProc" parameterType="java.lang.String" statementType="CALLABLE" resultType="com.mybatis.entity.User"> {call proc_queryUser(#{user_name,jdbcType=VARCHAR,mode=IN})} </select> <parameterMap type="java.util.Map" id="userMap"> <parameter property="user_name" mode="IN" jdbcType="VARCHAR"/> </parameterMap> <!-- 調用存儲過程 --> <!-- 第二種方式,參數使用parameterMap --> <select id="findUserByProc1" parameterMap="userMap" statementType="CALLABLE" resultType="com.mybatis.entity.User"> {call proc_queryUser(?)} </select>
說明:這里使用兩種方式調用存儲過程,兩種方式的區別主要在於參數的使用方式上,第一種方式使用parameterType,第二種方式使用parameterMap。
5、測試代碼:
package com.mybatis.test; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import com.mybatis.entity.User; import com.mybatis.mapper.UserMapper; public class TestMybatisProceduce { private SqlSessionFactory sqlSessionFactory; // 此方法是在執行@Test方法之前執行 @Before public void setUp() throws Exception { String resource = "SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); // 創建SqlSessionFcatory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void TestProceduce(){ SqlSession sqlSession = sqlSessionFactory.openSession(); // 創建Usermapper對象,mybatis自動生成mapper代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); List userList = mapper.findUserByProc("小"); System.out.println(userList); sqlSession.close(); } @Test public void TestProceduce1(){ SqlSession sqlSession = sqlSessionFactory.openSession(); // 創建Usermapper對象,mybatis自動生成mapper代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map map = new HashMap(); map.put("user_name", "小"); List userList = mapper.findUserByProc1(map); System.out.println(userList); sqlSession.close(); } }
6、運行結果:
[User [id=8, username=小A, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=9, username=小B, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=10, username=小C, sex=1, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=11, username=小D, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015]] [User [id=8, username=小A, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=9, username=小B, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=10, username=小C, sex=1, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015], User [id=11, username=小D, sex=2, address=北京, birthday=Sat Jun 27 00:00:00 CST 2015]]
二、帶輸入輸出參數的存儲過程
1、創建存儲過程
DELIMITER // DROP PROCEDURE IF EXISTS proc_queryUserCount; CREATE PROCEDURE proc_queryUserCount( IN user_name VARCHAR(50) CHARACTER SET utf8, OUT count INT ) BEGIN SET @exeSql = CONCAT('SELECT count(*) into @rowsCount from t_user where username like \'',user_name,'%\''); -- 打印sql -- SELECT @exeSql; -- 預定義一個語句,並將它賦給stmtsql PREPARE stmtsql FROM @exeSql; EXECUTE stmtsql; -- 釋放一個預定義語句的資源 DEALLOCATE PREPARE stmtsql; SET count = @rowsCount; END // DELIMITER ;
2、存儲過程調用:
SET @user_name='小'; CALL proc_queryUserCount(@user_name,@count); SELECT @count;
3、在UserMapper.java中添加接口方法
/**調用存儲過程(帶輸入輸出參數的存儲過程)**/ public void findUserCountByProc(Map map);
4、在UserMapper.xml中添加如下配置項:
<parameterMap type="java.util.HashMap" id="userMap1"> <parameter property="user_name" jdbcType="VARCHAR" mode="IN"/> <parameter property="count" jdbcType="INTEGER" mode="OUT"/> </parameterMap> <!-- 調用存儲過程 (帶輸入輸出參數的存儲過程)--> <select id="findUserCountByProc" parameterMap="userMap1" statementType="CALLABLE"> {call proc_queryUserCount(?,?)} </select>
5、測試代碼:
@Test public void TestProceduce2(){ SqlSession sqlSession = sqlSessionFactory.openSession(); // 創建Usermapper對象,mybatis自動生成mapper代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map map = new HashMap(); map.put("user_name", "小"); mapper.findUserCountByProc(map); System.out.println("userCount="+map.get("count")); sqlSession.close(); }
6、運行結果:
userCount=4
三、返回多個結果集
1、創建存儲過程
DELIMITER // DROP PROCEDURE IF EXISTS proc_query; CREATE PROCEDURE proc_query( IN user_id INT, OUT order_count INT ) BEGIN SET @exeSql = CONCAT('SELECT id,username,sex,date_format(birthday,\'%Y-%m-%d\')birthday,address ', 'from t_user where id=\'',user_id,'\''); PREPARE stmtsql FROM @exeSql; EXECUTE stmtsql; DEALLOCATE PREPARE stmtsql; SET @exeSql1 = CONCAT('SELECT id,user_id,number,date_format(createtime,\'%Y-%m-%d %H:%i:%s\')createtime ', 'from orders where user_id=\'',user_id,'\''); PREPARE stmtsql1 FROM @exeSql1; EXECUTE stmtsql1; DEALLOCATE PREPARE stmtsql1; SET @exeSql2 = CONCAT('SELECT count(*) into @rowsCount from orders ', 'where user_id=\'',user_id,'\''); PREPARE stmtsql2 FROM @exeSql2; EXECUTE stmtsql2; DEALLOCATE PREPARE stmtsql2; SET order_count = @rowsCount; END // DELIMITER ;
2、存儲過程調用:
SET @user_id=2; CALL proc_query(@user_id,@order_count); SELECT @order_count;
3、在UserMapper.java中添加接口方法
/**調用存儲過程(返回多個結果集)**/ public List<List<?>> findUserOrdersByProc(Map map);
4、在UserMapper.xml中添加如下配置項:
<resultMap type="java.util.HashMap" id="userInfoMap"> <result column="id" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"/> <result column="username" property="username" javaType="java.lang.String" jdbcType="VARCHAR"/> <result column="birthday" property="birthday" javaType="java.lang.String" jdbcType="DATE"/> <result column="sex" property="sex" javaType="java.lang.String" jdbcType="CHAR"/> <result column="address" property="address" javaType="java.lang.String" jdbcType="VARCHAR"/> </resultMap> <resultMap type="java.util.HashMap" id="ordersMap"> <result column="id" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"/> <result column="user_id" property="user_id" javaType="java.lang.Integer" jdbcType="INTEGER"/> <result column="number" property="number" javaType="java.lang.String" jdbcType="VARCHAR"/> <result column="createtime" property="createtime" javaType="java.lang.String" jdbcType="TIMESTAMP"/> </resultMap> <!-- 調用存儲過程 (返回多個結果集)--> <select id="findUserOrdersByProc" parameterType="java.util.Map" resultMap="userInfoMap,ordersMap" statementType="CALLABLE"> {call proc_query(#{user_id,jdbcType=INTEGER,mode=IN}, #{order_count,jdbcType=INTEGER,mode=OUT})} </select>
5、測試代碼:
@Test public void TestProceduce3(){ SqlSession sqlSession = sqlSessionFactory.openSession(); // 創建Usermapper對象,mybatis自動生成mapper代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map map = new HashMap(); map.put("user_id", "2"); List<List<?>> resultList = mapper.findUserOrdersByProc(map); List<Map> list1 = (List<Map>)resultList.get(0); List<Map> list2 = (List<Map>)resultList.get(1); System.out.println(list1); System.out.println(list2); System.out.println("orderCount="+map.get("order_count")); sqlSession.close(); }
6、運行結果:
[{id=2, birthday=2014-07-10, sex=1, username=張三, address=北京市}] [{createtime=2015-07-17 14:13:23, id=3, number=1000012, user_id=2}] orderCount=1
四、總結:
如果sql中用的是select出結果,不需要配置out參數。多個結果集/結果集可以配置resultMap 來返回LIST,主要是調用selectList方法會自動把結果集加入到list中去的。