Java Spring动态生成Mysql存储过程详解
一、 背景
由于公司业务需要动态配置一些存储过程来生成数据,之前尝试过使用jpa来完成,或多或少都存在一些问题,最后使用了spring的Jdbctemplate。
二、 环境
1.此随笔内容基于spring boot项目
2.数据库为mysql 5.7.9版本
3.jdk 版本为1.8
三、 说明
说明:为方便表示,下列存储过程在代码中的表示我称之为接口配置
四、 内容
1、定义接口和接口参数bean;
1)接口配置bean:
@Entity @Table(name="qt_interface") public class QtInterface { @Id private String id; private String name; private String content; private String info; private String status; //此处省略get、set… }
2)接口配置参数bean:
@Entity @Table(name="qt_interface_parameter") public class QtInterfaceParameter { @Id private String id; @Column(name="inter_id") private String interId; private String name; //参数名称 private String explain_info; //参数描述 private String type;// 输入输出类型 private String paraType; // 参数类型 private Integer paraLen; //此处省略get、set… }
2、编写页面输入接口配置的信息;
1)Html部分代码:
<div class="form-group"> <label for="name" class="col-sm-2 control-label">接口名称<a style="color:red;">*</a>:</label> <div class="col-sm-4"> <input type="text" id="name" name="name" class="form-control"/> </div> <label for="status" class="col-sm-2 control-label">接口状态<a style="color:red;">*</a>:</label> <div class="col-sm-4" > <select id="status" disabled="disabled" class="form-control"> <option value="0">保存</option> <option value="1">已创建</option> </select> </div> </div> <div class="form-group"> <label for="content" class="col-sm-2 control-label">接口内容<a style="color:red;">*</a>:</label> <div class="col-sm-10"> <textarea id="content" name="content" rows="5" class="form-control"></textarea> </div> </div> <div class="form-group"> <label for="explain_info" class="col-sm-2 control-label">接口说明:</label> <div class="col-sm-10"> <textarea id="explain_info" name="explain_info" rows="3" class="form-control"></textarea> </div> </div> <div class="form-group"> <label for="qtInterList" class="col-sm-2 control-label">接口参数:</label> <div class="col-sm-10"> <div class="ibox-content" style="width:100%;"> <table id="qtInterList" class="easyui-datagrid"> </table> </div> </div> </div>
2)Js部分代码太长,就只贴一个提交方法吧
function createProduce(inter_id) { var postData = { id: $("#inter_id").val(), item_id: $("#item_id").val(), name: $("#name").val(), content: $("#content").val(), explain_info: $("#explain_info").val(), jsonData: JSON.stringify(jsonData)// 参数明细信息,字段就是接口配置参数bean 中的字段信息 }; $.ajax({ url: Url + 'test/createPro', type: 'get', //GET async: false, //或false,是否异步 data: JSON.stringify(postData), timeout: 5000, //超时时间 dataType: 'json', //返回的数据格式: success: function (result, textStatus, jqXHR) { if (result.result == "1") { // 编辑赋值 layer.alert("创建成功", {icon: 0}); } else { layer.alert("创建失败,请检查sql语句,注意结尾不能有分号!具体错误信息:"+result.msg, {icon: 5}); } }, error: function (xhr, textStatus) { layer.alert(textStatus); } }); }
3、将数据上传到后台之后,后台生成存储过程。当然一般情况下,我们还是先把数据接口和接口明细数据持久化保存,再来执行创建操作,可以保证数据不会丢失。此处由于篇幅问题,我就省略了中间这一步。
1)创建一个service 的接口:
public interface TestService { ResultInfo createPro(Map<String,Object> map); }
2)然后创建接口的实现类:
@Service public class TestServiceImpl implements TestService { /** * 创建存储过程 * * @param map 接口配置和接口参数信息 * 参数详解: type 输入输出参数,取值为 in,out * paraType 参数类型。取值为:1:int 2:double 3:varchar 4:datetime * @return */ @Override @Transactional public void createPro(Map<String,Object> map) { ResultInfo resultInfo = new ResultInfo(); QtInterface qtInterface=new QtInterface(); qtInterface =buildInterface(map, qtInterface);// 加载接口配置信息 List<QtInterfaceParameter> paraList = new ArrayList<QtInterfaceParameter>(); paraList = buildParam(map.get("jsonData"));// 加载接口配置信息 StringBuffer bf = new StringBuffer(); // 建立生成过程的语句 bf.append("create procedure \t"); bf.append(qtInterface.getName()); bf.append("\n"); bf.append("("); String para_type = ""; int i = 1; for (QtInterfaceParameter qt : paraList) { switch (qt.getParaType()) { // 参数类型 case "1": para_type = "int"; break; case "2": para_type = "double"; break; case "3": para_type = "varchar(" + qt.getParaLen() + ")"; break; case "4": para_type = "datetime"; break; default: para_type = "varchar(255)"; break; } if (i == paraList.size()) { bf.append("" + qt.getType() + " " + qt.getName() + " " + para_type + ") "); } else { bf.append("" + qt.getType() + " " + qt.getName() + " " + para_type + ", "); } i++; } bf.append(" COMMENT '"+ qtMonitorWarnInterface.getInfo() +"'\n"); // 添加描述信息 bf.append("BEGIN\n"); bf.append(qtInterface.getContent()); // 存储过程内容 bf.append(";\nEND;"); // 先执行删除操作 jdbcTemplate.execute("drop procedure if exists " + qtInterface.getName() + " ;"); jdbcTemplate.execute(bf.toString()); } /** * 初始化接口配置信息 * */ private QtInterface buildInterface(Map<String, Object> map, QtInterface qtInterface) { // 接口配置名称 if (map.get("name") != null && !"".equals(map.get("name "))) { qtInterface.setName((String) map.get("name ")); } //此处省略其他项,其他项的取值方法跟上面的一样 … return qtInterface; } /** * 初始化接口配置参数明细 * */ private List<QtInterfaceParameter> buildParam(String postData) { List<QtInterfaceParameter> list = new ArrayList<QtInterfaceParameter>(); if(postData!=null &&!"".equals(postData)){ List<Map<String, Object>> listParam = (List<Map<String, Object>>) JsonMapper.fromJsonString(postData, ArrayList.class); for (Map<String, Object> map : listParam) { QtInterfaceParameter para = new QtInterfaceParameter(); // 接口配置参数名称 if (map.get("name") != null && !"".equals(map.get("name "))) { para.setName((String) map.get("name ")); } // 此处省略其他项,其他项的取值方法跟上面的一样 … list.add(para); } } return list; }
3) 添加控制器进行调用:
@Controller @RequestMapping(value = "/test") public class TestController { @Autowired private TestService testService; @RequestMapping(value = "/createPro", method = RequestMethod.GET) public ResultInfo createPro(@RequestBody Map<String, Object> map ) { ResultInfo resultInfo = new ResultInfo(); try { testService.createPro(Id); resultInfo.setResult(1); resultInfo.setMsg("创建过程成功"); } catch (Exception e) { resultInfo.setResult(-1); resultInfo.setMsg(e.getMessage()); } return resultInfo; } }
4)最后动态生成的SQL就是这个样子:
CREATE PROCEDURE `testbase`.`test`(in a_user_id varchar(100)) COMMENT '测试接口' BEGIN select * from userInfo where user_id=a_user_id; END
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
Spring Cloud 中@FeignClient注解中的contextId属性详解
这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25Springboot如何实现Web系统License授权认证
这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 这篇文章主要介绍了Vue基于localStorage存储信息代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-16
- 新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
深入研究mysql中的varchar和limit(容易被忽略的知识)
为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15如何在Spring WebFlux的任何地方获取Request对象
这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31