三层架构

前段时间公司要求修改一个网站,打开后我疯了,一层没有都是调用的DB接口,遍地的SQL语句,非常杂乱。

什么是三层架构?

三层架构是将整个项目划分为三个层次:表现层、业务逻辑层、数据访问层。目的为了高内聚低耦合思想。

三层结构

表现层(UI):接受用户请求,数据的返回呈现。

业务逻辑层(BLL ):用来处理业务逻辑,处理用户提交的数据。

数据访问层(DAL):用来与数据库进行交互,处理增、删、改、差。

实体类对象(Model):用来存储实体类。

三层关系

UI表现层:接收用户输入的数据,并传递给业务逻辑层。

BLL业务逻辑层:把接收到的数据传递给数据访问层,并返回结果给UI层。

DAL数据访问层:负责与数据库进行交互,并将结果返回给BLL层。

什么时候需要分层?

当项目过大的时候可以分层开发,这样可以每个人负责的不同,共同进行开发。如果一个项目非常小的话,独立开发可以不分层。

操作步骤:

1、创建结构

新增三个类库分别是:BLL、DAL、Model,并建立一个UI层(winform 或 webform 或 MVC项目)设置启动项为UI层。

这里随个人喜欢可以再加一个Common层,负责处理其他常用方法。

2、引用关系

DAL要用到Model,BLL要用到DAL、CL和Model,UI要用到BLL、Model和CL。相互引用即可。

实现登陆

登陆是所有系统的入口,相信大家一般都用session,本例使用FormsAuthentication微软提供的身份认证,存储在cookie中。

假设有如下管理员表:

mif_id:唯一标识,lever等级,usernmae,psw账号密码,trueName姓名,createTime创建日期,isLock是否锁定,Power权限。

编写实体类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Model
  7. {
  8. /// <summary>
  9. /// 管理员实体类
  10. /// </summary>
  11. public class ManagerInfo
  12. {
  13. /// <summary>
  14. /// 标识ID
  15. /// </summary>
  16. public int mif_id { get; set; }
  17. /// <summary>
  18. /// 暂时没用
  19. /// </summary>
  20. public int mif_pid { get; set; }
  21. /// <summary>
  22. /// 管理员等级
  23. /// </summary>
  24. public int mif_lever { get; set; }
  25. /// <summary>
  26. /// 账号
  27. /// </summary>
  28. public string mif_userName { get; set; }
  29. /// <summary>
  30. /// 密码
  31. /// </summary>
  32. public string mif_psw { get; set; }
  33. /// <summary>
  34. /// 姓名
  35. /// </summary>
  36. public string mif_trueName { get; set; }
  37. /// <summary>
  38. /// 创建时间
  39. /// </summary>
  40. public DateTime mif_createTime { get; set; }
  41. /// <summary>
  42. /// 是否锁定
  43. /// </summary>
  44. public bool mif_isLock { get; set; }
  45. /// <summary>
  46. /// 权限
  47. /// </summary>
  48. public string mif_power { get; set; }
  49. }
  50. }

ManagerInfo.cs

习惯性编写完Model重新生成下Model层,检查是否有错误。

编写数据访问层

引入sqlHelper文件(上一文章中找),修改UI中的web.config添加数据库连接字符串,并在sqlHelper中修改相关名称,注意引入System.configuration.dll。

编写操作ManagerInfo的数据访问类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Model;
  6. using System.Data.SqlClient;
  7.  
  8. namespace DAL
  9. {
  10. /// <summary>
  11. /// 管理员数据访问类
  12. /// </summary>
  13. public class ManagerInfoDal
  14. {
  15. /// <summary>
  16. /// 通过账号查找
  17. /// </summary>
  18. /// <param name="userName"></param>
  19. /// <returns></returns>
  20. public static ManagerInfo row(string userName)
  21. {
  22. string sql = "select mif_id,mif_lever,mif_userName,mif_psw,mif_trueName,mif_createTime,mif_isLock from managerInfo where mif_userName = @uid";
  23. var v = new ManagerInfo();
  24. using (var dr = SQLHelper.ExecuteReader(sql, new SqlParameter("@uid", userName)))
  25. {
  26. if (dr.Read())
  27. {
  28. v.mif_id = Convert.ToInt32(dr["mif_id"]);
  29. v.mif_lever = Convert.ToInt32(dr["mif_lever"]);
  30. v.mif_userName = dr["mif_userName"].ToString();
  31. v.mif_psw = dr["mif_psw"].ToString();
  32. v.mif_trueName = dr["mif_trueName"].ToString();
  33. v.mif_createTime = Convert.ToDateTime(dr["mif_createTime"]);
  34. v.mif_isLock = Convert.ToBoolean(dr["mif_isLock"]);
  35. }
  36. }
  37. return v;
  38. }
  39. }
  40. }

ManagerInfoDal.cs

编写业务逻辑层

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using DAL;
  6. using System.Web.Security;
  7. using System.Web;
  8. using CL;
  9. using Model;
  10.  
  11. namespace BLL
  12. {
  13. /// <summary>
  14. /// 管理员
  15. /// </summary>
  16. public class ManagerInfoBll
  17. {
  18. /// <summary>
  19. /// 登陆
  20. /// </summary>
  21. /// <param name="userName"></param>
  22. /// <param name="passWord"></param>
  23. /// <param name="remember">是否记住</param>
  24. /// <returns></returns>
  25. public static string login(string userName, string passWord, string remember)
  26. {
  27. var v = ManagerInfoDal.row(userName);
  28. if (v.mif_id > )
  29. {
  30. if (v.mif_isLock == false)
  31. {
  32. if (v.mif_psw.Equals(createMD5.getMD5(passWord)))
  33. {
  34. var expires = DateTime.Now.AddMinutes();
  35. if (remember.Equals("on"))
  36. {
  37. expires = DateTime.Now.AddDays();
  38. }
  39. //将登陆的用户存储在Ticket中
  40. var ticket = new FormsAuthenticationTicket(, userName, DateTime.Now, expires, true, userName);
  41. //使用Encrypt方法加密Ticket,并存储在cookie中
  42. var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
  43. //防止浏览器攻击窃取、伪造cookie信息
  44. cookie.HttpOnly = true;
  45. cookie.Expires = expires;
  46. HttpContext.Current.Response.Cookies.Add(cookie);
  47. return "";
  48. }
  49. return "";
  50. }
  51. return "";
  52. }
  53. return "";
  54. }
  55. public static ManagerInfo row(string userName)
  56. {
  57. return ManagerInfoDal.row(userName);
  58. }
  59. /// <summary>
  60. /// 查询权限(通过数字查询名字)
  61. /// </summary>
  62. /// <param name="userRole">权限数字</param>
  63. /// <returns></returns>
  64. public static string getRole(int userRole)
  65. {
  66. switch (userRole)
  67. {
  68. case :
  69. return "编辑";
  70. case :
  71. return "管理员";
  72. case :
  73. return "系统";
  74. default:
  75. return "暂无";
  76. }
  77. }
  78. }
  79. }

ManagerInfoBll.cs

管理员等级这里建议写成枚举,本人较懒。

FormsAuthenticationTicket这个东西比传统的session和cookie的好处就是 可以任意目录设置他的访问权限,如果没有登陆直接跳出到登陆页面。而不用每个页面一开始都认证一番~

还有 cookie.HttpOnly 在使用cookie时这一项最好设置一下,否则可能会客户端模拟cookie进行攻击。

编写通用层

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Cryptography;
  5. using System.Text;
  6.  
  7. namespace CL
  8. {
  9. public class createMD5
  10. {
  11. public static string getMD5(string str)
  12. {
  13. var md5 = MD5.Create();
  14. var buffer = Encoding.Default.GetBytes(str);
  15. var mdbuffer = md5.ComputeHash(buffer);
  16. StringBuilder result = new StringBuilder();
  17. for (int i = ; i < mdbuffer.Length; i++)
  18. {
  19. result.Append(mdbuffer[i].ToString("x2"));
  20. }
  21. return result.ToString();
  22. }
  23. }
  24. }

createMD5

生成MD5的代码,可不用。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Web;
  10.  
  11. namespace CL
  12. {
  13. public static class createVlidate
  14. {
  15. /// <summary>
  16. /// 字符
  17. /// </summary>
  18. /// <param name="len">几位</param>
  19. /// <returns></returns>
  20. public static string validation(int cd)
  21. {
  22. var ran = new Random();
  23. int num, tem;
  24. string rtuStr = "";
  25. for (int i = ; i < cd; i++)
  26. {
  27. num = ran.Next();
  28. if (i % == )
  29. tem = num % + ''; //数字
  30. else
  31. tem = num % + 'A'; //字母
  32. rtuStr += Convert.ToChar(tem).ToString();
  33. }
  34. //写入cookie
  35. HttpCookie cookie = new HttpCookie("check");
  36. cookie.Value = rtuStr.ToLower();
  37. HttpContext.Current.Response.Cookies.Add(cookie);
  38. return rtuStr;
  39. }
  40.  
  41. /// <summary>
  42. /// 生成图像
  43. /// </summary>
  44. /// <param name="check">字符</param>
  45. public static byte[] drawImg(string check)
  46. {
  47. Bitmap img = new Bitmap(, );
  48. var ht = Graphics.FromImage(img);
  49. ht.Clear(Color.White);
  50. ht.DrawLine(new Pen(Color.SpringGreen), , , , );
  51. Font font = new Font("微软雅黑", , FontStyle.Bold);
  52. var jianbian = new LinearGradientBrush(new Rectangle(, , img.Width, img.Height), Color.Teal, Color.Snow, 2f, true);
  53. ht.DrawString(check, font, jianbian, , );
  54. ht.DrawRectangle(new Pen(Color.Aqua), , , img.Width - , img.Height - );
  55. MemoryStream ms = new MemoryStream();
  56. img.Save(ms, ImageFormat.Jpeg);
  57. ht.Dispose();
  58. img.Dispose();
  59. return ms.ToArray();
  60. }
  61. }
  62. }

createValidate.cs

生成验证码的,可自己写。

编写展现层

首先需要在web.config中设置authentication节点为Forms验证模式,然后就可以在目录中任意设置访问级别了。

  1. <authentication mode="Forms">
  2. <forms loginUrl="~/manage/index.html" timeout="" defaultUrl="~/manage/Net/" />
  3. </authentication>

登陆页面代码

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" />
  6. <meta http-equiv="X-UA-Compatible" content="IE=9" />
  7. <meta name="viewport" content="width=device-width, initial-scale=1">
  8. <title>汉之殇管理系统</title>
  9. <link href="css/bootstrap.css" rel="stylesheet" />
  10. <link href="css/admin.css" rel="stylesheet" />
  11. <!--[if lt IE 9]>
  12. <script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
  13. <script src="http://apps.bdimg.com/libs/respond.js/1.4.2/respond.min.js"></script>
  14. <![endif]-->
  15. </head>
  16. <body class="login">
  17. <nav class="navbar navbar-default navbar-static-top">
  18. <div class="container">
  19. <div class="navbar-header">
  20. <a href="login.html" class="navbar-brand">汉之殇管理系统</a>
  21. </div>
  22. </div>
  23. </nav>
  24. <div class="container">
  25. <div class="panel panel-default">
  26. <div class="panel-body">
  27. <div id="ts"></div>
  28. <h4 class="page-header">登陆</h4>
  29. <div class="form-group has-feedback">
  30. <label class="sr-only" for="userName">账号</label>
  31. <input type="text" id="userName" class="form-control" placeholder="账号" maxlength="50" autofocus />
  32. <span class="glyphicon glyphicon-user form-control-feedback" aria-hidden="true"></span>
  33. </div>
  34. <div class="form-group has-feedback">
  35. <label class="sr-only" for="passWord">密码</label>
  36. <input type="password" id="passWord" class="form-control" maxlength="50" placeholder="密码" />
  37. <span class="glyphicon glyphicon-lock form-control-feedback" aria-hidden="true"></span>
  38. </div>
  39. <div class="form-group has-feedback">
  40. <label class="sr-only" for="validateCode">验证码</label>
  41. <input type="text" id="validateCode" class="form-control validateCode" placeholder="验证码" maxlength="4" />
  42. <img src="checkLogin/ValidateCode.ashx" id="img" onclick="changeCode()" class="validateImg">
  43. <a href="javascript:changeCode()">看不清,换一张</a>
  44. </div>
  45. <div class="form-group">
  46. <input type="checkbox" id="remember" checked="checked" /> <span class="form-control-static">记住我 </span>
  47. <button id="submit" type="button" class="btn btn-primary col-xs-offset-4" style="width:40%">登录</button>
  48. </div>
  49. </div>
  50. </div>
  51. </div>
  52. <nav class="navbar navbar-default navbar-fixed-bottom">
  53. <div class="container">
  54. <div class="navbar-header">
  55. <p class="navbar-text">&copy; 2015 汉之殇 版权所有</p>
  56. </div>
  57. </div>
  58. </nav>
  59. <script src="js/jquery-1.7.2.min.js"></script>
  60. <script src="js/status.js"></script>
  61. <script src="js/login.js"></script>
  62. </body>
  63. </html>

index.html

验证码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using CL;
  6.  
  7. namespace UI.manage.checkLogin
  8. {
  9. /// <summary>
  10. /// ValidateCode 的摘要说明
  11. /// </summary>
  12. public class ValidateCode : IHttpHandler
  13. {
  14. public void ProcessRequest(HttpContext context)
  15. {
  16. context.Response.ContentType = "image/jpeg";
  17.  
  18. var check = createVlidate.validation();
  19. byte[] buffer = createVlidate.drawImg(check);
  20.  
  21. context.Response.BinaryWrite(buffer);
  22. }
  23.  
  24. public bool IsReusable
  25. {
  26. get
  27. {
  28. return false;
  29. }
  30. }
  31. }
  32. }

ValidateCode.ashx

登陆用的JS

  1. $(function () {
  2. $.get("checkLogin/Validate.ashx?rand=" + Math.random(0, 1), function (data) {
  3. if (data == "0") {
  4. location.href="/manage/Net/"
  5. }
  6. });
  7.  
  8. if (top.location != self.location) {
  9. top.location = self.location;
  10. }
  11.  
  12. var lj = window.location.toString();
  13. if (lj.lastIndexOf("?") != -1) {
  14. status("info", "请先登录!");
  15. $("#userName").focus();
  16. }
  17.  
  18. $(".login").height(document.documentElement.clientHeight);
  19. document.onkeydown = function (e) {
  20. var ev = document.all ? window.event : e;
  21. if (ev.keyCode == 13) {
  22. $("#submit").click();
  23. }
  24. }
  25. });
  26. $("#submit").click(function () {
  27. //$("#submit").attr("disabled", "true");
  28. var userName = $("#userName").val();
  29. var passWord = $("#passWord").val();
  30. var validateCode = $("#validateCode").val();
  31. var remember = $("#remember:checked").val();
  32. if (userName != "") {
  33. if (passWord != "") {
  34. if (validateCode != "") {
  35. if (validateCode.toLowerCase() == getCode()) {
  36. $.post("checkLogin/Validate.ashx", { userName: userName, passWord: passWord, remember: remember }, function (data) {
  37. changeCode();
  38. if (data == "0") {
  39. location.href = "Net/";
  40. } else if (data == "1") {
  41. status("no", "登陆失败,密码错误!");
  42. $("#passWord").focus();
  43. return false;
  44. } else if (data == "2") {
  45. status("no", "登陆失败,账号已被禁止登陆!");
  46. $("#userName").focus();
  47. return false;
  48. } else {
  49. status("no", "登陆失败,账号不存在!");
  50. $("#userName").focus();
  51. return false;
  52. }
  53. });
  54. return false;
  55. }
  56. status("no", "验证码不正确!");
  57. $("#validateCode").focus();
  58. return false;
  59. }
  60. status("info", "请输入验证码!");
  61. $("#validateCode").focus();
  62. return false;
  63. }
  64. status("info", "请输入您的密码!");
  65. $("#passWord").focus();
  66. return false;
  67. }
  68. status("info", "请输入您的账号!");
  69. $("#userName").focus();
  70. return false;
  71. });
  72. function changeCode() {
  73. $("#img").attr("src", $("#img").attr("src") + "?");
  74. }
  75. function getCode() {
  76. var cookies = document.cookie.split(";");
  77. for (var i = 0; i < cookies.length; i++) {
  78. var validate = cookies[i].split("=");
  79. if (validate[0].replace(/(^\s*)|(\s*$)/g, "") == "check") {
  80. return validate[1].replace(/(^\s*)|(\s*$)/g, "");
  81. }
  82. }
  83. }

login.js

验证的一般处理程序

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5.  
  6. namespace UI.manage.checkLogin
  7. {
  8. /// <summary>
  9. /// Validate 的摘要说明
  10. /// </summary>
  11. public class Validate : IHttpHandler
  12. {
  13.  
  14. public void ProcessRequest(HttpContext context)
  15. {
  16. var userName = context.Request["userName"];
  17. var passWord = context.Request["passWord"];
  18. var remember = context.Request["remember"] == null ? "" : context.Request["remember"];
  19. if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(passWord))
  20. {
  21. var result = BLL.ManagerInfoBll.login(userName, passWord, remember);
  22. context.Response.Write(result);
  23. }
  24. else
  25. {
  26. if (context.Request.IsAuthenticated)
  27. {
  28. context.Response.Write("");
  29. }
  30. }
  31. }
  32.  
  33. public bool IsReusable
  34. {
  35. get
  36. {
  37. return false;
  38. }
  39. }
  40. }
  41. }

Validate.ashx

最后附上效果图如下:

登陆后使用 Page.User.Identity.Name 获取用户标识。

如下:

获取信息及退出登陆如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Security;
  6. using System.Web.UI;
  7. using System.Web.UI.WebControls;
  8. using BLL;
  9. using Model;
  10.  
  11. namespace UI.manage.Net
  12. {
  13. public partial class _default : System.Web.UI.Page
  14. {
  15. protected void Page_Load(object sender, EventArgs e)
  16. {
  17. if (!IsPostBack)
  18. {
  19. var userName = Page.User.Identity.Name;
  20. int roleId = ManagerInfoBll.row(userName).mif_lever;
  21.  
  22. this.userId.InnerText = userName;
  23. this.userRole.InnerText = ManagerInfoBll.getRole(roleId);
  24. }
  25.  
  26. var logout = Request["logout"];
  27. if (!string.IsNullOrEmpty(logout))
  28. {
  29. FormsAuthentication.SignOut();
  30. Response.Redirect("../index.html");
  31. }
  32. }
  33. }
  34. }

default.aspx.cs

最后 在禁止匿名访问的目录下 新增一个web.config 内容如下

  1. <?xml version="1.0"?>
  2. <configuration>
  3. <system.web>
  4. <authorization>
  5. <deny users="?"/>
  6. </authorization>
  7. </system.web>
  8. </configuration>

这样,当记住凭证后直接访问登陆或者该目录都可以直接跳转,如果点击退出或过期后,则自动跳出到登陆页面中。至此大功告成~

31、三层架构、AJAX+FormsAuthentication实现登陆的更多相关文章

  1. 三层架构(MVC)实现简单登陆注册验证(含验证码)

    前言在我的上一篇微博里我已经提出了登陆的方法,当时我采取的是纯servlet方式,因为当时刚接触到servlet,正好网上没有这方面的全面讲解,所以我就发飙了.不过在现实生产中我们大多采用的三层架构. ...

  2. 三层架构下实现用户登陆C#

    上篇文章讲到三层.接下来就通过一个实例详细的看怎么用三层实现用户登陆界面. 一.Model实体(LoginModel): namespace LoginModel { //加入类:UserInfo M ...

  3. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  4. c#三层架构登陆实例

    很早之前,就听说过三层结构了.当时只知道 三层结构 是把 系统的 界面  跟 数据库操作等不相关的程序分别开来.原来这么简单的实现,确实传说中的 三层结构啊. 首先,先来看一下是哪三层.表示层(UI, ...

  5. 一、JSP九大内置对象 二、JAVAEE三层架构和MVC设计模式 三、Ajax

    一.JSP九大内置对象###<1>概念 不需要预先申明和定义,可以直接在jsp代码中直接使用 在JSP转换成Servlet之后,九大对象在Servlet中的service方法中对其进行定义 ...

  6. [转]C#三层架构登陆实例

    很早之前,就听说过三层结构了.当时只知道 三层结构 是把 系统的 界面  跟 数据库操作等不相关的程序分别开来.原来这么简单的实现,确实传说中的 三层结构啊. 首先,先来看一下是哪三层.表示层(UI, ...

  7. 简单使用Idea创建三层架构项目和数据库连接(使用原生ajax进行访问+ajax)

    Idea创建三层架构项目 首先创建一个Web项目model 创建Web完成后进行创建entity.dao.service 特别注意 根据上面的步骤进行创建即可得到 创建完成 我们首先创建数据库 cre ...

  8. 从MVC和三层架构说到SSH整合开发

    相信很多人都认同JavaWeb开发是遵从MVC开发模式的,遵从三层架构进行开发的,是的,大家都这么认同.但是相信大家都会有过这样一个疑问,if(MVC三层模式==三层架构思想)out.println( ...

  9. tornado框架&三层架构&MVC&MTV&模板语言&cookie&session

    web框架的本质其实就是socket服务端再加上业务逻辑处理, 比如像是Tornado这样的框架. 有一些框架则只包含业务逻辑处理, 例如Django, bottle, flask这些框架, 它们的使 ...

随机推荐

  1. linux下解压缩jar包

    在部署项目是需要对jar中的文件进行编辑,这就要在linux命令行下对jar进行解压缩操作. 比如有个jar包,/usr/local/EtnetChinaApplication.jar 解包到临时目录 ...

  2. oracle object_id和data_object_id的区别

    Oracle的数据字典表dba_objects包含了两个字段,object_id, data_object_id,官方文档上的解释是: object_id: Dictionary object num ...

  3. POJ_3045_Cow_Acrobats_(贪心)

    描述 http://poj.org/problem?id=3045 n头牛,每头牛都有重量w[i]和力量s[i].把这n头牛落起来,每头牛会有一个危险值,危险值是它上面所有牛的重量和减去它的力量.求危 ...

  4. Linux route命令详解和使用示例(查看和操作IP路由表)

    Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或 ...

  5. Makefile第三讲:终端传值给Makefile、Makefile传值给C++代码

    摘要 终端传值给Makefile,咋传?只需在终端输入以下命令,那么就可以在Makefile文件中放心大担的使用$(abcde)这个变量了,它的值为BBB Makefile fun.h #includ ...

  6. 动态规划(计数DP):JLOI 2016 成绩比较

    Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M- 1的整数.一位同学在必修课上可以获得的分数是1到Ui中的一个 ...

  7. HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

    Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  8. dev中gridview控件 z

    目录:一.客户端常用1.常用API2.聚焦行变更事件3.客户端选择多行4.客户端选择行5. 获取选择的行数目6.单击行时,选中行7.通过checkbox 选择行8.选择所有行9.启动编辑框,Conta ...

  9. Apache.NMS.Stomp 下载

    最近项目中有用到ActiveMQ, MQ服务器61613的端口是用的STOMP协议, 原来项目中有使用MQ, 但发现缺少Apache.NMS.Stomp.dll的引用,于是上官网上找,结果发现所有的A ...

  10. NodeAsp——像开发NodeJS应用一样玩转ASP

    NodeAsp是一套Classic ASP框架,借鉴了NodeJS的模块化思想,让您可以使用全新的理念愉快地书写ASP程序. NodeAsp使用遵循CommonJS规范的require,完全兼容Nod ...