Java Spring動(dòng)態(tài)生成Mysql存儲(chǔ)過程詳解
一、 背景
由于公司業(yè)務(wù)需要?jiǎng)討B(tài)配置一些存儲(chǔ)過程來生成數(shù)據(jù),之前嘗試過使用jpa來完成,或多或少都存在一些問題,最后使用了spring的Jdbctemplate。
二、 環(huán)境
1.此隨筆內(nèi)容基于spring boot項(xiàng)目
2.數(shù)據(jù)庫為mysql 5.7.9版本
3.jdk 版本為1.8
三、 說明
說明:為方便表示,下列存儲(chǔ)過程在代碼中的表示我稱之為接口配置
四、 內(nèi)容
1、定義接口和接口參數(shù)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)接口配置參數(shù)bean:
@Entity
@Table(name="qt_interface_parameter")
public class QtInterfaceParameter {
@Id
private String id;
@Column(name="inter_id")
private String interId;
private String name; //參數(shù)名稱
private String explain_info; //參數(shù)描述
private String type;// 輸入輸出類型
private String paraType; // 參數(shù)類型
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">接口狀態(tài)<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">已創(chuàng)建</option>
</select>
</div>
</div>
<div class="form-group">
<label for="content" class="col-sm-2 control-label">接口內(nèi)容<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">接口參數(shù):</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部分代碼太長(zhǎng),就只貼一個(gè)提交方法吧
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)// 參數(shù)明細(xì)信息,字段就是接口配置參數(shù)bean 中的字段信息
};
$.ajax({
url: Url + 'test/createPro',
type: 'get', //GET
async: false, //或false,是否異步
data: JSON.stringify(postData),
timeout: 5000, //超時(shí)時(shí)間
dataType: 'json', //返回的數(shù)據(jù)格式: success: function (result, textStatus, jqXHR) {
if (result.result == "1") { // 編輯賦值
layer.alert("創(chuàng)建成功", {icon: 0});
} else {
layer.alert("創(chuàng)建失敗,請(qǐng)檢查sql語句,注意結(jié)尾不能有分號(hào)!具體錯(cuò)誤信息:"+result.msg, {icon: 5});
}
},
error: function (xhr, textStatus) {
layer.alert(textStatus);
}
});
}
3、將數(shù)據(jù)上傳到后臺(tái)之后,后臺(tái)生成存儲(chǔ)過程。當(dāng)然一般情況下,我們還是先把數(shù)據(jù)接口和接口明細(xì)數(shù)據(jù)持久化保存,再來執(zhí)行創(chuàng)建操作,可以保證數(shù)據(jù)不會(huì)丟失。此處由于篇幅問題,我就省略了中間這一步。
1)創(chuàng)建一個(gè)service 的接口:
public interface TestService {
ResultInfo createPro(Map<String,Object> map);
}
2)然后創(chuàng)建接口的實(shí)現(xiàn)類:
@Service
public class TestServiceImpl implements TestService {
/**
* 創(chuàng)建存儲(chǔ)過程
*
* @param map 接口配置和接口參數(shù)信息
* 參數(shù)詳解: type 輸入輸出參數(shù),取值為 in,out
* paraType 參數(shù)類型。取值為: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()) { // 參數(shù)類型
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()); // 存儲(chǔ)過程內(nèi)容
bf.append(";\nEND;");
// 先執(zhí)行刪除操作
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 "));
}
//此處省略其他項(xiàng),其他項(xiàng)的取值方法跟上面的一樣 …
return qtInterface;
}
/**
* 初始化接口配置參數(shù)明細(xì)
*
*/
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();
// 接口配置參數(shù)名稱
if (map.get("name") != null && !"".equals(map.get("name "))) {
para.setName((String) map.get("name "));
}
// 此處省略其他項(xiàng),其他項(xiàng)的取值方法跟上面的一樣 …
list.add(para);
}
}
return list;
}
3) 添加控制器進(jìn)行調(diào)用:
@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("創(chuàng)建過程成功");
} catch (Exception e) {
resultInfo.setResult(-1);
resultInfo.setMsg(e.getMessage());
}
return resultInfo;
}
}
4)最后動(dòng)態(tài)生成的SQL就是這個(gè)樣子:
CREATE PROCEDURE `testbase`.`test`(in a_user_id varchar(100)) COMMENT '測(cè)試接口' BEGIN select * from userInfo where user_id=a_user_id; END
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中操作Bean的生命周期的方法總結(jié)
在SpringBoot應(yīng)用中,管理和操作Bean的生命周期是一項(xiàng)關(guān)鍵的任務(wù),這不僅涉及到如何創(chuàng)建和銷毀Bean,還包括如何在應(yīng)用的生命周期中對(duì)Bean進(jìn)行精細(xì)控制,本文給大家總結(jié)了SpringBoot中操作Bean的生命周期的方法,需要的朋友可以參考下2023-12-12
Java 輸入多行字符串或者多個(gè)int數(shù)值的方法
今天小編就為大家分享一篇Java 輸入多行字符串或者多個(gè)int數(shù)值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
如何使用 Shell 腳本查看多個(gè)服務(wù)器的端口是否打開的方法
這篇文章主要介紹了如何使用 Shell 腳本來查看多個(gè)服務(wù)器的端口是否打開的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼
這篇文章主要介紹了Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11

