上节课我们讲述了NVelocity的简单应用,但是没有和数据库打交道,这次我们来和数据库连接实现人员的增删改查。
1. 上篇博客回顾
链接:http://blog.csdn.net/u010955843/article/details/42528761
开讲之前,我们先来回顾上一节课讲的内容,主要是两个页面,一个是一般处理程序的页面,另一个是渲染后的模板。
? 机制
上篇博客中我们建立一个person类,并且在一般处理程序中对其进行了赋值,之后交给了模板(html)进行数据填充,渲染成html页,之后生成的纯html文本返回给一般处理程序将,一般处理程序将其返回给浏览器进行解析,并且显示。
? 好处
实现了数据和逻辑和界面的分离:数据给了模板(一般由html担当),最后一般处理程序拿到渲染html进行输出;模板不管数据来源,只是知道表格中需要设置几行几列;一般处理程序只是取数据,传给模板,不管模板会把数据渲染成什么样子的,也就是各自只是负责自己的那一块就可以了
2. 与数据库连接实现人员增删改查
上节课我们只是在一般处理程序中写的数据源对象,那么在传统web开发NVelocity如何数据库进行交互的呢,我们先来介绍程序编写的步骤。
? 建立数据库并且建表
可以自己定,我们的库为CRUDTest,表明为Persons
设置Id为自增的,我们可以手动输入几条记录
? CommonHelper
和上次一样,我们首先下载NVelocity的DLL,之后将其添加到建立的相应项目下,直接拖进项目下面即可,之后添加对它的引用即可。
上次我们是将模板写在一个一般处理程序中,但是我们知道这样的只是适用一个或者少数的处理程序,要是想要达到模板的复用或者方便的使用,我们可以将其进行封装,放到一个类中即可,这样实现了方法的复用。
我们知道这里只是有两个参数不一样,即将渲染的模板,另一个是将要填充模板的文件或者数据。
具体代码如下:
<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity; using NVelocity.App; using NVelocity.Runtime; using System; using System.Collections.Generic; using System.Linq; using System.Web; //using NVelocity;using NVelocity.App;using NVelocity.Runtime;必须引入的 //这个类用于封装Nvelocity模板的渲染 namespace yinqingmuban { public class commonHelper { /// <summary> /// 用data数据填充templateName模板,渲染生成html返回 /// </summary> /// <param name="templateName">模板名字</param> /// <param name="data">填充模板数据</param> /// <returns></returns> public static string RenderHtml(string templateName, object data) { VelocityEngine vltEngine = new VelocityEngine(); vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file"); vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹,我们遵从上次讲的我们还是放在templates这个文件夹中,自己也可以新建别的名字的 vltEngine.Init(); //引擎初始化 VelocityContext vltContext = new VelocityContext(); vltContext.Put("Data", data);//设置参数,在模板中可以通过$data来引用 Template vltTemplate = vltEngine.GetTemplate(templateName);//渲染的html模板 System.IO.StringWriter vltWriter = new System.IO.StringWriter(); vltTemplate.Merge(vltContext, vltWriter); string html = vltWriter.GetStringBuilder().ToString(); return html; } } }</span></strong>
? Sqlhelper
相信大家都学过三层,这里不再做过多的介绍。封装了一系列的增删改查的方法,并且建立了数据库的里连接。这里不再展示了
? 配置文件
用于配置连接数据库的字符串,这样便于我们灵活更换数据库,而不用于更改代码内部。
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><connectionStrings> <add name="conStr" connectionString="data source=.;database=CRUDTest;uid=sa;pwd=123456;"/> </connectionStrings></span></strong>
? 人员显示的一般处理程序(personlist.ashx)
这里主要是读取数据,然后把它渲染到html页上进行输出。
<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; namespace yinqingmuban { /// <summary> /// personlist 的摘要说明 /// </summary> public class personlist : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //context.Response.Write("Hello World"); DataTable dt = sqlHelper.ExecuteDataTable("select * from Persons"); //DataTable不是集合,所以无法foreach遍历,DataTable的Rows属性 //代表表格中的数据行的集合(DataRow的集合),一般传递DataRowCollection //给模板方便遍历 string html = commonHelper.RenderHtml("personlist.html", dt.Rows); context.Response.Write(html); } public bool IsReusable { get { return false; } } } }</span></strong>
? 建立人员列表的渲染模板(personlist.html)
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <!-- 人员的操作处理,增删改查 --> <a href="personEdit.ashx?Action=AddNew">新增人员</a> <!--//变量data中的每一行,并且输入每一行中的每一列的字段值--> <table> <thead> <tr><td>删除</td><td>编辑</td><td>姓名</td><td>年龄</td><td>邮箱</td></tr> </thead> <tbody> #foreach($person in $Data) <tr><td><a href="personEdit.ashx?Action=Delete&Id=$person.Id">删除</a></td><td><a href="personEdit.ashx?Action=Edit&Id=$person.Id">编辑</a></td><td>$person.Name</td><td>$person.Age</td><td>$person.Email</td></tr> #end </tbody> </table> </body> </html> </span></strong>
? 对列表进行增删改(personEdit.ashx)
<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.SqlClient; using System.Data; namespace yinqingmuban { /// <summary> /// personEdit 的摘要说明 /// </summary> public class personEdit : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //PersonEdit.ashx?action=AddNew //PersonEdit.ashx?action=Edit&Id=3 string action = context.Request["action"]; if (action == "AddNew") { //判断是否含有Save并且等于true,如果是的话就说明是点击【保存】按钮请求来的 bool save = Convert.ToBoolean(context.Request["Save"]); if (save)//是保存 { string name = context.Request["Name"]; int age = Convert.ToInt32(context.Request["Age"]); string email = context.Request["Email"]; sqlHelper.ExecuteNonQuery("Insert into Persons(Name,Age,Email) values(@Name,@Age,@Email)", new SqlParameter("@Name", name) , new SqlParameter("@Age", age) , new SqlParameter("@Email", email)); context.Response.Redirect("personlist.ashx");//保存成功返回列表页面 } else { //string html = CommonHelper.RenderHtml("PersonEdit.htm", new { Name = "", Age = 20, Email = "@rupeng.com" }); //定义匿名对象 Action可能与数据库中字段重复,建议分开,相关和无关的字段;New一个匿名类型,等于在一个匿名类中又创建一个匿名类, var data = new { Action = "AddNew", Person = new { Name = "", Age = 20, Email = "@rupeng.com" } }; //进行渲染 string html = commonHelper.RenderHtml("personEdit.html", data); context.Response.Write(html); } } else if (action == "Edit") { //判断是否含有Save并且等于True,如果是的话说明点击了保存按钮 bool save = Convert.ToBoolean(context.Request["Save"]); if (save) { //所有的信息服务器端尽量不要记,尽量通过客户端传递 //服务器是一个健忘症(无状态),服务器只认识Request中的信息 long id = Convert.ToInt64(context.Request["Id"]); string name = context.Request["Name"]; int age = Convert.ToInt32(context.Request["Age"]); string email = context.Request["Email"]; sqlHelper.ExecuteNonQuery("update Persons set [email protected],[email protected],[email protected] where [email protected]", new SqlParameter("@Id", id), new SqlParameter("@Name", name), new SqlParameter("@Age", age), new SqlParameter("@Email", email)); context.Response.Redirect("personlist.ashx"); } else { long id = Convert.ToInt64(context.Request["Id"]); DataTable dt = sqlHelper.ExecuteDataTable("select * from Persons where [email protected]", new SqlParameter("@Id", id)); if (dt.Rows.Count <= 0) { context.Response.Write("没有找到Id=" + id + "的数据"); } else if (dt.Rows.Count > 1) { context.Response.Write("找到多条Id=" + id + "的数据"); } else { DataRow row = dt.Rows[0]; var data = new { Action = "Edit", Person = row }; string html = commonHelper.RenderHtml("personEdit.html", data); context.Response.Write(html); } } } else if (action == "Delete") { long id = Convert.ToInt64(context.Request["Id"]); sqlHelper.ExecuteNonQuery("delete from Persons where [email protected]", new SqlParameter("@Id",id)); context.Response.Redirect("personlist.ashx"); } else { context.Response.Write("Action参数错误!"); } } public bool IsReusable { get { return false; } } } }</span></strong>
? 建立人员增删改的渲染模板(personEdit.html)
<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title> #if($Data.Action=="AddNew") 新增用户 #else 编辑用户$Data.Person.Name #end </title> </head> <body> <form action="personEdit.ashx" method="post"> <!--<input type="hidden" name="Action" value="AddNew" />--> <input type="hidden" name="Action" value="$Data.Action" /> <input type="hidden" name="Save" value="true" /> #if($Data.Action=="Edit") <input type="hidden" name="Id" value="$Data.Person.Id" /> #end <table style="background-color:blueviolet"> <tr><td>姓名:</td><td><input type="text" name="Name" value="$Data.Person.Name" /></td></tr> <tr><td>年龄:</td><td><input type="text" name="Age" value="$Data.Person.Age" /></td></tr> <tr><td>邮箱:</td><td><input type="text" name="Email" value="$Data.Person.Email" /></td></tr> <tr><td></td><td><input type="submit" value="保存" /></td></tr> </table> </form> </body> </html> </span></strong>
? 效果
列表显示
点击新增人员
点击编辑
通过隐藏字段来实现想要的结果,在实现增删改的页面我们用了隐藏字段,隐藏字段是服务器端控件,这样我们在服务器端可以通过隐藏字段的name来获得其相应的值,主要是因为关于一些操作这些是不要用户可以看到的,只是程序需要看到,故而做成了隐藏字段。
至此我们就实现与数据库的交互,出现的效果自己可以写写代码看一下啊。
3. 总结
这样总算完美了,不然总是觉得少了些什么,自己最近时间紧,一直没有写这篇与数据库交互的博客,在mvc中同样存在一个引擎Razor,我们称之为视图引擎,希望在这篇博客的基础能够激起你对引擎探究的好奇心,自己去看看和研究吧,相信你会感兴趣的。