热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mybatics中调用mysql存储过程_mysql

说起mybatics框架,身边的java开发工程师们基本上都是耳熟能详。mybatics是apache的一个开源项目,前身为ibatics,2010年此项目由apache软件基金会

mybatics 中调用mysql存储过程。

说起mybatics 框架,身边的java开发工程师们基本上都是耳熟能详。 mybatics是apache的一个开源项目,前身为ibatics,2010年此项目由apache软件基金会迁移到了google code,mybatics的确是一款十分优秀的开源持久层框架,sql代码隔离封装、自动POJO映射、jdbc 动态sql———— mybatics的好处可以说出一箩筐,然而mybatics还有一个十分优秀的特性却往往被人忽略 —-那就是mybatics还支持存储过程的调用。

      不熟悉存储过程的人大都觉得存储过程复杂难懂,认为既然有了dao,那么所有的对数据库操作的逻辑(CRUD)都放到dao层就可以了,存储过程是没有必要的。无论如何,在dao中写java代码总比在数据库中写存储过程要舒服容易的多,又何必多花费时间学习一门新的存储过程语言呢?

     的确,对于以下中小型项目而言,基本的增删改查sql操作就足以应付了(再稍微复杂点也就高级查询,也就把dao层改改弄得稍复杂点就行了)。可是做过稍大型点的项目的人(尤其是互联网方面)都知道,大项目尤其是分布式系统的互联网项目对于数据库安全、性能、稳定性都有很高的要求。 当web服务器和数据库服务器分布在不同的机器上,dao层调数据库服务器是需要很大的网络开销,sql语句必须从web服务器发送到数据库服务器再执行。可是存储过程就不同,存储过程的所有sql逻辑到存放在数据库服务器本地且执行效率非常高。而且由于dao层代码是放到本地,存储过程代码是在远程服务器中,故安全性上也比不上存储过程。至于稳定性就更不用谈了。

    幸运的是mybatics是完美支持存储过程调用的,这一点让人感到十分欣慰,也无疑更是增加了我对它的喜爱。

     对于mysql而言,mysql 5.0以后的版本是支持存储过程的 。

    下面我介绍下mybatics中如何调用mysql 存储过程,至于调用oracle 的存储过程也是大同小异的,值得注意的是当程序需要返回List集合数据出来时,Oracle中需要返回游标,而mysql中直接select出去即可 。

  1、 mybatics中调用mysql 存储过程返回LIST 列表数据。

         根据name (模糊)查询用户信息列表,返回用户列表

         UserMapper.xml 中 配置  存储过程调用, 注意  statementType="CALLABLE"  ,select元素配置的ressultType 直接就是User类型。

 

      service 层java代码,调用mapper接口 入参传一个map,返回值是List 类型

    

 public Map getUserListNameLike(String name) {        try {           Map  params=AjaxUtil.getMap();           params.put("name", name);           List userList =  userMapper.queryUserListByLikeName_SP(params);           if(userList!=null){            Map map= AjaxUtil.messageMap(1, "查询成功");            map.put("userList", userList);           return map;           }   } catch (Exception e) {    logger.error(e);    throw new RuntimeException(e);   }      return AjaxUtil.messageMap(-1, "查询失败");  }

          mapper 接口 代码,就一个接口声明(通过mybatics动态代理方式产生其实现类)

 public List queryUserListByLikeName_SP( Map params);

     最后看下,存储过程的代码。(也很简单就一个select 模糊查询)

     

DELIMITER $$  USE `easyuidemo`$$  DROP PROCEDURE IF EXISTS `queryUserList_nameSP`$$  CREATE DEFINER=`root`@`localhost` PROCEDURE `queryUserList_nameSP`(IN in_name VARCHAR(50)) BEGIN     SELECT  * FROM t_user t WHERE t.name  LIKE   CONCAT('%',in_name,'%') ;     END$$  DELIMITER ;

      2、   mybatics中调用mysql 存储过程添加用户。

页面表单ajax上传的用户信息,通过存储过程完成用户添加。要求添加成功时,存储过程中要返回rc(reponseCode结果码)、msg(结果消息)、userId(新添加的用户id)

        UserMapper.xml 中的配置。

       值得注意的是,这里的存储过程配置既可以配置为select节点元素,也可以配置为其它insert、update、delete元素,且无须配置resultType 或resultMap,如果是select元素,请一定要设置userCache=“false”  。入参我这里设置为了map。(这里的map其实就是java.util.Map, mybatics中内置了许多java中类型到jdbc类型的别名映射,比如java中int对应为jdbc中integer,而map就是java.util.Map的在mybatics中的别名 ),大家可能会注意我这入参并没有用User  这个bean对象,用bean来传字段属性岂不是更合乎情理吗? 这个稍候再跟大家解释下。。。

    service 层java代码。

    大家一定在奇怪这句代码  userMapper.addUser_SP(params); 这前面并没有用变量接收方法的返回值,其实这个方法是没有返回值的,即使你定义了要返回某个值(如Map),你会发现无论你得到的永远是null。所以这里根本就不需要接收返回值。那么调用存储过程返回的out参数到要如何接收呢?细心的你可能已经发现了,没错,就是在入参param中!!调用存储过程成功后,你会发现,存储返回的rc、 msg和userId 三个out参数都被放到了你传入的参数params中————也就是说params会在调用存储成功后多出三个字段值rc、msg、userId。

 public Map addUser_SP(User user) {   try {    Map  params=AjaxUtil.getMap();    params.put("name", user.getName());    params.put("address", user.getAddress());    params.put("age", user.getAge());    params.put("email", user.getEmail());    params.put("phone", user.getPhone());      userMapper.addUser_SP(params);      Map map=new HashMap();      map.put("rc", params.get("rc"));      map.put("msg", params.get("msg"));      map.put("userId", params.get("userId"));      return map;   } catch (Exception e) {    logger.error(e);    throw new RuntimeException(e);      }  }

   

再看下mapper接口方法的定义(没什么好说的就一个接口方法定义)

public void addUser_SP(Map params);

最后再看下存储过程代码:

DELIMITER $$  USE `easyuidemo`$$  DROP PROCEDURE IF EXISTS `addUser_SP`$$  CREATE DEFINER=`root`@`localhost` PROCEDURE `addUser_SP`(   IN in_name VARCHAR (50),   IN in_age INTEGER,   IN in_email VARCHAR (50),   IN in_address VARCHAR (200),   IN in_phone VARCHAR (20),   OUT rc INTEGER,   OUT msg VARCHAR (50),   OUT userId VARCHAR (50) ) BEGIN   DECLARE v_userId VARCHAR (50) DEFAULT ROUND(RAND() * 9000000+10000000) ;   DECLARE v_ucount INTEGER DEFAULT 0 ;   SELECT      COUNT(*) INTO v_ucount    FROM     t_user    WHERE t_user.`id` = v_userId ;   IF v_ucount > 0    THEN SET rc = - 1 ;   SET msg = '生成userId重复,插入失败' ;   SET userId='-00000000';   ELSE    INSERT INTO t_user (id, `name`, age, email, address, phone)    VALUES     (       v_userId,       in_name,       in_age,       in_email,       in_address,       in_phone     ) ;   SET userId = v_userId ;   SET rc=1;   SET msg='添加成功';  #commit ;   END IF ; END$$  DELIMITER ;

存储过程本身也没什么好说的,唯一值得大家关注的是:mysql存储过程中最后有commit和没有commit 是有所不同的。

如果存储过程中没有执行commit,那么spring容器一旦发生了事务回滚,存储过程执行的操作也会回滚。如果存储过程执行了commit,那么数据库自身的事务此时已提交,这时即使在spring容器中托管了事务,并且由于其他原因导致service代码中产生异常而自动回滚,但此存储过程是不会回滚,因为数据自身的事务已在存储过程执行完毕前提交了,  也就是说此时spring回滚对存储过程的操作是无效的了。

欢迎大家阅读《mybatics 中调用mysql存储过程_mysql》,跪求各位点评,by



推荐阅读
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 标题: ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 2018深入java目标计划及学习内容
    本文介绍了作者在2018年的深入java目标计划,包括学习计划和工作中要用到的内容。作者计划学习的内容包括kafka、zookeeper、hbase、hdoop、spark、elasticsearch、solr、spring cloud、mysql、mybatis等。其中,作者对jvm的学习有一定了解,并计划通读《jvm》一书。此外,作者还提到了《HotSpot实战》和《高性能MySQL》等书籍。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
author-avatar
用户uuexwjx90j
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有