Java Spring动态生成Mysql存储过程详解
作者:画笔灬 发布时间:2024-01-25 10:16:32
标签: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
来源:https://www.cnblogs.com/Aimee-AI/p/10849198.html
0
投稿
猜你喜欢
- 在一个大型的项目中,不可避免会出现操作时间的业务,比如时间的格式化,比如时间的加减,我们一般会直接使用moment.js库来做,毕竟稳定可靠
- 前言为了往我们写好的Python代码传入参数,有很多种方法,比如使用input获取从DOS 输入的参数,又或者读取txt 文件中的字符作为参
- 一:直接把MDB(MDE)文件放到网络中的共享目录中,在客户端做好对应的快捷方式二:数据库折分(菜单:工具,实用工具,折分)成前后台,把后台
- 本文实例讲述了python求pi的方法,是一篇翻译自国外网站的文章,分享给大家供大家参考。具体实现方法如下:#_*_ coding=utf-
- 1.执行cmd命令,不显示执行过程中弹出的黑框def run_cmd( cmd_str='', echo_print=1):
- Supervisor 是一个类 unix 操作系统下的进程监控管理工具。安装 SupervisorSupervisor 是由 Python
- 本文较为详细的讲述了Python中常用的模块,分享给大家便于大家查阅参考之用。具体如下:1.内置模块(不用import就可以直接使用)常用内
- 需求描述最近在写一个图像标注小工具,其中需要用到一个缩略图列表,来查看文件夹内的图片文件。这里整理一个基于QListWidget实现的版本,
- 需求:统计列表list1中元素3的个数,并返回每个元素的索引list1 = [3, 3, 8, 9, 2, 10, 6, 2, 8, 3,
- 如何用SQL 建表? 如下:CREATE TABLE statement
- 前言本文从代码复用的角度一步一步演示如何从python普通代码进化到面向对象,并通过代码去解释一些面向对象的理论。所以,本文前面的内容都是非
- 一、Python不同版本的类Python2.2之前是没有共同的祖先的,之后引入Object类,它是所有类的共同祖先类ObjectPython
- torch.nn 是专门为神经网络设计的模块化接口,nn构建于autgrad之上,可以用来定义和运行神经网络nn.Module 是nn中重要
- paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。paramiko支持Lin
- 一、工具python3第三方类库requestspython3-pyqt5(GUI依赖,不用GUI可不装)ubuntu系列系统使用以下命令安
- 1. set 的基本内容1.基本特点(1) 无序性(2) 确定性(3) 不重复性2.set() 实质内部进行 可迭代性的 for 循环例子:
- 本文实例讲述了Python 操作 PostgreSQL 数据库。分享给大家供大家参考,具体如下:我使用的是 Python 3.7.0Post
- insert into(列名) select 列名 from 表名 where 条件 --不创建表,只复制表数据 select 列名 int
- 概述最近在跑一篇图像修复论文的代码,配置好环境之后开始运行,发现数据一直加载不进去。害,还是得看人家代码咋写的,一句一句看逻辑,准能找出问题
- ndarray 的数据类型数据类型,即 dtype ,也是一个特殊的对象, 它包含了ndarray需要为某一种类型数据所申明的内存块信息(也