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调用存储过程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈SpringMVC对RESTfull的支持

    浅谈SpringMVC对RESTfull的支持

    这篇文章主要介绍了浅谈SpringMVC对RESTfull的支持,分享了相关配置代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 关于Java中反射机制的深入讲解

    关于Java中反射机制的深入讲解

    反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性,下面这篇文章主要给大家介绍了关于Java中反射机制的相关资料,需要的朋友可以参考下
    2018-08-08
  • Java中数组的创建与传参方法(学习小结)

    Java中数组的创建与传参方法(学习小结)

    这篇文章主要介绍了Java中数组的创建与传参方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • 分析Java设计模式之组合模式

    分析Java设计模式之组合模式

    组合模式是一种对象的行为模式。将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。它的本质是统一叶子对象和组合对象。它的目的是让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作
    2021-06-06
  • spring boot实现图片上传到后台的功能(浏览器可直接访问)

    spring boot实现图片上传到后台的功能(浏览器可直接访问)

    这篇文章主要介绍了spring boot实现图片上传到后台的功能(浏览器可直接访问),需要的朋友可以参考下
    2022-04-04
  • Java读写文件创建文件夹多种方法示例详解

    Java读写文件创建文件夹多种方法示例详解

    这篇文章主要介绍了Java读写文件创建文件夹等多种操作的方法,大家参考使用吧
    2013-11-11
  • 一文了解Java动态代理的原理及实现

    一文了解Java动态代理的原理及实现

    动态代理指的是,代理类和目标类的关系在程序运行的时候确定的,客户通过代理类来调用目标对象的方法,是在程序运行时根据需要动态的创建目标类的代理对象。本文将通过案例详细讲解一下Java动态代理的原理及实现,需要的可以参考一下
    2022-07-07
  • Java进阶学习:网络服务器编程

    Java进阶学习:网络服务器编程

    Java进阶学习:网络服务器编程...
    2006-12-12
  • Java使用反射创建对象示例

    Java使用反射创建对象示例

    这篇文章主要介绍了Java使用反射创建对象,结合实例形式分析了java使用反射创建对象的具体实现方法及相关操作技巧,需要的朋友可以参考下
    2019-07-07
  • java实现json字符串格式化处理的工具类

    java实现json字符串格式化处理的工具类

    这篇文章主要为大家详细介绍了如何使用java实现json字符串格式化处理的工具类,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01

最新评论