第四章:通用类DBHelper和异常处理
第四章:通用类DBHelper和异常处理
本章目标
- 掌握异常处理try-catch-finally
- 会编写通用类DBHelper
本章内容
为什么要使用异常处理?
如下图所示:当在程序运行过程中出现以下几种情况:
- 无法打开数据库
- 数据操作出错
- 出现一些意外错误
- ………..
出现异常,导致结果:程序异常终止,如何在异常中让程序恢复运行呢?所以要使用到异常处理机制。
什么是异常处理
什么是异常?
程序在运行时发生的错误,叫异常。
什么是异常处理?
在编写代码时,预知可能发生的异常,在程序中编码处理。
在 C# 语言中异常与异常处理语句包括三种形式,即 try catch、try finally、try catch finally。
在上述三种异常处理的形式中所用到关键字其含义如下:
try:用于检查发生的异常,并帮助发送任何可能的异常。
catch:以控制权更大的方式处理错误,可以有多个 catch 子句。
finally:无论是否引发了异常,finally 的代码块都将被执行。
如何处理异常
使用 try-catch 块捕获和处理异常
在 try 语句中放置可能出现异常的语句,而在 catch 语句中放置异常时处理异常的语句,通常在 catch 语句中输出异常信息或者发送邮件给开发人员等。
语法:
1
2
3
4
5
6
7
8try
{
//程序代码,包含可能出现异常的代码
}
catch(处理的异常类型)
{
// 错误处理代码
}案例:在控制台输入年龄
未使用异常处理:
1
2
3
4
5
6
7static void Main(string[] args)
{
Console.WriteLine("请输入年龄:");
int age=int.Parse(Console.ReadLine());//将输入的字符串转换成数字
Console.WriteLine("你的年龄是:{0}",age);
}当在控制台输入错误时,出现结果如下:
使用异常处理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14static void Main(string[] args)
{
try
{
Console.WriteLine("请输入年龄:");
int age = int.Parse(Console.ReadLine());//将输入的字符串转换成数字
Console.WriteLine("你的年龄是:{0}", age);
}
catch (Exception e)
{
Console.WriteLine("你输入的年龄有错!");
}
}当在控制台输入错误时,出现如下:
异常类:Exception及常用的异常类
序号 异常类 描述 1 MemberAccessException 访问错误:类型成员不能被访问 2 ArgumentException 参数错误:方法的参数无效 3 ArgumentNullException 参数为空:给方法传递一个不可接受的空参数 4 ArithmeticException 数学计算错误:由于数学运算导致的异常,覆盖面广。 5 ArrayTypeMismatchException 数组类型不匹配 6 DivideByZeroException 被零除 7 FormatException 参数的格式不正确 8 IndexOutOfRangeException 索引超出范围,小于0或比最后一个元素的索引还大 9 InvalidCastException 非法强制转换,在显式转换失败时引发 10 MulticastNotSupportedException 不支持的组播:组合两个非空委派失败时引发 11 NotSupportedException 调用的方法在类中没有实现 12 NullReferenceException 引用空引用对象时引发 13 OutOfMemoryException 无法为新语句分配内存时引发,内存不足 14 OverflowException 溢出 15 StackOverflowException 栈溢出 16 TypeInitializationException 错误的初始化类型:静态构造函数有问题时引发 17 NotFiniteNumberException 无限大的值:数字不合法 多个catch捕获多个异常
为什么要使用多个catch捕获异常?
虽然可以使用不带参数的 catch 子句捕捉任何类型的异常,但不推荐这种用法。 通常,您应该只捕捉那些您知道如何从中恢复的异常。
作用:
通过使用多个 catch 块,可以捕获和处理多种类型的异常
语法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14try
{
//程序代码,包含可能出现异常的代码
}
catch(处理的异常类型)
{
// 错误处理代码
}
catch(处理的异常类型){
// 错误处理代码
}
catch(处理的异常类型){
// 错误处理代码
}注意事项:
- catch出现的顺序很重要,必须先出现异常的子类异常,再出现父类异常
案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23try
{
Console.WriteLine("请输入第一个数:");
int num1 = int.Parse(Console.ReadLine());
Console.WriteLine("请输入第二个数:");
int num2 = int.Parse(Console.ReadLine());
int result = num1 / num2;
Console.WriteLine("{0}/{1}={2}", num1, num2, result);
}
catch (FormatException ex)
{
Console.WriteLine(ex.Message);
}
catch (DivideByZeroException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}异常一:输入格式错误的情况
异常二:除数为0的情况
finally 块
作用:无论是否发生异常,都会执行
语法:
语法一:try-catch-finally
1
2
3
4
5
6
7
8
9
10
11
12try
{
// ……
}
catch(处理的异常类型)
{
}
finally
{
//.....无论什么情况都要执行的代码
}语法二:try-finally
1
2
3
4
5
6
7
8try
{
// ……
}
finally
{
//.....无论什么情况都要执行的代码
}
案例:实现数据库操作登录功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39static void Main(string[] args)
{
Console.WriteLine("请输入用户名:");
string userName = Console.ReadLine();
Console.WriteLine("请输入密码:");
string password = Console.ReadLine();
string connString = "server=.;database=MySchool;uid=sa;pwd=sa;";
SqlConnection conn = new SqlConnection(connString);
try
{
conn.Open();//打开数据库
string sql = "select count(1) from Admin where LoginId=@loginId and LoginPwd=@loginPwd;";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@loginId", userName);
cmd.Parameters.AddWithValue("@loginPwd", password);
int count = (int)cmd.ExecuteScalar();
if (count > 0)
{
Console.WriteLine("登录成功");
}
else
{
Console.WriteLine("登录失败");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
conn.Close();//关闭连接
}
Console.ReadKey();
}
通用类DBHelper
在项目配置文件中App.config,添加连接字符串节点:
先在App.config里文件里添加这一行是连接字符串配置,用于指定连接到数据库所需的参数
1
2
3<connectionStrings>
<add name="名称" connectionString="server=.;database=MySchool;uid=sa;pwd=sa;"/>
</connectionStrings>具体说明:
:这是一个 XML 元素,用于包含所有连接字符串的集合。 :这是 中的一个子元素,用于添加一个连接字符串。
name=”Asset”:这是连接字符串的名称,可以在代码中使用该名称来引用该连接字符串。
connectionString=”…”:这是连接字符串的实际值,包含了连接到数据库所需的各种参数。右键添加引用Configuration
创建DBHelper类
读取连接字符串,从配置文件App.config中读取
1
2
3using System.Configuration;//引入命名空间
public static readonly string connString = ConfigurationManager.ConnectionStrings["myschool"].ToString();实现增、删、改操作的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23/// <summary>
/// 实现增,删,改操作
/// </summary>
/// <param name="commandText">sql语句</param>
/// <param name="commandType">操作类型</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
public int ExecuteNonQuery(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
using (SqlConnection connection = new SqlConnection(connString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.CommandType = commandType;
if (parameters != null)
{
command.Parameters.AddRange(parameters);//添加参数
}
connection.Open();
return command.ExecuteNonQuery();
}
}实现返回单行单列的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public object ExecuteScalar(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
using (SqlConnection connection = new SqlConnection(connString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.CommandType = commandType;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
connection.Open();
return command.ExecuteScalar();
}
}实现查询SqlDataReader操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public SqlDataReader ExecuteReader(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
SqlConnection connection = new SqlConnection(connString);//不能关闭连接
SqlCommand command = new SqlCommand(commandText, connection);
command.CommandType = commandType;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
connection.Open();
return command.ExecuteReader(CommandBehavior.CloseConnection);//关闭DataReader对象后自动关闭连接
}返回DataTable操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public DataTable ExecuteDataTable(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
using (SqlConnection connection = new SqlConnection(connString))
{
SqlCommand command = new SqlCommand(commandText, connection);
command.CommandType = commandType;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable dataTable = new DataTable();
connection.Open();
adapter.Fill(dataTable);
return dataTable;
}
}功能实现,调用DBHelpler类:
实现登录功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28public static void Login()
{
Console.WriteLine("请输入账号:");
string loginId = Console.ReadLine();
Console.WriteLine("请输入密码:");
string loginPwd = Console.ReadLine();
string sql = "select count(1) from Admin where LoginId=@loginId and LoginPwd=@loginPwd";
DBHelper dBHelper2 = new DBHelper();
//添加参数
SqlParameter[] sp = new SqlParameter[]
{
new SqlParameter("@loginId",loginId),
new SqlParameter("@loginPwd",loginPwd)
};
int count = Convert.ToInt32(dBHelper2.ExecuteScalar(sql, CommandType.Text, sp));
if (count > 0)
{
Console.WriteLine("登录成功~");
}
else
{
Console.WriteLine("登录失败~");
}
}实现新增功能(修改,删除类似则省略代码):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public static void AddUser()
{
Console.WriteLine("请输入账号:");
string loginId = Console.ReadLine();
Console.WriteLine("请输入密码:");
string loginPwd = Console.ReadLine();
string sql = "insert into Admin(LoginId,LoginPwd) values(@loginId,@loginPwd)";
//添加参数
SqlParameter[] sp = new SqlParameter[]
{
new SqlParameter("@loginId",loginId),
new SqlParameter("@loginPwd",loginPwd)
};
DBHelper dBHelper = new DBHelper();
int count = dBHelper.ExecuteNonQuery(sql, CommandType.Text, sp);
if (count > 0)
{
Console.WriteLine("添加成功!");
}
else
{
Console.WriteLine("添加失败!");
}
}实现查询全部信息,使用DataReader方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public static void SelectAll()
{
string sql = "select loginId,loginPwd from Admin";
DBHelper dBHelper=new DBHelper();
//无参数则传入null
SqlDataReader sdr= dBHelper.ExecuteReader(sql, CommandType.Text, null);
Console.WriteLine("账号\t密码");
while (sdr.Read())
{
Console.WriteLine("{0}\t{1}", sdr["loginId"], sdr["loginPwd"]);
}
sdr.Close();//记得必须关闭
}实现查询全部信息,使用DataTable方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public static void SelectAll2()
{
string sql = "select loginId,loginPwd from Admin";
DBHelper dBHelper = new DBHelper();
//无参数则传入null
DataTable dt = dBHelper.ExecuteDataTable(sql, CommandType.Text, null);
Console.WriteLine("账号\t密码");
foreach (DataRow dr in dt.Rows)
{
Console.WriteLine("{0}\t{1}", dr["loginId"], dr["loginPwd"]);
}
}