一、先创建一个存储过程

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_adder`(IN `a` int,IN `b` int,OUT `sum` int)
BEGIN
    if a is null then set a = 0; 
  end if;
    if b is null then set b = 0;
  end if;
    set sum  = a + b;
END

存储过程proc_adder功能很简单,两个整型输入参数a和b,一个整型输出参数sum,功能就是计算输入参数a和b相加的结果,赋值给输出参数sum;

在SQL中调用存储过程

set @b=5;
call proc_adder(2,@b,@s);
select @s as sum;

结果如下:

二、使用JdbcTemplate调用存储过程

JdbcTemplate在 spring-jdbc-5.0.2.RELEASE.jar 中,我们在导包的时候,除了要导入这个 jar 包外,还需要导入一个 spring-tx-5.0.2.RELEASE.jar(它是和事务相关的)。

引入依赖:

<!-- jdbcTemplate -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

使用时直接注入即可

@Autowired
private JdbcTemplate jdbcTemplate;

 代码:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = PtsServerApplication.class)
@Slf4j
public class TestDemo {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test() {
        final int[] sum = new int[1];
        jdbcTemplate.execute(new ConnectionCallback() {
            @Override
            public Object doInConnection(Connection connection) throws SQLException, DataAccessException {
                //不自动提交,即为手动提交
                connection.setAutoCommit(false);
                //预处理,指定存储过程名和参数,?作为占位符,后面根据占位符赋值或设置输出值的类型
                CallableStatement statement = connection.prepareCall("{ call proc_adder(2,?,?)}");
                // 给存储过程中的输入参数赋值,
                statement.setInt(1, 5);
                // 存储过程中的输出参数处理方式
                statement.registerOutParameter(2, Types.INTEGER);
                statement.execute();
                //获取返回的参数
                sum[0] = statement.getInt(2);
                connection.commit();
                return null;
            }
        });
        log.info("返回的参数:{}", sum[0]);
        System.out.println(sum[0]);
    }
}

 使用jdbcTemplate方式时,必须要设置不自动提交。另外调用时的参数必须对应,即使是输出参数也要指定占位符,设置输出的类型。

三、通过Mybatis调用mysql存储过程

TestMaper.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.ljxx.dao.TestDao">
    <select id="call" statementType="CALLABLE">
        {call
            proc_adder(2,
                #{b,mode=IN,jdbcType=INTEGER},
                #{sum,mode=OUT,jdbcType=INTEGER}
            )
        }
    </select>
</mapper>

指定参数名,出入参类型及参数对应数据库的数据类型。

方式二、使用占位符方法

<?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.ljxx.dao.TestDao">
    <select id="call" statementType="CALLABLE" parameterMap="AddrMap">
        {call proc_adder(2,?,?)}
    </select>

    <!--定义参数-->
    <parameterMap id="AddrMap" type="java.util.Map">
        <parameter property="b" jdbcType="INTEGER" mode="IN" />
        <parameter property="sum" jdbcType="INTEGER" mode="OUT" />
    </parameterMap>
</mapper>

TestDao

public interface TestDao {
    void call(Map<String, Object> map);
}

调用TestDao接口

@RunWith(SpringRunner.class)
@SpringBootTest(classes = PtsServerApplication.class)
@Slf4j
public class TestDemo {
    @Autowired
    private TestDao testDao;
    @Test
    public void test1() {
        Integer b = 5;
        Map<String, Object> map = new HashMap<>();
        map.put("b",b);
        testDao.call(map);
        int sum = 0;
        if (map != null && map.get("sum") != null) {
            sum = (Integer) map.get("sum");
        }
        log.info("返回的参数:{}", sum);
        System.out.println(sum);
    }
}

 参数需要使用map进行定义,其中输入参数需事先定义,输出参数在调用后直接从map中获取即可,无需对方法写返回值。

注意:

(1)上面两种方法在xml中必须指定statementType="CALLABLE",否则会报错。

(2)jdbcType是mysql数据库的类型,不是java的基本类型

 

posted on 2021-08-31 14:33  周文豪  阅读(486)  评论(0编辑  收藏  举报