在Java中使用MySQL的存储过程

在java中有两种方式调用MySQL的存储过程,下面分别介绍:

1.环境准备

首先创建一个存储过程:

create procedure p_test(in count int,out rs varchar(1000))
begin
    declare curr int default 1;
    declare result_str varchar(1000) default '';
    cnt_loop:loop
        if curr > count then 
            leave cnt_loop;
        end if;
        if curr = 1 then
            set result_str = concat(result_str,curr);
        else 
            set result_str = concat(result_str,',',curr);
        end if;
        set curr = curr + 1;
    end loop cnt_loop;
    set rs = result_str;
end;

上述存储过程用于拼接指定从1开始到指定值的数字,仅为演示说明。

2.使用JdbcTemplate调用

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

@Service
@Slf4j
public class ProcedureService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public String test1() {
        final String[] str = {""};
        Integer count = 20;
        jdbcTemplate.execute(new ConnectionCallback() {
            @Override
            public Object doInConnection(Connection connection) throws SQLException, DataAccessException {
                //不自动提交,即为手动提交
                connection.setAutoCommit(false);
                //预处理,指定存储过程名和参数,?作为占位符,后面根据占位符赋值或设置输出值的类型
                CallableStatement statement = connection.prepareCall("{ call p_test(?,?)}");
                // 给存储过程中的输入参数赋值,
                statement.setInt(1, count);
                // 存储过程中的输出参数处理方式
                statement.registerOutParameter(2, java.sql.Types.VARCHAR);
                statement.execute();
                //获取返回的参数
                str[0] = statement.getString(2);
                connection.commit();
                return null;
            }
        });
        log.info("返回的参数:{}", str[0]);
        return str[0];
    }
}

3.使用mybatis调用

在mybatis中调用,一般在xml中调用,而指定参数也有两种类型,一种是直接写在内部,一种是使用占位符,然后再声明。

3.1 实现类中dao方法

    @Resource
    private ProcedureDao procedureDao;

    public String test2() {
        Integer count = 15;
        Map<String, Object> map = new HashMap<>();
        map.put("count", count);
        procedureDao.pTest(map);
        String str = "";
        if (map != null && map.get("result") != null) {
            str = map.get("result").toString();
        }
        return str;
    }

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

3.2 dao层定义方法

package com.zys.example.dao;

import org.apache.ibatis.annotations.Mapper;

import java.util.Map;

@Mapper
public interface ProcedureDao {
    void pTest(Map<String,Object> map);
}

3.3 xml中调用存储过程

以下两种方式二选一即可。

1)直接写在内部

    <select id="pTest" statementType="CALLABLE">
        {call
            p_test(
                #{count,mode=IN,jdbcType=INTEGER},
                #{result,mode=OUT,jdbcType=VARCHAR}
            )
        }
    </select>

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

2)使用占位符方法

    <select id="pTest" statementType="CALLABLE" parameterMap="pTestMap">
        {call p_test(?,?)}
    </select>

    <!--定义参数-->
    <parameterMap id="pTestMap" type="java.util.Map">
        <parameter property="count" jdbcType="INTEGER" mode="IN" />
        <parameter property="result" jdbcType="VARCHAR" mode="OUT" />
    </parameterMap>

个人推荐使用第二种方式,对参数清晰明了。

注意:

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

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

posted @ 2021-08-23 19:00  钟小嘿  阅读(1800)  评论(0编辑  收藏  举报