Mybatis调用存储过程的案例

 更新时间:2023年07月19日 09:34:30   作者:绿野仙踪max  
这篇文章主要介绍了Mybatis如何调用存储过程,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

推荐阅读:

关于mybatis调用存储过程获取返回值问题

mybatis调用存储过程的实例代码

MyBatis学习教程(六)-调用存储过程

Mybatis如何调用存储过程

一、前置工作

1.首先,我们需要创建一个学生表,以下是学生表的建表语句:

create table student
(
    id   int         not null
        primary key,
    name varchar(10) not null,
    sex  varchar(10) not null,
    age  int         not null
);

2.接下来,我们创建一个与学生表对应的实体类,用于映射数据库中的记录。以下是一个简单的学生实体类的示例:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {
    int id;
    String name;
    String sex;
    int age;
}

3.最后,我们将定义存储过程来查询符合指定性别的学生信息和总条数。存储过程代码如下:

CREATE PROCEDURE getStudentBySex(IN p_sex VARCHAR(255),OUT p_totalCount INT)
BEGIN
    SELECT COUNT(*) INTO p_totalCount FROM student WHERE sex = p_sex;
    SELECT * FROM student WHERE sex = p_sex;
END;

二、基于xml文件调用存储过程

1.首先配置MyBatis的配置文件,以下是配置参数:

<?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">
<!--mybatis主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事物类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;allowMultiQueries=true&amp;multipleStatements=true"/>
                <property name="username" value="root"/><!--数据库账号-->
                <property name="password" value="013579"/><!--数据库密码-->
            </dataSource>
        </environment>
    </environments>
    <!--映射配置,这样的配置,MyBatis就能够加载StudentDao.xml映射文件,并将其与相应的DAO接口关联起来,使您能够在代码中使用该接口来调用存储过程。-->
    <mappers>
        <mapper resource="dao/StudentDao.xml"/>
    </mappers>
</configuration>

2.DAO 层函数定义:

@Mapper
public interface StudentDao {
    List<Student> getStudentForSex(Map<String,Object> param);
}

3.配置 XML 文件与 DAO 层函数进行映射,实现调用存储过程,以下是配置内容的示例:

<mapper namespace="dao.StudentDao">
    <select id="getStudentForSex" statementType="CALLABLE" resultType="pojo.Student">
        {call getStudentBySex(#{p_sex, mode=IN, jdbcType=VARCHAR},#{p_totalCount, mode=OUT, jdbcType=INTEGER})}
    </select>
</mapper>
  • namespace:需要与dao层接口保持一致,才能成功映射,这里设置为"dao.StudentDao"。
  • id:表示映射语句的唯一标识符,要与dao层对应的函数名称一致,这里设置为"getStudentForSex"。
  • statementType:指定语句的类型,这里设置为"CALLABLE",表示调用存储过程。
  • resultType:指定查询结果的返回类型,要与dao层函数返回值的类型保持一致,这里设置为"pojo.Student",表示返回一个Student对象作为结果。
  • #{p_sex, mode=IN, jdbcType=VARCHAR}:这是输入参数p_sex的配置,其中:
  • 1.p_sex:表示输入参数的名称。
  • 2.mode=IN:表示该参数是一个输入参数。
  • 3.jdbcType=VARCHAR:表示输入参数的JDBC类型为VARCHAR。
  • #{p_totalCount, mode=OUT, jdbcType=INTEGER}:这是输出参数p_totalCount的配置,其中:
  • 1.p_totalCount:表示输出参数的名称。
  • 2.mode=OUT:表示该参数是一个输出参数。
  • 3.jdbcType=INTEGER:表示输出参数的JDBC类型为INTEGER。

3.测试过程如下:

public class test {
    public static void main(String[] args) throws IOException {
        //1、读取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2、创建 SqlSessionFactoryBuilder 的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3、使用构建者模式创建工厂对象 SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //4、使用SqlSessionFactory 生产 SqlSession
        SqlSession session = factory.openSession();
        //5、使用SqlSession 创建 dao接口的代理对象
        StudentDao mapper = session.getMapper(StudentDao.class);
        //6、使用代理对象执行查询所有的方法
        Map<String,Object> param=new HashMap<String, Object>();
        param.put("p_sex","男");
        //7、调用方法
        List<Student> studentList=  mapper.getStudentForSex(param);
        System.out.println("查询的学生结果集: "+studentList);
        //8、输出查询总数
        Object count=param.get("p_totalCount");
        System.out.println("查询的结果总数: "+count);
    }
}

4.测试结果如下:

查询的结果

5.过程分析:  

到这里大家可能有些疑惑,为什么存储过程中有两个参数getStudentBySex(IN p_sex VARCHAR(255),OUT p_totalCount INT),但是 DAO 层函数getStudentForSex(Map<String,Object> param)确只有一个参数,不应该是一一对应吗?其实不然,在MyBatis中,存储过程的参数和DAO层函数的参数之间并不需要一一对应。这是因为MyBatis提供了一种通过参数的名称来匹配的机制,而不仅仅依赖于参数的位置。

  在上述示例中,存储过程 getStudentBySex 定义了两个参数:p_sex 和 p_totalCount。而在DAO层函数 getStudentForSex 中,只有一个参数 param,它是一个 Map<String, Object> 类型的参数。这个参数中的key和value可以与存储过程中的参数名称进行匹配。在实际调用时,可以通过以下方式传递参数:

Map<String,Object> param=new HashMap<String, Object>();
param.put("p_sex","男");
List<Student> studentList=  mapper.getStudentForSex(param);
Object count=param.get("p_totalCount");

  MyBatis会通过参数名称 “p_sex” 将值 “男” 传递给存储过程的 p_sex 参数。对于输出参数 p_totalCount,MyBatis会自动将存储过程的输出参数(OUT参数)的值放置在Map<String, Object>类型的参数对象中。这是因为MyBatis使用参数名称作为键,参数值作为值,将存储过程的输出结果映射到参数对象中。  在示例中,我们使用Map<String, Object>作为DAO层函数的参数对象。当执行带有输出参数的存储过程时,MyBatis会自动将输出参数的值设置到该Map对象中,以键值对的形式存储。在调用studentDao.getStudentForSex(param)时,MyBatis会执行存储过程并将输出参数的值设置到param对象中。这样,就可以通过访问param对象来获取存储过程执行后的输出参数值。

三、基于注解调用存储过程

  • 使用注解调用存储过程比使用 XML 简单一些,因为不需要定义与 DAO 层函数进行映射的 XML 文件,只需要使用两个关键注解即可。以下是实现过程的详细步骤:

1.首先配置 MyBatis 的配置文件。以下是配置参数的示例:

<?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">
<!--mybatis主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事物类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC&amp;allowMultiQueries=true&amp;multipleStatements=true"/>
                <property name="username" value="root"/>
                <property name="password" value="013579"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
    	<!-- StudentDao映射器 -->
    	<mapper class="dao.StudentDao"/>
	</mappers>
</configuration>

请注意,与之前的配置不同,这里的 扫描的是接口,而不是 XML 文件。

2.使用注解方式调用存储过程:

@Mapper
public interface StudentDao {
    @Select("call getStudentBySex(#{p_sex,mode=IN,jdbcType=VARCHAR},#{p_totalCount,mode=OUT,jdbcType=INTEGER})")
    @Options(statementType = StatementType.CALLABLE)
    List<Student> getStudentForSex(Map<String,Object> param);
}
  • @Select: 这是 MyBatis 的注解,用于指定 SQL 查询语句。在这里,我们使用了存储过程的调用语法call,并指定了存储过程名为 getStudentBySex。通过 ${} 语法,我们将参数 p_sex 和 p_totalCount 与方法参数 param 中的对应键值进行绑定。mode=IN 表示参数的传入模式为输入参数,mode=OUT表示参数的传入模式为输出参数。jdbcType=VARCHAR 和 jdbcType=INTEGER 则指定了参数的 JDBC 类型。
  • @Options: 这是 MyBatis 的注解,用于配置选项。在这里,我们使用了 statementType =StatementType.CALLABLE,表示该语句为可调用语句类型。
  • List: 这是方法的返回类型,表示该方法将返回一个 Student 对象的列表。

3.测试过程如下:

public class test {
    public static void main(String[] args) throws IOException {
        //1、读取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2、创建 SqlSessionFactoryBuilder 的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3、使用构建者模式创建工厂对象 SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //4、使用SqlSessionFactory 生产 SqlSession
        SqlSession session = factory.openSession();
        //5、使用SqlSession 创建 dao接口的代理对象
        StudentDao mapper = session.getMapper(StudentDao.class);
        //6、使用代理对象执行查询所有的方法
        Map<String,Object> param=new HashMap<String, Object>();
        param.put("p_sex","男");
        //7、调用方法
        List<Student> studentList=  mapper.getStudentForSex(param);
        System.out.println("查询的学生结果集: "+studentList);
        //8、输出查询总数
        Object count=param.get("p_totalCount");
        System.out.println("查询的结果总数: "+count);
    }
}

4.测试结果如下:

测试结果

四、结语

到此这篇关于Mybatis如何调用存储过程的文章就介绍到这了,更多相关mybatis调用存储过程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java开发之request对象常用方法整理

    Java开发之request对象常用方法整理

    这篇文章主要介绍了 Java开发之request对象常用方法整理的相关资料,需要的朋友可以参考下
    2017-02-02
  • 详解如何用Java去除HTML标签

    详解如何用Java去除HTML标签

    在平时工作中,偶尔会用 Java 做一些解析HTML的工作。有时需要删除所有的HTML标签,只保留纯文字内容。这个问题在做过一些爬虫工作的朋友来说很简单。下面来说说,我们平时使用到的集中解析的方法
    2022-12-12
  • java理论基础Stream元素的匹配与查找

    java理论基础Stream元素的匹配与查找

    这篇文章主要为大家介绍了java理论基础Stream元素的匹配与查找方法的示例说明解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • 自定义注解和springAOP捕获Service层异常,并处理自定义异常操作

    自定义注解和springAOP捕获Service层异常,并处理自定义异常操作

    这篇文章主要介绍了自定义注解和springAOP捕获Service层异常,并处理自定义异常操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • hutool 工具类基本使用教程

    hutool 工具类基本使用教程

    Hutool 是一个 Java 工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让 Java 语言也可以 “甜甜的”,下面通过本文学习下hutool 工具类基本使用教程,感兴趣的朋友跟随小编一起看看吧
    2021-12-12
  • spring初始化源码代码浅析

    spring初始化源码代码浅析

    Spring框架被广泛应用于我们的日常工作中,但是很长时间以来我们都是只会使用,不懂它的作用原理,下面这篇文章主要给大家介绍了关于spring初始化源码的相关资料,需要的朋友可以参考下
    2023-04-04
  • Java设计模式之初识行为型模式

    Java设计模式之初识行为型模式

    今天带大家学习Java设计模式的相关知识点,文中对Java行为型模式做了非常详细的介绍及代码示例,对正在学习java的小伙伴们很有帮助,需要的朋友可以参考下
    2021-06-06
  • SpringBoot中如何统一接口返回与全局异常处理详解

    SpringBoot中如何统一接口返回与全局异常处理详解

    全局异常处理是个比较重要的功能,一般在项目里都会用到,这篇文章主要给大家介绍了关于SpringBoot中如何统一接口返回与全局异常处理的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • Java实现简单的五子棋游戏示例代码

    Java实现简单的五子棋游戏示例代码

    这篇文章主要为大家介绍了如何利用Java语言实现简单的五子棋游戏,文中的示例代码讲解详细,对我们学习Java游戏开发有一定帮助,需要的可以参考一下
    2022-05-05
  • 模拟打印机排队打印效果

    模拟打印机排队打印效果

    本节主要介绍了模拟打印机排队打印效果的具体实现,感兴趣的朋友可以参考下
    2014-07-07

最新评论