1. 程式人生 > >Spring Boot JdbcTemplate ACE 模板

Spring Boot JdbcTemplate ACE 模板

Spring Boot JdbcTemplate

基於Bootstrap3的ACE模板,並實現了一個基本的增刪改查分頁功能

Jar 依賴

 

主要是thymeleaf 的使用比較經典,Bootstrap ACE真的好用

明天來完善其細節

 

 

優點如下

在配置上,0配置,約定大於配置

@Autowired
private Environment env;
//destroy-method="close"的作用是當資料庫連線不使用的時候,就把該連線重新放到資料池中,方便下次使用呼叫.
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//使用者名稱
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密碼
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setInitialSize(2);//初始化時建立物理連線的個數
dataSource.setMaxActive(20);//最大連線池數量
dataSource.setMinIdle(0);//最小連線池數量
dataSource.setMaxWait(60000);//獲取連線時最大等待時間,單位毫秒。
dataSource.setValidationQuery("SELECT 1");//用來檢測連線是否有效的sql
dataSource.setTestOnBorrow(false);//申請連線時執行validationQuery檢測連線是否有效
dataSource.setTestWhileIdle(true);//建議配置為true,不影響效能,並且保證安全性。
dataSource.setPoolPreparedStatements(false);//是否快取preparedStatement,也就是PSCache
return dataSource;
}

連線池如此配置,相當簡單,沒有多餘的程式碼和笨重的xml配置

 

然後直接注入Spring JDBC的JdbcTemplate即可用, 但是如何控制事務呢,明天寫

2017年10月12日23:46:13

 

 

其次 Dao Daoimpl Service ServiceImpl 一氣呵成,

 

controller層如下


					@RequestMapping(value = "/queryLeanList",method = RequestMethod.POST,produces="application/json;charset=UTF-8")
public @ResponseBody Map<String,Object> queryLearnList(HttpServletRequest request , HttpServletResponse response,
@RequestParam(value = "page",required = false)String page1,
@RequestParam(value = "rows",required = false)String rows1,
@RequestParam(value = "author",required = false)String author,
@RequestParam(value = "title",required = false)String title
){
String page = page1; // 取得當前頁數,注意這是jqgrid自身的引數
String rows = rows1; // 取得每頁顯示行數,,注意這是jqgrid自身的引數
Map<String,Object> params = new HashMap<String,Object>();
params.put("page", page);
params.put("rows", rows);
params.put("author", author);
params.put("title", title);
Page pageObj =learnService.queryLearnResouceList(params);
List<Map<String, Object>> learnList=pageObj.getResultList();
Map<String,Object> jo= new HashMap<>();
jo.put("rows", learnList);
jo.put("total", pageObj.getTotalPages());
jo.put("records", pageObj.getTotalRows());
return jo;
}

 

Spring MVC 超級好用的書寫方式, @RequestParam @ResponseBody 得益於強大的HttpMessageConverters , 如下圖

 

其實Struts2也有第三方外掛可以實現,只不過很不好用

 

這個Demo中 Page寫的也不錯,很有邏輯性 還有tools包中的一些工具類也相當好

靜態資源:

SpringBoot 約定大於規則, static 是靜態資源,可以直接訪問, template中必須通過內部跳轉,很好用.

 

下面是 thymeleaf引擎的好處, 與SpringMVC Spring 完美結合。 然後是Bootstrap ACE模板的好處

 

Thymeleaf優點

正如Thymeleaf官網所說。

Thymeleaf是面向Web和獨立環境的現代伺服器端Java模板引擎。

Thymeleaf的主要目標是為您的開發工作流程帶來優雅的自然模板 - 可以正確顯示在瀏覽器中的HTML,也可以作為靜態原型工作,從而在開發團隊中進行更強大的協作。

隨著Spring框架的模組,與您最喜歡的工具的整合,以及插入自己的功能的能力,Thymeleaf是現代HTML5 JVM Web開發的理想選擇,儘管它可以做的更多。

Thymeleaf 編寫的HTML模板仍然像HTMl一樣工作,讓您在應用程式執行的實際模板繼續作為有用的設計

  • 1.Thymeleaf 在有網路和無網路的環境下皆可執行,即它可以讓美工在瀏覽器檢視頁面的靜態效果,也可以讓程式設計師在伺服器檢視帶資料的動態頁面效果。這是由於它支援 html 原型,然後在 html 標籤裡增加額外的屬性來達到模板+資料的展示方式。瀏覽器解釋 html 時會忽略未定義的標籤屬性,所以 thymeleaf 的模板可以靜態地執行;當有資料返回到頁面時,Thymeleaf 標籤會動態地替換掉靜態內容,使頁面動態顯示。
  • 2.Thymeleaf 開箱即用的特性。它提供標準和spring標準兩種方言,可以直接套用模板實現JSTL OGNL表示式效果,避免每天套模板、該jstl、改標籤的困擾。同時開發人員也可以擴充套件和建立自定義的方言。
  • 3.Thymeleaf 提供spring標準方言和一個與 SpringMVC 完美整合的可選模組,可以快速的實現表單繫結、屬性編輯器、國際化等功能。

Bootstrap ACE模板優點

從功能實現來分析

 

1、查詢功能和初始化資料

Jdgird

 

$(grid_selector).jqGrid({
url:"learn/queryLeanList", //對應的controller層方法
datatype: "json",
mtype: 'POST',
height:window.screen.height-550,
colModel: [
{ label: 'id', name: 'id', width: 75,hidden:true},
{ label: '作者', name: 'author', width: 200 },
{ label: '教程名稱', name: 'title', width: 200 },
{ label: '地址', name: 'url', width: 200 ,hidden:true},
{ label: '地址', name: 'opt', width: 200,formatter: function(cellvalue, options, cell){
return '<a href="'+cell.url+'" class="btn btn-purple btn-sm" target="_blank"><i class="fa fa-cog fa-spin" aria-hidden="true"></i>點我</a>';
}}
],

 

Controller層程式碼,聰明的是查詢方法和自動初始化資料用的是一個Controller方法(但是增加了耦合性,估計在大型專案中肯定不會採取)


					@RequestMapping(value = "/queryLeanList",method = RequestMethod.POST,produces="application/json;charset=UTF-8")
public @ResponseBody Map<String,Object> queryLearnList(HttpServletRequest request , HttpServletResponse response,
@RequestParam(value = "page",required = false)String page1,
@RequestParam(value = "rows",required = false)String rows1,
@RequestParam(value = "author",required = false)String author,
@RequestParam(value = "title",required = false)String title
){
String page = page1; // 取得當前頁數,注意這是jqgrid自身的引數
String rows = rows1; // 取得每頁顯示行數,,注意這是jqgrid自身的引數
Map<String,Object> params = new HashMap<String,Object>();
params.put("page", page);
params.put("rows", rows);
params.put("author", author);
params.put("title", title);
Page pageObj =learnService.queryLearnResouceList(params);
List<Map<String, Object>> learnList=pageObj.getResultList();
Map<String,Object> jo= new HashMap<>();
jo.put("rows", learnList);
jo.put("total", pageObj.getTotalPages());
jo.put("records", pageObj.getTotalRows());
return jo;
}

 

只需要在實現的時候,這樣寫(有一個where 1=1 , 後面根據傳入引數來判斷,是否要加入and 等等)

 

@Override
public Page queryLearnResouceList(Map<String,Object> params) {
StringBuffer sql =new StringBuffer();
sql.append("select * from learn_resource where 1=1");
if(!StringUtil.isNull((String)params.get("author"))){ //StringUtil 是自己寫的工具類,防止為null,""等
sql.append(" and author like '%").append((String)params.get("author")).append("%'");
}
if(!StringUtil.isNull((String)params.get("title"))){
sql.append(" and title like '%").append((String)params.get("title")).append("%'");
}
Page page = new Page(sql.toString(), Integer.parseInt(params.get("page").toString()), Integer.parseInt(params.get("rows").toString()), jdbcTemplate);
return page;
}

查詢程式碼,直接呼叫

 

//查詢點選事件
$("#queryBtn").click(function(){
var qryAuthor=$("#qryAuthor").val();
var qryTitle=$("#qryTitle").val();
$(grid_selector).jqGrid('setGridParam',{
postData:{author:qryAuthor,title:qryTitle},
//search: true,
page:1
}).trigger("reloadGrid");
});

2、新增使用者和修改使用者

按鈕

新增和修改視窗

<!--新增視窗-->
<div id="addModal" class="bootbox modal fade" tabindex="-1" role="dialog"> // role 決定了其隱藏
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">新增教程</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form" onsubmit="return false;">

<div class="form-group" style="display: none;">
<label class="col-sm-2 control-label">id</label>
<div class="col-sm-8">
<input id="id" type="text" class="form-control" placeholder="" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">作者</label>
<div class="col-sm-8">
<input id="author" type="text" class="form-control" placeholder="輸入作者" />
</div>
</div>
<div class="form-group" >
<label class="col-sm-2 control-label">教程名稱</label>
<div class="col-sm-8">
<input id="title" type="text" class="form-control" placeholder="輸入教程名稱" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">教程地址</label>
<div class="col-sm-8">
<input id="url" type="text" class="form-control" placeholder="輸入教程地址" />
</div>
</div>

</form>
</div>
<div class="modal-footer">
<button data-bb-handler="confirm" type="button" id="saveLearnBtn" class="btn btn-success radius">
<span><i class="icon-ok"></i></span> &nbsp;&nbsp;&nbsp;
</button>
<button data-bb-handler="cancel" type="button" id="cancelSave" class="btn btn-danger radius">取消</button>
</div>
</div>
</div>
</div>

點選修改和增加的按鈕,彈出對話方塊

這裡有兩個小細節

  1. Task變數, 用來選擇是呼叫的add方法,還是update方法
  2. 往前臺資料時已經將每個資料的資訊都獲取了,這樣就不用再單獨請求單條資料了

彈出對話方塊後 儲存方法, 新增和更新用的是一個按鈕,用task 屬性智慧識別


/**
* 儲存教程(新增或修改)
*/
function saveLearn(){
var id = $('#id').val(); //獲取輸入資料
var author = $('#author').val();
var title = $('#title').val();
var url = $('#url').val();
$.ajax({
url: "learn/"+task,//動態的改變請求Controller
cache: false,
dataType:'json',
data : {
"id":id,
"author":author,
"title": title,
"url":url
},
type : 'post',
beforeSend: function () { //防止重複提交
// 禁用按鈕防止重複提交
$('#saveLearnBtn').attr({ disabled: "disabled"});
},
success: function(result){
if(result.flag == true){ //如果沒有成功
$.messager.alert('溫馨提示',result.message);
$("#addModal").modal('hide');
refreshData(); //重新整理結果
}else{
$.messager.alert('溫馨提示',result.message);
}
},
complete: function () {
$('#saveLearnBtn').removeAttr("disabled"); //控制dom屬性,刪除disabled屬性
},
error: function (data) {
console.info("error: " + data.responseText); //錯誤返回值
}
});
}

 

後臺就很好實現了

  1. 刪除功能的實現


					//刪除教程方法 選擇多個的話,行id用逗號隔開比如 3,4
$("#deleteLearnBtn").click(function () {
var rows=$(grid_selector).getGridParam('selarrrow'); //這點很靈性
if(rows.length>0){
$.messager.confirm("溫馨提示", "是否確定刪除所選記錄?", function() {
$.ajax({
url:"learn/delete",
cache: false,
type:"post",
data:{"ids": rows.join(",")}, //這點很靈性,自動的
beforeSend : function(){
loading=layer.load("正在刪除中...");
},
success:function(result){
$.messager.alert(result.message);
refreshData();
},error:function(){
$.messager.alert("溫馨提示","請求錯誤!");
},
complete : function(){
layer.close(loading);
}
});
});
}else{
//兩種風格的提示,layer或者messager自己選擇一種用即可。
// $.messager.alert("溫馨提示","至少選擇一行記錄!");
layer.msg('至少選中一行記錄!', {icon: 7,time: 2000}); //2秒關閉(如果不配置,預設是3秒)
}
})

});

 

刪除後臺邏輯也很好實現

 

至此結束