前言:在兩年前(最初發布時間:2013年1月9日(csdn),當前文章時間2015年11月10日),項目組推出了基於Dapper,Mvc和WebApi的快速開發框架,隨着後續Slickflow產品的實踐和應用,今再次對SlickOne項目作以回顧和總結。其目的是精簡,持續改進,保持重構,讓開發人員瞭解到最新的變化,尤爲是全棧開發人員作以參考。javascript
兩年以前的博客文章能夠查閱(最初發布時間:2013年1月9日):css
http://blog.csdn.net/besley/article/details/8479943前端
1. 新版本變化綜述:java
1) Dapper部分的變化:git
Dapper自己有支持對數據庫底層接口,這次主要是增長了Oracle和MySQL數據庫的接口,也修改了Dapper裏面的SqlMapper文件。github
2) SlickOne.Data 數據訪問web
在泛型封裝的基礎上,提供了列表分頁,新增主鍵ID返回,根據多ID值查詢返回列表,新增查詢功能的存儲過程等接口。ajax
3) Mvc/WebApisql
將兩個類型的項目動態庫文件整合在一個Web項目裏面,同時響應頁面請求和Api請求。數據庫
4) Web前端
由JQueryUI 轉換到 Bootstrap框架,核心組件SlickGrid 轉換爲Bootstrap樣式。
2. 框架設計
1) 數據訪問Repository泛型類
Repository泛型類,完全實現數據快速訪問,不用重複編寫不一樣實體的通用基本方法;並且此泛型類的存在也用以支持Dapper,EF,Heibernate等各類數據訪問框架,考慮到不一樣用戶的技術儲備,只要去實現IRepository的接口方法就能夠繼續使用本身喜歡的框架。
2) 基於簡單實體訪問
簡單實體,原始來源爲數據庫表的對應實體,並且並限定爲只包含屬性字段。在早期版本區分了數據實體和業務實體,有AutoMapper的轉換工具,在新版本里面,再也不強調業務實體,而是統一命名爲簡單實體,始終根據簡單實體作業務功能開發,作數據的存儲和讀取。
3) 接口定義優先策略
接口方法更加側重於業務過程的定義。基本方法如新增,編輯和刪除能夠直接快速調用Repository裏的泛型方法,再也不默認自動生成Partial文件去維護,包括Interface, Service類和ApiController類都再也不生成Partial類文件。
4) WebApi 接口封裝
消息體引用ResponseResult泛型類,包括狀態(Status),消息(Message)和實體(Entity)關鍵屬性。ResponseResult類用於服務端到前端的數據和消息封裝,消息內容格式是JSON數據格式。
5) Javascript模板引擎
採用前端Javascript模板引擎,解析WebApi傳遞迴的JSON對象,作前端界面展示。模板引擎能夠採用HandlebarsJS或DustJS。也能夠選擇其它模板引擎。
6) Bootstrap
前端框架過渡到Bootstrap框架,相應的控件,如SlickGrid和ZTree等控件均可以找到對應Bootstrap的樣式版本。
3. 解決方案結構圖示
4. 項目代碼實例
1) 實體對象
/// <summary> /// 產品實體對象 /// </summary> [Table("PrdProduct")] public class ProductEntity { public int ID { get; set; } public string ProductName { get; set; } public string ProductCode { get; set; } public string ProductType { get; set; } public Nullable<decimal> UnitPrice { get; set; } public string Notes { get; set; } }
2) 接口定義
/// <summary> /// 產品服務接口 /// </summary> public interface IProductService { List<ProductEntity> GetProductList(); }
3) 服務實現
/// <summary> /// 獲取列表數據(示例查詢方法,實際會用到分頁,此處用於演示。) /// </summary> /// <returns></returns> public List<ProductEntity> GetProductList() { var sql = @"SELECT ID, ProductName, ProductCode, ProductType, UnitPrice, CreatedDate FROM PrdProduct"; var list = QuickReporsitory.Query<ProductEntity>(sql, null) .ToList(); return list; }
4) WebApi
/// <summary> /// 獲取產品列表 /// </summary> /// <returns></returns> [HttpGet] public ResponseResult<List<ProductEntity>> GetProductList() { var result = ResponseResult<List<ProductEntity>>.Default(); try { var list = ProductService.GetProductList(); result = ResponseResult<List<ProductEntity>>.Success(list); } catch (System.Exception ex) { result = ResponseResult<List<ProductEntity>>.Error( string.Format("讀取{0}數據失敗, 錯誤:{1}", "產品列表", ex.Message) ); } return result; }
5) 前端腳本
productlist.load = function () { jshelper.ajaxGet("/soneweb/api/product/GetProductList", null, function (result) { if (result.Status == 1) { var columnProduct = [ { id: "ID", name: "ID", field: "ID", width: 40, cssClass: "bg-gray" }, { id: "ProductName", name: "名稱", field: "ProductName", width: 120, cssClass: "bg-gray" }, { id: "ProductCode", name: "編碼", field: "ProductCode", width: 120, cssClass: "bg-gray" }, { id: "ProductType", name: "類型", field: "ProductType", width: 160, cssClass: "bg-gray" }, { id: "UnitPrice", name: "單價", field: "UnitPrice", width: 160, cssClass: "bg-gray" }, { id: "CreatedDate", name: "建立時間", field: "CreatedDate", width: 200, cssClass: "bg-gray", formatter: datetimeFormatter }, ]; var optionsProduct = { editable: true, enableCellNavigation: true, enableColumnReorder: true, asyncEditorLoading: true, forceFitColumns: false, topPanelHeight: 25 }; var dsProduct = result.Entity; var dvProduct = new Slick.Data.DataView({ inlineFilters: true }); var gridProduct = new Slick.Grid("#myProductGrid", dvProduct, columnProduct, optionsProduct); dvProduct.onRowsChanged.subscribe(function (e, args) { gridProduct.invalidateRows(args.rows); gridProduct.render(); }); dvProduct.onRowCountChanged.subscribe(function (e, args) { gridProduct.updateRowCount(); gridProduct.render(); }); dvProduct.beginUpdate(); dvProduct.setItems(dsProduct, "ID"); gridProduct.setSelectionModel(new Slick.RowSelectionModel()); dvProduct.endUpdate(); gridProduct.onSelectedRowsChanged.subscribe(function (e, args) { var selectionRowIndex = args.rows[0]; var row = dvProduct.getItemByIdx(selectionRowIndex); if (row) { productlist.mselectedProductID = row.ID; productlist.mselectedProductRow = row; } }); }; }); function datetimeFormatter(row, cell, value, columnDef, dataContext) { if (value != null && value != "") { return value.substring(0, 10); } } }
6) 頁面呈現
5. 項目應用場景
SlickOne適用於BS/CS等架構的系統,目前已經用於Web網站項目,電商ERP,OA,工做流和App等各類類型的系統。
6. 項目資源
SlickOne項目開源地址:
http://github.com/besley/slickone
(包含數據庫腳本文件)
SlickOne 作框架基礎的權限管理:
http://github.com/besley/slicksafe
SlickSafe 權限管理在線DEMO:
http://demo.slickflow.com/ssweb/
7. 特別緻謝
感謝隨風,青文等網友對項目代碼的貢獻,開源能讓你們集體參與,能讓更多人分享代碼成果。
8. 培訓及技術支持
爲團隊開發人員快速上手,Slickflow項目組提供線上開發框架架構設計培訓,流程引擎培訓,SlickGrid插件開發培訓等服務,歡迎留言或諮詢。
9. 在線QQ交流羣
QQ羣: 151650479