Mysql存储过程调用

这篇具有很好参考价值的文章主要介绍了Mysql存储过程调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目结构:

Mysql存储过程调用

准备数据

CREATE TABLE `demo_entity` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
  `age` bigint(20) DEFAULT '0',
  `cdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `udate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

1、存储过程的调用
存储过程主要返回三类

1、返回数值的存储过程,其执行完后返回一个值,例如数据库中执行一个有返回值的函数或命令。 2、返回记录集的存储过程:执行结果是一个记录集,例如,从数据库中检索出符合某一个或几个条件的记录。 3、行为存储过程,用来实现数据库的某个功能,而没有返回值,例如在数据库中的更新和删除操作。 1、接收一个返回值 1.1、创建存储过程 1.2、返回out变量

DROP PROCEDURE IF EXISTS pro;
CREATE PROCEDURE pro (
  IN userId INT,
  OUT userCount INT
)
  BEGIN
    DECLARE user_name VARCHAR (64);
    #SELECT d.name FROM demo_entity d WHERE d.id = userId INTO user_name;
    #INSERT INTO demo_entity (name) VALUES (user_name);
    SELECT COUNT(*) FROM demo_entity INTO userCount;
end;

call pro(1,@userCount);
select @userCount ;

1.2、返回集合和out变量

DROP PROCEDURE IF EXISTS pro_one_list;
CREATE PROCEDURE pro_one_list (
  IN p_name varchar(20),
  OUT userCount INT
)
  BEGIN
    select count(*) from demo_entity d where d.name = p_name into userCount ;
    SELECT * FROM demo_entity d  where  d.name = p_name;
  end;


call pro_one_list('小芳',@userCount);
select @userCount ;

Mysql存储过程调用

1.3、返回多列集合和变量

drop procedure IF EXISTS pro_many_list ;
CREATE PROCEDURE pro_many_list (
  IN one_name varchar(20),
  IN two_name varchar(20),
  OUT userCount INT
)
  BEGIN
    select count(*) from demo_entity d where d.name = one_name into userCount ;
    SELECT d.* FROM demo_entity d  where  d.name = one_name;
    SELECT e.* FROM demo_entity e  where  e.name = two_name;
  end;


call pro_many_list('小芳','小小芳',@userCount);
select @userCount ;

Mysql存储过程调用

Mysql存储过程调用

2、mybatis xml 配置

out 中必须制定jdbc类型,因为存储过程会对它进行赋值操作

<?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.example.cache.mapper.DemoEntityMapper">




    <!--out 中必须制定jdbc类型,因为存储过程会对它进行赋值操作-->
    <select id="procedureGetOut" parameterType="java.util.Map" statementType="CALLABLE" >
      call pro (
              #{userId,   mode=IN},
              #{userCount,mode=OUT,jdbcType=INTEGER}
      )
  </select>



    <select id="procedureGetOneList" parameterType="java.util.Map" statementType="CALLABLE" resultType="com.example.cache.entity.DemoEntity" >
      call pro_one_list (
              #{userName, mode=IN},
              #{userCount,mode=OUT,jdbcType=INTEGER}
      )
  </select>




    <resultMap id="twoList" type="com.example.cache.entity.DemoEntity">
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
    </resultMap>

    <resultMap id="oneList" type="com.example.cache.entity.DemoEntity">
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
    </resultMap>

    <!--resultMap中会提示报错,但是实际上启动项目不会报错-->
    <select id="procedureGetManyList" parameterType="java.util.Map" statementType="CALLABLE" resultMap="oneList,twoList">
      call pro_many_list (
              #{oneName, mode=IN},
              #{twoName, mode=IN},
              #{userCount,mode=OUT,jdbcType=INTEGER}
      )
   </select>


</mapper>

3、mapper接口

@Mapper
public interface DemoEntityMapper {

    /**
     * 1、获取 存储过程out参数值
     * @param map
     * @return
     */
    void procedureGetOut(Map map);


    /**
     * 2、获取 存储过程的结果集合-只有一个
     * @param map
     * @return
     */
    List<DemoEntity> procedureGetOneList(Map map) ;



    /**
     * 3、获取 存储过程的 获取多个集合 使用了泛型,有可能集合中是不同的
     * @param
     * @return
     */
    List<List<?>> procedureGetManyList(Map map);

}

4、业务层

@Service
public class ProcedureServiceImpl implements IProcedureService {
    @Autowired
    DemoEntityMapper demoEntityMapper;

    @Override
    public Integer procedureGetOut(Long id) {
        Map<String, Object> param = new HashMap<>();
        param.put("userId", id) ;
        //执行完存储过程会自动更新这个map值
        demoEntityMapper.procedureGetOut(param);
        return Integer.valueOf(param.get("userCount").toString());
    }


    /**
     * 2、获取 存储过程的结果集合-只有一个
     * @param name
     * @return
     */
    @Override
    public List<DemoEntity> procedureGetOneList(String name) {
        Map<String, Object> param = new HashMap<>();
        param.put("userName", name) ;

        //获取结果集
        List<DemoEntity> list  = demoEntityMapper.procedureGetOneList(param);
        System.out.println(Integer.valueOf(param.get("userCount").toString()));

        return list;
    }

    /**
     * 3、获取 存储过程的 获取多个集合 使用了泛型,有可能集合中是不同的
     * @param
     * @return
     */
    @Override
    public List<List<?>> procedureGetManyList(String oneName, String twoName) {
        Map<String, Object> param = new HashMap<>();
        param.put("oneName", oneName) ;
        param.put("twoName", twoName) ;
        List<List<?>> lists =   demoEntityMapper.procedureGetManyList(param) ;
        System.out.println("数组大小"+lists.size());
        System.out.println("某个数量"+Integer.valueOf(param.get("userCount").toString()));
        return lists;
    }
}

5、控制层

@RestController
@RequestMapping("/procedure")
public class ProcedureController {
    @Autowired
    IProcedureService procedureService;

    @GetMapping("/procedureGetOut")
    @ResponseBody
    public String  procedureGetOut(Long id){
        Integer integer = procedureService.procedureGetOut(id);
        return String.valueOf(integer);
    }

    /**
     * @Author
     * @Description //TODO 获取返回结果集
     * @Date
     * @Param
     * @return
     **/
    @GetMapping("procedureGetOneList")
    @ResponseBody
    public List<?> procedureGetOneList(String name){
        return procedureService.procedureGetOneList(name);
    }


    /**
     * @Author
     * @Description //TODO 获取返回结果集(多个)
     * @Date
     * @Param
     * @return
     **/
    @GetMapping("procedureGetManyList")
    @ResponseBody
    public List<?> procedureGetManyList(String oneName,String twoName){
        return procedureService.procedureGetManyList(oneName,twoName);
    }

}

6、application.properties配置文件

server.port=9090
spring.datasource.url=jdbc:mysql://localhost:3306/procedure
spring.datasource.username=root
spring.datasource.password=root
#数据库驱动
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# 打开驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=true
# classpath和classpath*的区别
#classpath:只会到你的class路径中查找找文件。
#classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。
#注意: 用classpath*:需要遍历所有的classpath,所以加载速度是很慢的;因此,在规划的时候,应该尽可能规划好资源文件所在的路径,尽量避免使用classpath*。
#接口的配置文件的位置-映射用
mybatis.mapper-locations=classpath*:com/example/cache/mapper/xml/*Mapper.xml

# mapper包下打印日志
logging.level.com.example.cache.mapper=debug


spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=''


#debug=true

7、pom文件依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

调用回报错:

报错问题:
mapper绑定异常 nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): xxx.xxxx.mapper.UserMapper.getAllUser] with root cause

背景:

mapper接口和**mapper.xml映射文件**在同一个包下。

在看到 **Invalid bound statement (not found)**后,提示未找到mapper映射文件,然后打开编译后的target包或生成的jar包后,找到mapper映射文件存放位置,发现编译后的jar包内并没有此映射文件,进而将问题指向到Maven编译的过程中没有将普通配置文件编译进jar包内。

报错原因:

​ 由于我把mapper映射文件放在mapper接口的同一包里,并没有放在resources目录下,导致通过Maven编译后没有把除Java以外的映射文件、配置文件编译到target和jar包内,在运行时,调用mapper映射文件时,发现在同一个目录下没有找到mapper映射文件而报错。

​ 我们知道Maven是根据pom.xml执行任务,其中build标签描述了如何来编译及打包项目,而具体的编译和打包工作是通过build中配置的 plugin 来完成。而对于resources目录下资源,往往不是代码(.properties或XML配置文件),无需编译,所以在构建过程中往往会将资源文件从源路径直接复制到指定的目标路径。

​ src/main/java和src/test/java这两个目录中的所有*.java文件会分别在comile和test-comiple阶段被编译,编译结果分别放到了target/classes和targe/test-classes目录中,但是这两个目录中的其他文件都会被忽略掉。

解决办法:

需要在你的项目的pom文件中添加一下配置文章来源地址https://www.toymoban.com/news/detail-446721.html

<build>
        <resources>
        <!-- 解决mapper绑定异常 -->
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.yml</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <!-- 解决未找到数据源等配置异常 -->
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.yml</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
    </resources>
</build>

到了这里,关于Mysql存储过程调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于MyBatisPlus框架下出现xml里面定义的方法无法被正确识别以及提示调用mysql存储过程时参数无效的问题

    网上很多解决方法都是查看函数名是否一致、命名空间等,但还有一种可能是你调用接口的模块本身的resource文件夹下就有一个含有xml的mapper文件夹,而这个文件夹里面不含有方法A的sql实现,如下图: 导致程序只在这个mapper里面找A的sql实现,那肯定会提示没有找到。 除了检

    2024年02月09日
    浏览(50)
  • 【MySQL 数据库】9、存储过程

    🌱 存储过程是事先经过编译并存储在数据库中的 SQL 语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,可以提高数据处理效率 🌱 存储过程思想上很简单:就是数据库 SQL 语言层面的代码封装与重用 🍃 【封装,复用

    2024年02月08日
    浏览(47)
  • 数据库(MySQL)的存储过程

    存储过程是事先经过编译并存储在数据库中的一段SQL 语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。 存储过程思想上很简单,就是数据库SQL 语言层面的代码封装与重用。 特点

    2024年02月10日
    浏览(43)
  • MySQL数据库中的存储过程以及存储函数练习

     字段名       数据类型       主键    外键    非空   唯一    自增       id             INT               是      否       是       是           否    name    VARCHAR(50)   否      否       是       否           否    glass   VARCHAR(50)     否   

    2024年02月15日
    浏览(44)
  • MySQL数据库——MySQL修改存储过程(ALTER PROCEDURE)

    在实际开发过程中,业务需求修改的情况时有发生,所以修改 MySQL 中的存储过程是不可避免的。 MySQL 中通过 ALTER PROCEDURE 语句来修改存储过程。下面将详细讲解修改存储过程的方法。 MySQL 中修改存储过程的语法格式如下: ALTER PROCEDURE 存储过程名 [ 特征 ... ] 特征 指定了存储

    2024年02月04日
    浏览(44)
  • mysql在EPICS IOC过程变量数据存储中的应用

    此处使用的IOC中含有3个温度值,2个二进制输出,2个二进制输入,如下所示: 三个温度值的过程变量名: THREETS:T1:Temperarure THREETS:T2:Temperarure THREETS:T3:Temperarure 两个二进制输出: TEST:Bo1 TEST:Bo2 两个二进制输入: TEST:Bi1 TEST:Bi2 在mysql数据库中建立一个名为temperature的数据库,并

    2024年02月13日
    浏览(33)
  • 使用MySQL存储过程提高数据库效率和可维护性

    MySQL 存储过程是一种强大的数据库功能,它允许你在数据库中存储和执行一组SQL语句,类似于编程中的函数。存储过程可以大幅提高数据库的性能、安全性和可维护性。本文将详细介绍MySQL存储过程的使用。 MySQL存储过程是一组预编译的SQL语句,它们以一个名称存储在数据库

    2024年02月08日
    浏览(47)
  • MySQL数据库——存储过程-变量(系统变量、用户定义变量、局部变量)

    目录 系统变量  1.查看系统变量  2.设置系统变量 演示示例 用户定义变量 1.赋值  2.使用 演示示例 局部变量 声明  赋值 演示示例 变量 在MySQL中变量分为三种类型: 系统变量、用户定义变量、局部变量。 系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全

    2024年02月05日
    浏览(52)
  • Mysql数据库实验报告--实验五 存储过程和触发器

    在这个系列会更新一些最近老师要求写的实验报告~ 大家尽量对着我的文章做一个参考,不要盲目的cv,毕竟这个对于我们以后的工作学习还是十分重要的。 从这个实验开始,就不在cmd命令行里面进行mysql数据库的操作,因为代码长度和代码的复杂性,需使用 MySQL Workbench: 双

    2024年02月09日
    浏览(63)
  • MySQL强制使用索引的两种方式及优化索引,使用MySQL存储过程创建测试数据。

    一、MySQL强制使用索引的两种方式 1、使用 FORCE INDEX 语句: 使用 FORCE INDEX(索引名称)走索引: 2、使用 USE INDEX 语句: 使用 USE INDEX(索引名称)走索引: FORCE INDEX 或 USE INDEX 的区别? FORCE INDEX :这个语句指示MySQL强制查询使用特定的索引。它会忽略优化器的选择,无论索引

    2024年02月03日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包