昨天写了 web三层架构的第一版,准确的说是三层架构的前期,顶多算是个二层架构,要慢慢完善。

第一版里,程序虽说能运行起来,但是有一个缺陷,就是里面的SQL语句,是使用的拼接字符进行执行。这样安全系数很低,如果有心人的话,可能会SQL注入,重新拼接字符,然后篡改我们的数据库内容,导致不可挽回的损失。

在第二版本,也就是这一版里,我对原来的SQL语句进行了重构,使用带参数的SQL语句对数据库进行操作,这样做的好处是,无论用户输入的是什么格式的字符,SQL语句都会原封不动的把这些字符写入到数据库中,这样就避免了有心人对字符进行拼接,导致数据库出错。

下面我用另一个小例子来说明防止SQL注入的核心代码,在最后会给出我重构过的第一版程序,也就是今天要写第二版程序:

这是DAO类中的insert方法:

         public bool insert(string name, string sex, string salary)
{
bool flag = false; SqlParameter[] paras = new {
new SqlParameter("@name", name),
new SqlParameter("@sex", sex),
new SqlParameter("@salary", salary)
}; string sql = "insert into person ([name], sex, salary) values (@name, @sex, @salary)"; if (sq.ExecuteNonQuery(sql, paras) > ) //把SQL语句和SQL参数同时传入SQLHelper的ExecuteNonQuery中执行。
{                   // flag = true;
} return flag;
}

这是SQLHelper类中的ExecuteNonQuery方法:

         public int ExecuteNonQuery(string sql, SqlParameter[] paras)
{
int result; cmd = new SqlCommand(sql, getcon()); //创建SQLcommand对象cmd cmd.Parameters.AddRange(paras); //在SQLcommand对象cmd中,添加参数。
                              //上面的这一句注释,是自己的理解,如果理解错了,请在评论区帮忙指正一下,先谢过。
result = cmd.ExecuteNonQuery(); //然后执行对象cmd,其中已经包含了SQL语句和要用的参数 return result;
    }

上面是一个小例子,创建了一张表,然后向表里的 NAME SEX SALARY 三个字段中添加内容。

下面是第二版web三层架构程序:

SQLhelper助手类:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Data;
using System.Data.SqlClient;
using System.Configuration; namespace DAL
{
public class SQLHelper
{
SqlCommand cmd = null; public string strcon()
{
string strcon = ConfigurationManager.ConnectionStrings["strcon"].ConnectionString; return strcon;
} public SqlConnection getcon()
{
SqlConnection con = new SqlConnection(strcon()); if (con.State == ConnectionState.Closed)
{
con.Open();
} return con;
} #region 执行增删改查的SQL语句
/// <summary>
/// 执行增删改查的SQL语句
/// </summary>
/// <param name="sql">要执行的SQL</param>
/// <returns>返回执行SQL语句后影响的行数</returns>
public int ExecuteNonQuery(string sql)
{
int res; try
{
cmd = new SqlCommand(sql, getcon()); res = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (getcon().State == ConnectionState.Open)
{
getcon().Close();
}
} return res;
}
#endregion #region 执行带参数的增删改SQL语句
/// <summary>
/// 执行带参数的增删改SQL语句
/// </summary>
/// <param name="sql">要执行的SQL语句</param>
/// <param name="paras">传入的参数</param>
/// <returns>返回受影响的行数</returns>
public int ExecuteNonQuery(string sql, SqlParameter[] paras)//上下两个ExecuteNonQuery因为使用了方法的重载,其中参数不同,所以虽说都在调用ExecuteNonQuery,但是传递的参数的个数不同,系统会自动识别用哪一个ExecuteNonQuery方法。
{
int res; cmd = new SqlCommand(sql, getcon());// 1 cmd.Parameters.AddRange(paras);// 2 res = cmd.ExecuteNonQuery(); return res;
}
#endregion #region 执行传入的SQL查询语句
/// <summary>
/// 执行传入的SQL查询语句
/// </summary>
/// <param name="sql">要执行的查询SQL</param>
/// <returns>返回查询SQL语句的数据集</returns>
public DataTable ExecuteQuery(string sql)
{
DataTable dt = new DataTable(); //创建一个SqlCommand对象cmd,让其连接数据库,并指向sql语句。//自己理解,如果不对的话请在评论区指正,先谢过。
cmd = new SqlCommand(sql, getcon()); //执行cmd连接的数据库.使用using后在执行完毕后,直接关闭sdr。不需要写sdr.closed.
using (SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))//如果使用 CommandBehavior.CloseConnection 参数,那么在代码的结尾处就不需要写 getcon().Close(),他会直接关闭。
{
dt.Load(sdr);// Load 这种方法适合于SqlDataReader。如果是SqlDataAdapter,则会用到 Fill 方法。
} return dt;
}
#endregion #region 执行传入带参数的SQL查询语句
/// <summary>
/// 执行传入带参数的SQL查询语句
/// </summary>
/// <param name="sql">要执行的SQL语句</param>
/// <param name="paras">传入的参数</param>
/// <returns>返回查询的数据集</returns>
public DataTable ExecuteQuery(string sql, SqlParameter[] paras)
{
DataTable dt = new DataTable(); cmd = new SqlCommand("sql", getcon()); cmd.Parameters.AddRange(paras); using (SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(sdr);
} return dt;
}
#endregion
}
}

personDAO员工操作类:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Data;
using System.Data.SqlClient; namespace DAL
{
public class personDAO
{
SQLHelper sq = null; public personDAO()
{
sq = new SQLHelper();
} #region 增加员工信息
/// <summary>
/// 增加员工信息
/// </summary>
/// <param name="name">要添加的员工姓名</param>
/// <param name="sex">要添加的员工性别</param>
/// <param name="salary">要添加的员工工资</param>
/// <returns>返回真假值:如果是真显示添加成功,如果是假显示添加失败</returns>
public bool insert(string name, string sex, string salary)
{
bool flag = false; SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@name", name),
new SqlParameter("@sex", sex),
new SqlParameter("@salary", salary)
}; string sql = "insert into person ([name], sex, salary) values (@name, @sex, @salary)";//记住,添加参数的时候,不需要 双引号 或是 单引号。 if (sq.ExecuteNonQuery(sql, paras) > )//把sql语句和所用到参数数组,一起传送到 ExecuteNonQuery 中去执行。
{
flag = true;
} return flag;
}
#endregion #region 删除员工信息
/// <summary>
/// 删除员工信息
/// </summary>
/// <param name="id">要删除员工的id</param>
/// <returns>返回真假值:如果是真显示删除成功,如果是假显示删除失败</returns>
public bool delete(string id)
{
bool flag = false; SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@id", id)
}; string sql = "delete from person where id = @id";//记住,添加参数的时候,不需要 双引号 或是 单引号。 if (sq.ExecuteNonQuery(sql, paras) > )
{
flag = true;
} return flag;
}
#endregion #region 更改员工信息
/// <summary>
/// 更改员工信息
/// </summary>
/// <param name="id">要更改的员工编号</param>
/// <param name="name">要更改的员工姓名</param>
/// <param name="sex">要更改的员工性别</param>
/// <param name="salary">要更改的员工工资</param>
/// <returns>返回真假值:如果是真显示更改成功,如果是假显示更改失败</returns>
public bool update(string id, string name, string sex, string salary)
{
bool flag = false; SqlParameter[] paras = new SqlParameter[]//创建参数数组
{
new SqlParameter("@id", id),//我的理解:对参数数组赋值
new SqlParameter("@name", name),
new SqlParameter("@sex", sex),
new SqlParameter("@salary", salary)
}; //使用参数数组
string sql = "update person set [name] = @id, sex = @name, salary = @sex where id = salary";//记住,添加参数的时候,不需要 双引号 或是 单引号。 if (sq.ExecuteNonQuery(sql, paras) > )
{
flag = true;
} return flag;
}
#endregion #region 判断员工姓名是否重复
/// <summary>
/// 判断员工姓名是否重复
/// </summary>
/// <param name="name">要进行判断的员工姓名</param>
/// <returns>返回真假值:如果是真代表重复,如果是假进行添加</returns>
public bool repeat(string name)
{
bool flag = false; SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@name", name)
}; string sql = "select * from person where [name] = @name";//记住,添加参数的时候,不需要 双引号 或是 单引号。 #region 下面这样写的话,还要重新建立一张虚拟表,如果直接用下面的方法,进行行数的判断就不需要建立。
//DataTable dt = sq.ExecuteQuery(sql); //if (dt.Rows.Count > 0)//dt.Rows.Count 这个方法是检查返回的虚拟表中是不是有数据,如果有的话则行数不为零。如果没有的话则行数为零。
//{
// flag = true;
//}
#endregion if (sq.ExecuteQuery(sql, paras).Rows.Count > )//dt.Rows.Count 这个方法是检查返回的虚拟表中是不是有数据,如果有的话则行数不为零。如果没有的话则行数为零。
{
flag = true;
} return flag;
}
#endregion
}
}

上面就是重构的第一版的代码,也就是第二版,其中如果有错误的地方,请在评论区帮忙指正。

简单的web三层架构系统【第二版】的更多相关文章

  1. 简单的web三层架构系统【第三版】

    今天是第三版,和前几天一样今天还是要对代码进行优化,三层架构是一种思想,具体能不能使得整个系统安全和高性能,还是要看代码编写的是否合理,逻辑性是否严谨. 昨天偶然间看到别人写的三层架构中,竟然没有在方 ...

  2. 简单的web三层架构系统【第五版】

    接上一版,今天差不多就是三层架构后台代码的完结了,这一版写完,接下来就是前台的制作了,前台不太熟悉,还在深入学习.过一段时间在写,今天先把后台代码写完. 三层架构包括DAL层, BLL层, UI层(也 ...

  3. 简单的web三层架构系统【第四版】

    上一次写了第三版, 因为之前无意之间看到一段视频,说是把系统中所有的SQL语句都做成存储过程.可以在很大程度上优化系统的SQL执行速度.所以百度了一下细节问题,之后我把所有的SQL语句,都做成了存储过 ...

  4. 简单的web三层架构系统【第一版】

    SQLhelper助手类编写: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using Sys ...

  5. 关于WEB三层架构的思考

    1.MVC设计思想 MVC程序设计思想是眼下比較流行的WEB开发的模式,当中,M(model)是模型.即JavaBean,用来封装和保存数据:V(view)是视图,即JSP.用来显示内容:C(cont ...

  6. WEB三层架构与MVC

    web三层架构是指: >用户接口层(UI Layer) >业务逻辑层(Bussiness Layer) >持久化层 关于业务逻辑和用户接口 在早期的web开发中,因为业务比较简单,并 ...

  7. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

  8. Django——WEB三层架构与MVC

    而我发此文的目的有二:一者,让初学者能够听到一家之言,是为解惑:二者,更希望抛砖引玉,得到专家的批判. 许多学生经常问我,MVC到底和WEB三层架构有啥关系? 开始时,我也只能给他们一些模糊的回答.时 ...

  9. Kali Linux Web渗透测试手册(第二版) - 1.3 - 靶机的安装

    Kali Linux Web渗透测试手册(第二版) - 1.3 - 靶机的安装  一.配置KALI Linux和渗透测试环境 在这一章,我们将覆盖以下内容: 在Windows和Linux上安装Virt ...

随机推荐

  1. Xampp Linux应用

    一.基本操作: 1.Xampp安装包下载:   https://www.apachefriends.org/index.html   2.安装与配置:   将xampp-linux-x64-5.6.3 ...

  2. 製程能力介紹(SPC introduction) ─ 製程能力改善及評估

    如何改善製程能力 參考下面常態分配圖,原製程能力不足,其製成品有一定比率超出下限規格,其改善對策有二: 縮小製程變異,也就是改善Cp,提高Cp的值. 移動製程中心,也就是改善Ck,減小Ck的值. 就技 ...

  3. 微软 Office 2010 SP2 正式版下载大全(含简中)

    7月24日消息,微软正式为 Office 2010 和 SharePoint 2010 系列产品发布 SP 2服务包,带来重要更新和修复.除了提供产品补丁,SP2服务包还将提升产品的稳定性.性能以及安 ...

  4. 【HTML5】DOMContentLoaded事件

    这个事件是从HTML中的onLoad的延伸而来的,当一个页面完成加载时,初始化脚本的方法是使用load事件,但这个类函数的缺点是仅在所有资源都完全加载后才被触发,这有时会导致比较严重的延迟,开发人员随 ...

  5. Wet Shark and Flowers(思维)

    C. Wet Shark and Flowers time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  6. mac 版本号控制工具SmartSVN7.5.4(破解版)

    SmartSVN7.5.4和破解工具,下载地址:http://download.csdn.net/detail/pearlhuzhu/7407319 操作步骤: 1.在MAC上选中smartsvn-m ...

  7. Bootstrap的aria-label与aria-labelledby

    aria-label: 正常情况下,form表单的input组件都有对应的label,当input组件获取到焦点时,屏幕阅读器会读出相应label里的文本. 但是如果没有给输入框设置label时,当其 ...

  8. svm评价指标公式

    在做svm分类试验时,对于结果的处理,仅用一种指标很难得到正确评估算法的效果.所以,一般要用到precision(精确率),recall(召回率),F-measure.accuracy(准确率)四个指 ...

  9. 使用Spire PDF for .NET将HTML转换成PDF文档

    目录 开发环境说明 Spire PDF for .NET (free edition)体验 资源下载 开发环境说明 Microsoft Visual Studio 2013 Ultimate Edit ...

  10. Java threadpool机制深入分析

    简介 在前面的一篇文章里我对java threadpool的几种基本应用方法做了个总结.Java的线程池针对不同应用的场景,主要有固定长度类型.可变长度类型以及定时执行等几种.针对这几种类型的创建,j ...