1.三层架构
Web;BLL;DAL
在 VS 中建立三层架构,在一个统一的文件夹下新建网站 Web,并添加引用 BLL 和 DAL
2.在做项目时要多做测试,一边想着怎么实现,一边想着测试一下看看是否会出问题
例如测试连接数据库能否成功 【注意:通过 服务器资源管理器 创建的数据库 的属性中 可以看到肯定正确的 连接字符串!】
3.SqlCommand.ExecuteNonQuery 方法
对于 UPDATE、INSERT 和 DELETE 语句,返回值为该命令所影响的行数。 如果正在执行插入或更新操作的表上存在触发器,则返回值包括受插入或更新操作影响的行数以及受一个或多个触发器影响的行数。对于其他所有类型的语句,返回值为 -1如果发生回滚,则返回值也是 -1。
4.using语句
using(sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
dt.Load(sdr);
}
相当于:
sdr = cmd.ExecuteReader();
dt.Load(sdr);
sdr.Close();
conn.Close();
其实这种方式也类似于try-catch语句块
public int ExecuteNonQuery(string sql)
{
int res;
try
{
cmd = new SqlCommand(sql, GetConn());
res = cmd.ExecuteNonQuery();
}
catch (System.Exception e)
{
throw e;
}
finally //利用finally将sqlconnection关闭!
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
}
return res;
}
5. 重构方法
①在SQLHelper中定义一些私有的用于操作数据库的对象, SqlConnection SqlCommand SqlDataReader
并在SQLHelper的构造方法中将某些对象实例化
private SqlConnection conn = null;
private SqlCommand cmd = null;
private SqlDataReader sdr = null;
public SQLHelper()
{
string constr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
conn = new SqlConnection(constr);
}
②获得数据库连接对象写出成一个方法,并在方法中打开连接
private SqlConnection GetConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
6.SQL注入
如果添加新闻类别时 输入的是 娱乐新闻') delete category where id=3 --
那么实际的sql语句就是 insert into category(name) values ('娱乐新闻') delete category where id=3 -- ')
意思很明显,在插入了 娱乐新闻 后 还删除了 编号为 3 的新闻类别
解决方案: SQL 参数
例如: 重载SQLHelper中的方法ExecuteNonQuery
public int ExecuteNonQuery(string sql,SqlParameter[] paras)
{
int res;
using (cmd = new SqlCommand(sql, GetConn()))
{
cmd.Parameters.AddRange(paras);
res = cmd.ExecuteNonQuery();
}
return res;
}
在 CategoryDAO 中调用的方式,添加新闻类别的方法
public bool Insert(string caName)
{
bool flag = false;
string sql = "insert into category(name) values(@caName)";
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@caName",caName)
};
int res = sqlHelper.ExecuteNonQuery(sql,paras);
if (res>0)
{
flag = true;
}
return flag;
}