某某人曾经跟我说,你们做系统不就是增删查改吗。
是啊,很多时候我们就是把用户的数据同后台数据库进行增删查改的沟通。
但是,把CRUD(增删查改)做得好,可能也不是一件很简单的事,
这里要展现的是我现在能写出来最好的Demo了,水平有限,小弟在校学生一枚,还请各位看客多多指教。
Demo前台使用JQuery EasyUI 请求一般处理程序,一般处理程序调用BLL层方法,BLL==>DAL,一个简单三层的效果。
项目结构如图:
一、数据库表结构
这里只创建一个UserInfo表,表中字段有:UserID,CardID,UPwd,UName,UAge,IsDel,AddDate
二、后台处理CRUD
后台处理添加、删除(软删除)、编辑、查询(分页)。其中查询包括:分页和搜索处理所有有点麻烦,
1、先介绍数据访问层(DAL)中的方法
这里是,添加、删除、编辑、分页查询的方法。
前台查询的参数存储在NameValueCollection中,然后在DAL层中的PreSearchParameter方法中把查询参数装配到sql语句和SqlParameter中,
在DAL层中获取的数据是DataTable,然后在BLL层中转换成JSON格式的数据传给EasyUI展示。
1 using System; 2 using System.Text; 3 using System.Data; 4 using System.Data.SqlClient; 5 using Dedeyi.Common; 6 using System.Collections; 7 using System.Collections.Generic; 8 using System.Collections.Specialized; 9 10 namespace Dedeyi.ZSF.DAL 11 { 12 public class UserInfoDAL 13 { 14 /// <summary> 15 /// 增加一条数据 16 /// </summary> 17 public int Add(Dedeyi.ZSF.Model.UserInfo model) 18 { 19 StringBuilder strSql=new StringBuilder(); 20 strSql.Append("insert into UserInfo("); 21 strSql.Append("CardID,UPwd,UName,UAge,IsDel,AddDate)"); 22 strSql.Append(" values ("); 23 strSql.Append("@CardID,@UPwd,@UName,@UAge,@IsDel,@AddDate)"); 24 strSql.Append(";select @@IDENTITY"); 25 SqlParameter[] parameters = { 26 new SqlParameter("@CardID", SqlDbType.VarChar,16), 27 new SqlParameter("@UPwd", SqlDbType.VarChar,64), 28 new SqlParameter("@UName", SqlDbType.NVarChar,16), 29 new SqlParameter("@UAge", SqlDbType.Int,4), 30 new SqlParameter("@IsDel", SqlDbType.Bit,1), 31 new SqlParameter("@AddDate", SqlDbType.SmallDateTime)}; 32 parameters[0].Value = model.CardID; 33 parameters[1].Value = model.UPwd; 34 parameters[2].Value = model.UName; 35 parameters[3].Value = model.UAge; 36 parameters[4].Value = model.IsDel; 37 parameters[5].Value = model.AddDate; 38 39 object obj = SQLHelper.ExecuteScalar(strSql.ToString(),parameters); 40 if (obj == null) 41 { 42 return 0; 43 } 44 else 45 { 46 return Convert.ToInt32(obj); 47 } 48 49 } 50 51 /// <summary> 52 /// 删除用户 53 /// </summary> 54 /// <param name="keyid"></param> 55 public void Del(int keyid) 56 { 57 //此处软删除 58 string s = "update UserInfo set IsDel=1 where UserID="+keyid; 59 SQLHelper.ExecuteNoneQuery(s,null); 60 } 61 62 ///<summary> 63 ///更新一条数据 64 ///</summary> 65 public bool Update(Dedeyi.ZSF.Model.UserInfo model) 66 { 67 StringBuilder strSql = new StringBuilder(); 68 69 strSql.Append("update [UserInfo] set "); 70 strSql.Append(" CardID=@CardID,"); 71 strSql.Append(" UPwd=@UPwd,"); 72 strSql.Append(" UName=@UName,"); 73 strSql.Append(" UAge=@UAge "); 74 //strSql.Append(" IsDel=@IsDel,"); 75 //strSql.Append("AddDate=@AddDate"); 76 strSql.Append(" where UserID=@UserID"); 77 78 SqlParameter[] parameters = { 79 new SqlParameter("@UserID", SqlDbType.Int,4), 80 new SqlParameter("@CardID", SqlDbType.VarChar,16), 81 new SqlParameter("@UPwd", SqlDbType.VarChar,64), 82 new SqlParameter("@UName", SqlDbType.NVarChar,16), 83 new SqlParameter("@UAge", SqlDbType.Int,4), 84 //new SqlParameter("@IsDel", SqlDbType.Bit,1), 85 //new SqlParameter("@AddDate", SqlDbType.DateTime), 86 }; 87 parameters[0].Value = model.UserID; 88 parameters[1].Value = model.CardID; 89 parameters[2].Value = model.UPwd; 90 parameters[3].Value = model.UName; 91 parameters[4].Value = model.UAge; 92 //parameters[5].Value = model.IsDel; 93 //parameters[6].Value = model.AddDate; 94 95 int rows = SQLHelper.ExecuteNoneQuery(strSql.ToString(),parameters); 96 if (rows > 0) 97 { 98 return true; 99 } 100 else 101 { 102 return false; 103 } 104 } 105 106 107 //分页相关的 108 #region 109 /// <summary> 110 /// 获取条件查询数据行数 111 /// </summary> 112 /// <param name="nv">关键字,UName,UAge,在前台请求形成Hashtable作为参数时候要用到这个</param> 113 /// <returns>数据行数</returns> 114 public int GetSearchCount(NameValueCollection nv) 115 { 116 string sc; 117 SqlParameter[] ps; 118 PreSearchParameter(nv, out sc, out ps); 119 120 string sql = "select count(0) from UserInfo where " + sc; 121 122 return Convert.ToInt32(SQLHelper.ExecuteScalar(sql, ps)); 123 } 124 125 /// <summary> 126 /// 获取条件查询的分页数据 127 /// </summary> 128 /// <param name="index"></param> 129 /// <param name="size"></param> 130 /// <param name="nv">关键字,UName,UAge,在前台请求形成Hashtable作为参数时候要用到这个</param> 131 /// <returns></returns> 132 public DataTable GetSearchPage(int index, int size,NameValueCollection nv) 133 { 134 string f = "UserID,CardID,UPwd,UName,UAge,AddDate"; 135 string o = "AddDate DESC"; 136 return GetSearchePage(index,size,nv,f,o); 137 } 138 /// <summary> 139 /// 获取分页数据 140 /// </summary> 141 /// <param name="index">当前页</param> 142 /// <param name="size">每一页数据行数</param> 143 /// <param name="ht">查询条件key是字段,value是对应的值</param> 144 /// <param name="fieldList">要返回的字段</param> 145 /// <param name="orderby">排序规则不要order by ,如 AddDate desc,userid asc</param> 146 /// <returns></returns> 147 private DataTable GetSearchePage(int index, int size, NameValueCollection nv, string fieldList,string orderby) 148 { 149 string sc ; //过滤条件 150 SqlParameter[] ps; 151 PreSearchParameter(nv,out sc,out ps); 152 153 string sql = "select * from (select {0},ROW_NUMBER() over(order by {1}) as num from UserInfo where {2}) as tb"; 154 sql += " where num between {3} and {4}"; 155 156 sql = string.Format(sql, fieldList, orderby, sc, (index - 1) * size + 1, index * size); 157 158 return SQLHelper.GetDataTable(sql, ps); 159 } 160 161 /// <summary> 162 /// 把查询参数转换为sql,和SqlParameter 163 /// </summary> 164 /// <param name="ht">关键字,UName,UAge,在前台请求形成Hashtable作为参数时候要用到这个</param> 165 /// <param name="sql"></param> 166 /// <param name="paras"></param> 167 private void PreSearchParameter(NameValueCollection nv, out string sql, out SqlParameter[] paras) 168 { 169 sql = " '1'='1' and IsDel=0"; 170 List<SqlParameter> list = new List<SqlParameter>(); 171 if (!string.IsNullOrEmpty(nv["UName"])) 172 { 173 sql += " and UName like @UName"; 174 list.Add(new SqlParameter("@UName", "%" + nv["UName"] + "%")); 175 } 176 177 int tAge; 178 if (int.TryParse(nv["UAge"],out tAge)) 179 { 180 sql += " and UAge=" + nv["UAge"]; 181 } 182 paras = list.ToArray(); 183 } 184 185 #endregion 186 } 187 }
2、然后在业务逻辑层,做一些逻辑处理(JSON格式转换、添加预设值)
1 using Dedeyi.ZSF.DAL; 2 using Dedeyi.ZSF.Model; 3 using Dedeyi.Common; 4 using System; 5 using System.Collections.Specialized; 6 7 namespace Dedeyi.ZSF.BLL 8 { 9 public class UserInfoBLL 10 { 11 UserInfoDAL dal=new UserInfoDAL(); 12 13 /// <summary> 14 /// 添加 15 /// </summary> 16 /// <param name="user"></param> 17 /// <returns></returns> 18 public int Add(UserInfo user) 19 { 20 user.AddDate = DateTime.Now; 21 user.IsDel = false; 22 23 return dal.Add(user); 24 } 25 26 /// <summary> 27 /// 删除用户 28 /// </summary> 29 /// <param name="keyid"></param> 30 public void Del(int keyid) 31 { 32 dal.Del(keyid); 33 } 34 35 ///<summary> 36 ///更新一条数据 37 ///</summary> 38 public bool Update(Dedeyi.ZSF.Model.UserInfo model) 39 { 40 return dal.Update(model); 41 } 42 43 //分页相关的 44 #region 45 /// <summary> 46 /// 获取条件查询数据行数 47 /// </summary> 48 /// <param name="ht">关键字,UName,UAge,在前台请求形成Hashtable作为参数时候要用到这个</param> 49 /// <returns>数据行数</returns> 50 public int GetSearchCount(NameValueCollection ht) 51 { 52 return dal.GetSearchCount(ht); 53 } 54 55 /// <summary> 56 /// 获取条件查询的分页数据 57 /// </summary> 58 /// <param name="index"></param> 59 /// <param name="size"></param> 60 /// <param name="ht">关键字,UName,UAge,在前台请求形成Hashtable作为参数时候要用到这个</param> 61 /// <returns>json格式的数据集</returns> 62 public string GetSearchPage(int index, int size,NameValueCollection ht) 63 { 64 return JSONHelper.DataTableToJson(dal.GetSearchPage(index,size,ht)); 65 } 66 67 #endregion 68 69 } 70 }
3、界面层的一般处理程序,处理一般请求
1 using System.Web; 2 using Dedeyi.Common; 3 using Dedeyi.ZSF.Model; 4 using Dedeyi.ZSF.BLL; 5 using System; 6 7 namespace WebApp.Handler 8 { 9 /// <summary> 10 /// UserHandler 的摘要说明 11 /// </summary> 12 public class UserHandler : IHttpHandler,System.Web.SessionState.IRequiresSessionState 13 { 14 private HttpContext context; 15 private UserInfoBLL bll =new UserInfoBLL(); 16 17 public void ProcessRequest(HttpContext context) 18 { 19 context.Response.ContentType = "text/plain"; 20 21 //权限检查 22 // 23 try 24 { 25 string sType = context.Request["reqTypes"]; 26 if (string.IsNullOrEmpty(sType)) 27 { 28 context.Response.Write("参数错误"); 29 return; 30 } 31 this.context = context; 32 33 switch (sType.ToLower()) 34 { 35 case "add": 36 Add(); 37 break; 38 case "del": 39 Del(); 40 break; 41 case "update": 42 Update(); 43 break; 44 case "search": 45 Search(); 46 break; 47 48 } 49 } 50 catch (Exception ex) 51 { 52 context.Response.Write(new ReqMsg(false,ex.Message.ToString())); 53 } 54 } 55 /// <summary> 56 /// 获取用户ID 57 /// </summary> 58 /// <returns></returns> 59 private int GetUserID() 60 { 61 string s = context.Request["uid"]; 62 return StringHelper.GetInt(s); 63 } 64 65 /// <summary> 66 /// 添加方法 67 /// </summary> 68 private void Add() 69 { 70 UserInfo user=new UserInfo(); 71 int n= RequestHelper.FormToModel<UserInfo>(user,context.Request.Form); 72 ReqMsg msg = new ReqMsg(); 73 74 msg.Success=n>2?bll.Add(user)>0:false; 75 76 context.Response.Write(msg.ToString()); 77 78 } 79 80 /// <summary> 81 /// 更新 82 /// </summary> 83 private void Update() 84 { 85 UserInfo user = new UserInfo(); 86 int n = RequestHelper.FormToModel<UserInfo>(user, context.Request.Form); 87 ReqMsg msg = new ReqMsg(); 88 89 msg.Success = n > 2 ? bll.Update(user) : false; 90 91 context.Response.Write(msg.ToString()); 92 } 93 94 /// <summary> 95 /// 删除 96 /// </summary> 97 private void Del() 98 { 99 int i = GetUserID(); 100 bll.Del(i); 101 ReqMsg msg = new ReqMsg(true, "ok"); 102 context.Response.Write(msg.ToString()); 103 } 104 /// <summary> 105 /// 查询 106 /// </summary> 107 private void Search() 108 { 109 int index = StringHelper.GetInt(context.Request["page"], 1); 110 int page = StringHelper.GetInt(context.Request["rows"], 10); 111 112 string s = bll.GetSearchPage(index,page,context.Request.Form); 113 int t = bll.GetSearchCount(context.Request.Form); 114 115 context.Response.Write(RequestHelper.ResponseGridJSON(s,t)); 116 } 117 118 public bool IsReusable 119 { 120 get 121 { 122 return false; 123 } 124 } 125 } 126 }
三、EasyUI前台展示
前台方法主要是AJAX处理增删查改请求,创建工具菜单(可能工具权限显示部分但此次不考虑),
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApp.Default" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 5 <html xmlns="http://www.w3.org/1999/xhtml"> 6 <head runat="server"> 7 <title></title> 8 <link href="Scripts/EasyUI/themes/icon.css" rel="stylesheet" type="text/css" /> 9 <link href="Scripts/EasyUI/themes/default/easyui.css" rel="stylesheet" type="text/css" /> 10 <script src="Scripts/EasyUI/jquery-1.8.0.min.js" type="text/javascript"></script> 11 <script src="Scripts/EasyUI/jquery.easyui.min.js" type="text/javascript"></script> 12 <script src="Scripts/EasyUI/easyui-lang-zh_CN.js" type="text/javascript"></script> 13 <script src="Scripts/Common.js" type="text/javascript"></script> 14 15 <script type="text/javascript"> 16 var actionURL="handler/UserHandler.ashx"; 17 var CRUD = 18 { 19 Init: function () { 20 $('#dataTB').datagrid( 21 { 22 title: '用户列表', 23 iconCls: 'icon-reload', 24 800, 25 //height: size.height, 26 nowrap: false, 27 collapsible: false, 28 url: actionURL, 29 loadMsg: '正在加载……', 30 singleSelect: true, 31 striped: true, 32 pagesize: 10, 33 pagination: true, 34 queryParams: convertArray($('#fmSearch').serializeArray()), 35 toolbar: CreateToolBar(), 36 37 columns: [[ 38 { title: '编号', field: 'UserID', 80, align: 'center' }, 39 { title: '卡号', field: 'CardID', 100, align: 'center' }, 40 { title: '姓名', field: 'UName', 160, align: 'center' }, 41 { title: '密码', field: 'UPwd', 160, align: 'center' }, 42 { title: '年龄', field: 'UAge', 50, align: 'center' }, 43 { title: '添加时间', field: 'AddDate', 150, 44 formatter: function (val, rec) { 45 return ChangeDateFormat(val); 46 } 47 48 } 49 ]] 50 }); 51 }, 52 Add: function () { 53 $('#dialogAdd').dialog('open'); 54 $('#txt_editType').val('add'); //标示为添加 55 }, 56 Del: function () { 57 var r = $('#dataTB').datagrid('getSelected'); 58 if (r) { 59 $.messager.confirm('删除提示', '你确认删除这一条数据吗?', function (d) { 60 if (d) { 61 $.post(actionURL, { "reqTypes": "del", "uid": r["UserID"] }, function (d) { 62 var res = $.parseJSON(d); 63 if (res.Success) { 64 $.messager.show( 65 { 66 title: '系统提示', 67 msg: '删除成功!', 68 timeout: 1500 69 }); 70 $('#dataTB').datagrid('reload', convertArray($('#fmSearch').serializeArray())); 71 } else { 72 $.messager.alert('错误', res.Msg); 73 } 74 }); 75 } 76 }); 77 } else { 78 $.messager.alert('提示', '请选择一行数据!'); 79 } 80 81 }, 82 Update: function () { 83 var r = $('#dataTB').datagrid('getSelected'); 84 if (r == null) { $.messager.alert('提示', '请选择一行数据'); return; }; 85 $('#dialogAdd').dialog('open'); 86 $('#fmAdd').form('load', r); 87 $('#txt_editType').val('update'); 88 } 89 }; 90 91 function InitForm() { 92 $('#dialogAdd').dialog( 93 { 94 closed: true, 95 title:'添加用户', 96 300, 97 height:300 98 }); 99 } 100 101 function CreateToolBar() { 102 var a = []; 103 var isReflesh = true; 104 var isAdd = true; 105 var isDel = true; 106 var isUpdate = true; 107 if (isReflesh) { 108 a.push({ 109 text: '刷新', 110 iconCls: 'icon-reload', 111 handler: function () { 112 113 CRUD.Init(); 114 } 115 }); 116 117 a.push('-'); 118 119 } 120 121 if (isAdd) { 122 a.push({ 123 text: '添加', 124 iconCls: 'icon-add', 125 handler: function () { 126 CRUD.Add(); 127 } 128 }); 129 130 a.push('-'); 131 } 132 133 if (isUpdate) { 134 a.push({ 135 text: '编辑', 136 iconCls: 'icon-edit', 137 handler: function () { 138 CRUD.Update(); 139 } 140 }); 141 142 a.push('-'); 143 } 144 145 if (isDel) { 146 a.push({ 147 text: '删除', 148 iconCls: 'icon-cut', 149 handler: function () { 150 151 CRUD.Del(); 152 } 153 }); 154 155 a.push('-'); 156 } 157 return a; 158 } 159 </script> 160 <script type="text/javascript"> 161 162 $(function () { 163 164 CRUD.Init(); 165 166 InitForm(); 167 168 //查询事件 169 $('#a_search').click(function () { 170 $('#dataTB').datagrid('reload', convertArray($('#fmSearch').serializeArray())); 171 172 }); 173 //确定添加 174 $('#a_AddOK').click(function () { 175 if ($('#fmAdd').form('validate')) { 176 var send = convertArray($("#fmAdd").serializeArray()); 177 $.post(actionURL, send, function (d) { 178 $('#dataTB').datagrid('reload', convertArray($('#fmSearch').serializeArray())); 179 var res = $.parseJSON(d); 180 if (res.Success) { 181 $.messager.alert('提示', '操作成功'); 182 $('#fmAdd').form('clear'); 183 } else { 184 $.messager.alert('错误', res.Msg); 185 } 186 }); 187 } 188 189 }); 190 191 //取消 192 $('#a_AddCancle').click(function () { 193 $('#fmAdd').form('clear'); 194 $('#dialogAdd').dialog('close'); 195 196 }) 197 198 }); 199 </script> 200 201 </head> 202 <body> 203 <div id="dialogAdd" > 204 <form id="fmAdd" style="text-align:center;"> 205 <br /><br /> 206 <input type="hidden" name="reqTypes" id="txt_editType" /> 207 <input type="hidden" name="UserID" id="txt_editID"/> 208 用户名<input type="text" name="UName" required="true" class="easyui-validatebox" /><br /><br /> 209 卡号<input type="text" name="CardID" /><br /><br /> 210 年龄<input type="text" name="UAge" /><br /><br /> 211 密码<input type="text" name="UPwd" /><br /><br /> 212 <a class="easyui-linkbutton" id="a_AddOK">确定</a> 213 <a class="easyui-linkbutton" id="a_AddCancle">取消</a> 214 </form> 215 </div> 216 <div> 217 <form id="fmSearch"> 218 <input type="hidden" name="reqTypes" value="search" /> 219 用户名<input type="text" name="UName" /> 220 年龄<input type="text" name="UAge" /> 221 <a class="easyui-linkbutton" id="a_search">查询</a> 222 </form> 223 </div> 224 <table id="dataTB"></table> 225 </body> 226 </html>
最终显示效果如图:
JS帮助函数:
1 function ChangeShortDateFormat(cellval) { 2 if (!cellval) return ''; 3 var date = new Date(parseInt(cellval.replace("/Date(", "").replace(")/", ""), 10)); 4 var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; 5 var currentDate = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); 6 var hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); 7 var minu = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); 8 var sec = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds(); 9 10 return date.getFullYear() + "-" + month + "-" + currentDate; //+ " " + hour + ":" + minu + ":" + sec; 11 12 } 13 14 //表单序列化有转JSON格式 15 function convertArray(o) { 16 var v = {}; 17 for (var i in o) { 18 if (o[i].name != '__VIEWSTATE') { 19 if (typeof (v[o[i].name]) == 'undefined') 20 v[o[i].name] = o[i].value; 21 else 22 v[o[i].name] += "," + o[i].value; 23 } 24 } 25 return v; 26 }
********谢谢支持,感谢批评建议,努力学习中******************************
Demo 的 下载链接