Mybatis之基于XML的调用存储过程与手动回滚事务

时间:2021-11-15 11:20:44

一、调用存储过程

一、返回单个值

1、存储过程准备

这里先创建一个存储过程,传入参数为age,传出参数为count。然后先测试一下是否正确。

CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_get_usercountbyage`(in age int,out user_count int)
BEGIN
select count(1) into user_count from user a where a.age=age;
END
DELIMITER ;
SET @user_count = 0;
CALL mybatis.pro_get_usercountbyage(27, @user_count);
SELECT @user_count;

2、XML配置

这里配置传入参数的映射parameterMap,statementType,在parameterMap中设置参数的方向。

    <select id="getUserCount" parameterMap="getUserCountMap" statementType="CALLABLE">
CALL pro_get_usercountbyage(?,?)
</select>
<parameterMap type="java.util.Map" id="getUserCountMap">
<parameter property="age" mode="IN" jdbcType="INTEGER"/>
<parameter property="usercount" mode="OUT" jdbcType="INTEGER"/>
</parameterMap>

3、测试

这里传入参数age=27,然后获取返回的结果值。

        String statement="Cuiyw.MyBatis.DBMapping.UserMapper.getUserCount";
Map<String,Integer > map=new HashMap<String,Integer>();
map.put("age", 27);
session.selectOne(statement, map);
int result = map.get("usercount");
System.out.println(result);

二、返回列表

1.返回列表的和返回多个值的基本没太大区别,只是有一个地方需要注意,就是在存储过程select的列名要和resultMap的一致,我就踩到坑了在这个地方。存储过程还是在上面存储过程上改的。返回table。

DELIMITER ;

CALL mybatis.pro_get_usercountbyage(27);
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_get_usercountbyage`(in age int)
BEGIN
select * from user a where a.age=age;
END$$
DELIMITER ;

2.xml配置

这个只是增加了resultMap

    <select id="getUserCount" parameterMap="getUserCountMap" statementType="CALLABLE" resultMap="userResult">
CALL pro_get_usercountbyage(?)
</select>
<parameterMap type="java.util.Map" id="getUserCountMap">
<parameter property="age" mode="IN" jdbcType="INTEGER"/>
</parameterMap>

3.测试

        String statement="Cuiyw.MyBatis.DBMapping.UserMapper.getUserCount";
Map<String,Integer > map=new HashMap<String,Integer>();
map.put("age", 27);
List<User>users= session.selectList(statement, map);
for(int i=0;i<users.size();i++)
{
System.out.println(users.get(i).toString());
}

Mybatis之基于XML的调用存储过程与手动回滚事务

二、手动回滚事务

前面的demo中都是openSession()传的都是true,表示自动开启事务,这里演示下不是自动的情况。

        String resource = "Config.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(false);
// System.out.println("新增");
String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
try{
User user1=new User();
user1.setName("Cuiyw");
user1.setAge(27);
user1.setStatus(UserState.AVAILABLE);
int result=session.insert(statement, user1);
User user2=new User();
user2.setName("Cuiyw");
user2.setAge(1/0);
user2.setStatus(UserState.AVAILABLE);
result=session.insert(statement, user2);
session.commit();
System.out.println("OK");
}
catch(Exception e){
System.out.println("出错------------");
e.printStackTrace();
session.rollback();
}
finally
{
session.close();
}

上面实现User的新增,增加了两个user,第一个正常的,第二个会报错,当openSession()参数为false时执行上面的代码,会自动回滚,一条数据都没保存,如果是true时,会增加了第一条。