1)系统用户管理:用户的密码以md5散列值的形式保存在数据库中,密码不能明文保存。
2)客户资料管理:使用NPOI实现从Excel文件中批量导入客户资料,还可以将客户资料导出到Excel文件中。
3)客户资料的查询支持按照拼音检索。为了提高检索速度,在用户表中添加一个“姓名拼音”字段,在用户增加,修改时,计算姓名对应的拼音。
4)客户资料的检索支持符合检索,也就是根据用户姓名、地区、购买日期、分店等信息进行多条件符合检索。
5)常见问题管理:将用户常见的问题、回答保存在系统中,并且可以动态的对常见问题进行增删改查。常见问题以树状数据保存在数据库中,这样就可以支持常见问题的无限级分类
6)三层架构,重难点
7)笔试题让敲代码,所以现在所有的代码都必须手写。能手写代码才证明思路清晰。
8)使用SqlHelper+App.config+带参数的sql语句实现登录功能
MD5是一种散列算法,不是一种加密算法。任何长度的任意内容都可以使用MD5计算出散列值。主要作用是验明真身。
MD5一般是长度为32位的16进制字符串。MD5算法不可逆。
系统明文密码有哪些缺点? 个人信息泄露
计算用户输入的密码MD5值,与数据库存储的MD5值进行比较,如果相等则认为密码正确。
应用:使用文件的MD5值来检验文件是否被篡改过。
MD5算法是不可逆的。
原理:计算完毕会返回一个字节数组,就是将128位除以8,所以就是16个字节,再把每个byte转化成两位的16进制表示,最后看到的就是32位的字符串了。
对字符串进行MD5计算
SqlHelper的封装
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _49_ado.net复习
{
/// <summary>
/// 数据库操作辅助类
/// </summary>
class SqlHelper
{
//私有:本类,只读,当前 配置管理器类ConfigurationManager
private static readonly string connString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
/// <summary>
/// 执行增删改操作
/// </summary>
/// <param name="sql">要执行的sql语句或者存储过程</param>
/// <param name="type">类型</param>
/// <param name="pms">数据库参数</param>
/// <returns></returns>
public static int ExecuteNoQuery(string sql, CommandType type, params SqlParameter[] pms)
{
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = new SqlCommand(sql, conn))
{
//要执行的sql的类型
comm.CommandType = type;
if (pms != null)
{
comm.Parameters.AddRange(pms);
}
conn.Open();
//只返回受影响的行数
return comm.ExecuteNonQuery();
}
}
}
public static object ExecuteScalsr(string sql, CommandType type, params SqlParameter[] pms)
{
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = new SqlCommand(sql, conn))
{
//命令类型是sql还是存储过程
comm.CommandType = type;
if (pms != null)
{
//往命令对象中添加请求参数
comm.Parameters.AddRange(pms);
}
conn.Open();
return comm.ExecuteScalar();
}
}
}
public static SqlDataReader ExecuteDataReader(string sql, CommandType type, params SqlParameter[] pms)
{
//如果连接关闭了,就读取不到数据了。(查询数据和读取数据,必须使用同一个连接)
SqlConnection conn = new SqlConnection(connString);
using (SqlCommand comm = new SqlCommand(sql, conn))
{
comm.CommandType = type;
if (pms != null)
{
comm.Parameters.AddRange(pms);
}
try
{
//判断连接状况
if (conn.State == ConnectionState.Closed)
{
//如果连接状态是关闭的,就进行打开
conn.Open();
}
//读取完毕后,关闭连接
return comm.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception)
{
//如果出现异常,就进行捕获
//一旦出现异常,因为连接是打开的,需要手动释放资源
conn.Close();
conn.Dispose();
//捕获当前程序运行出现的异常
throw;
}
}
}
//返回DataTable
public static DataTable ExecuteDataTable(String sql, CommandType type, params SqlParameter[] pms)
{
DataTable dt = new DataTable();
using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connString))
{
adapter.SelectCommand.CommandType = type;
if (pms != null)
{
adapter.SelectCommand.Parameters.AddRange(pms);
}
//执行查询操作,获取数据
adapter.Fill(dt);
}
return dt;
}
}
}
//登录按钮业务逻辑using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _49_ado.net复习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
//MD5了解: 为什么要使用? 同一内容的MD5不会改变,根据这一特性进行对比
//数据库中存明文密码的缺点是什么?
//为什么要使用MD5算法?
//MD5算法不可逆,有些内容的MD5值可能相同。
//创建一个MD5对象,调用方法来创建MD5值。ComputerHash(数组)
//计算某一个文件的MD5值,计算某一个字符串的MD5值
}
/// <summary>
/// 登录的业务逻辑处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// 代码已经能够成功执行了
private void button1_Click(object sender, EventArgs e)
{
string useName = tb1.Text.Trim();
string password = tb2.Text;
string sql = "select count(*) from UserTable where loginName=@uid and password=@pwd";
//这一块的代码不太熟练啊
SqlParameter[] pms = new SqlParameter[] {
//数组里面存放的是每一个SqlParameter对象:sql参数对象;数组元素之间使用逗号分割
new SqlParameter("@uid",SqlDbType.NVarChar,50) { Value= useName},
new SqlParameter("@pwd",SqlDbType.NVarChar,50) { Value=password}
};
//记住这种写法,一定要多敲代码
SqlParameter[] pms1 = new SqlParameter[] {
new SqlParameter ("@uid",SqlDbType.NVarChar,50) {//这个值从哪里来?
Value =useName
},
new SqlParameter("@pwd",SqlDbType.NVarChar,50) {Value=password }
};
//能够查询到数据
int r = (int)SqlHelper.ExecuteScalsr(sql, CommandType.Text, pms);
if (r > 0)
{
MessageBox.Show("登录成功!");
}
else
{
MessageBox.Show("登录失败!");
}
}
}
}