“皇上,还记得当年大三时认识的存储过程吗?”
“朕记得,就是。。。”
今天咱们练练存储过程。如果现在需要写一个这样存储过程:查询得到男性或女性的数量, 如果传入的是0就女性否则是男性
其他不多说,在数据库中吧表定义好、数据插入好,等着朕来写存储过程吧。
create table p_user( id int primary key auto_increment, name nvarchar(10), sex nchar(1) ); insert into p_user(name,sex) values('A',"男"); insert into p_user(name,sex) values('B',"女"); insert into p_user(name,sex) values('C',"男"); #创建存储过程(查询得到男性或女性的数量, 如果传入的是0就女性否则是男性) DELIMITER $ CREATE PROCEDURE mybatis.ges_user_count(IN sex_id INT, OUT user_count INT) BEGIN IF sex_id=0 THEN SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='女' INTO user_count; ELSE SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='男' INTO user_count; END IF; END $
这里还是啰嗦几句吧,想必不少同学已经把存储过程的书写方式忘了个精光了。格式如上,参数两个,一个输入参数,一个输出参数,用IN和OUT标记。select语句的尾部的INTO是将返回结果传入某某变量的意思,这里是OUT参数变量user_count。
DELIMITER估计小白们都忘了吧,这个分隔符是用来标记执行末尾的符号的,因为定义存储过程实际上只是一步操作,但是存储过程体内存在的语句包含了分号,如果不声明DELIMITER,mysql会把当中的分号当成执行分隔符来进行断句,那样就嗝屁了。所以,这里把DELIMITER声明为#。
我们再定义一个PUser类:(本文出自:http://my.oschina.net/happyBKs/blog/475853)
package com.happyBKs.mybatis.C1_1.beans; public class PUser { private String id; private String name; private String sex; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public PUser(String id, String name, String sex) { super(); this.id = id; this.name = name; this.sex = sex; } public PUser() { super(); } @Override public String toString() { return "PUser [id=" + id + ", name=" + name + ", sex=" + sex + "]"; } }
关键还是映射文件怎么写。来吧!
puserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.happyBKs.mybatis.C1_1.puserMapper"> <!-- 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 CALL mybatis.get_user_count(1, @user_count); --> <select id="getCount" statementType="CALLABLE" parameterMap="getCountMap"> call mybatis.ges_user_count(?,?) </select> <parameterMap type="java.util.Map" id="getCountMap"> <parameter property="sex_id" mode="IN" jdbcType="INTEGER"/> <parameter property="user_count" mode="OUT" jdbcType="INTEGER"/> </parameterMap> </mapper>
这里注意我们需要为select设置属性为CALLABLE,用来声明接下来的select标签体内是调用存储过程,并且要为参数列表指定一个parameterMap。parameterMap将参数列表描述为java.util.Map类型,里面需要将各个parameter列出,property是传入的HashMap的键名称;mode标记IN、OUT、INOUT等,即输入还是输出;jdbcType描述参数类型。
MyBatis 通过包含的 jdbcType 枚举型,支持下面的 JDBC 类型:
注意:这里的property需要与调用它的方法提供的HashMap对象中的键名一致,而与数据库存储过程中的参数名称不需要一致,只要顺序一致、mode和类型一致就可以了。
把映射文件在config.xml配置文件中注册。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"/> <!-- development: 开发模式 work: 工作模式 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <!-- 在conf.xml文件中注册userMapper.xml文件 --> <mappers> <mapper resource="com/happyBKs/mybatis/C1_1/beans/orderMapper.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/orderMapper2.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/classMapper.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/classMapper2.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/classMapper3.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/classMapper4.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/userMapper.xml"/> <mapper resource="com/happyBKs/mybatis/C1_1/beans/puserMapper.xml"/> </mappers> </configuration>
调用测试代码:
package com.happyBKs.mybatis.C1_1; import java.io.IOException; import java.io.Reader; 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.Test; import com.happyBKs.mybatis.C1_1.beans.ConditionUser; import com.happyBKs.mybatis.C1_1.beans.User; public class TestCondition { @Test public void test2() { Reader reader=null; try { reader = Resources.getResourceAsReader("config.xml"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession sqlSession = sessionFactory.openSession(); String statement = "com.happyBKs.mybatis.C1_1.puserMapper.getCount"; Map<String, Integer> paramMap = new HashMap<String, Integer>(); paramMap.put("sex_id", 0); paramMap.put("user_count", -1); sqlSession.selectOne(statement, paramMap); Integer userCount = paramMap.get("user_count"); System.out.println(userCount); } }
输出结果:
1