知识点一:DBHelper
为什么要对操作数据库代码进行封装?
1,在实际的开发过程中在一个页面上会有很多不同的功能,如果每一个功能都需要操作数据库修改数据,按照在C#中使用AOD.NET框架操作数据库的流程,对应每一个功能都需要写一套:创建连接--创建Command对象--调用Command对象对应方法--关闭连接;比如新增记录和删除记录就要按照这个流程写两遍,而这2遍的代码唯一不同的地方就是执行的sql语句不同;
复制粘贴虽然好用,但是不高效,不够灵活;比如说数据库的连接字符需要修改(比如说数据库连接的密码修改了),对应每一个进行数据库操作创建数据库连接对象的代码都要去修改;
2,在开发过程中针对这种重复代码的情况,可以考虑的就是封装(就是将重复的代码写在方法中:比如增,删,改这样的操作,入参就是要执行的代码,返回值就是操作是否成功)
3,对于数据库相关的操作已经有一套比较通用的封装,就是DBHelper类,那么DBHelper是如何进行封装的,下面将进行详细介绍。
将DBHelper的封装分解为四步:
DBHelper1
创建DBHelper1类,将数据库操作用方法进行封装;通过实例化DBHelper类,使用 对象名.方法 的形式进行调用
知识点:类的实例化,对象方法的外部调用
DBHelper2
能够接收指定的sql命令,改造增,删,查方法,为有参方法,能够接收指定的sql命令并运行
知识点:有参方法
DBHelper3
在DBHelper2中每一个数据库操作方法都会声明,实例化Connection对象,将Connection对象从局部变量改为全局变量
知识点:
一、全局变量
类的成员包括:字段,方法;类的字段有叫做全局变量
字段的初始化:实例化类的时候类的字段会初始为该类型的默认值
类成员的两种访问方式:内部访问和外部访问
内部访问:类的成员包括:字段和方法;类的成员(这里指类的方法)可以直接通过本类中其他成员(类的字段)的名称直接访问其他成员
外部访问:从类的外部访问实例成员:必须包括 变量名称和成员名称,并且变量名称和成员名称之间用(.)号进行分隔
二、本地变量/局部变量(定义在方法中)
在方法体中声明,使用
作用范围:在创建本地代码的块中,也就是{}中;
生命周期:被声明的开始,代码块中的代码执行完之后结束(演示:加法)
DBHelper4
在DBHelper1-3中调用方法都是通过类的实例化,对象名.方法名的形式创建;
那么可不可以用类似 Consoles.WriteLine()这样 类名.方法名 的方式去调用DBHelper中的方法呢?
答案是可以的,单从写代码的角度看,少写了一行实例化类的代码;
知识点:类的静态成员
DBHelper代码:
class DBHelper
{
public static string ConnString = "server=SQL Server服务实例名; database=数据库名;Integrated Security=true"; //Windows身份验证
static SqlConnection Conn = null;
static void InitConnection()
{
if (Conn == null)
{
Conn = new SqlConnection(ConnString);
}
//判断连接对象是否关闭,如果关闭,只需要重新打开连接
if (Conn.State == ConnectionState.Closed)
{
Conn.Open();
}
//连接中断,重启连接
if (Conn.State == ConnectionState.Broken)
{
Conn.Close();
Conn.Open();
}
}
/// <summary>
///增,删,改
/// </summary>
/// <param name="sqlStr">没有结果集返回的sql命令</param>
/// <returns>true=表示操作成功</returns>
public static bool ExcuteNonQuery(string sqlStr)
{
//建立连接
InitConnection();
//创建命令对象
SqlCommand command = new SqlCommand(sqlStr,Conn);
int count = command.ExecuteNonQuery(); //命令收影响行数
Conn.Close();
return count > 0;
}
/// <summary>
/// 返回数据读取对象
/// </summary>
/// <param name="sqlStr">需要返回结果集的sql命令</param>
/// <returns>DataReader对象</returns>
public static SqlDataReader GetDataReader(String sqlStr)
{
//建立连接
InitConnection();
SqlCommand command = new SqlCommand(sqlStr,Conn);
//return command.ExecuteReader();
return command.ExecuteReader(CommandBehavior.CloseConnection); //数据读取完成后关闭连接
}
/// <summary>
/// 查询结果集的第一行第一列
/// </summary>
/// <param name="sqlStr">只需要结果集的第一行第一列的sql(通常为带聚合函数的sql)</param>
/// <returns>结果集的第一行第一列</returns>
public static object ExcuteScalar(string sqlStr)
{
//建立连接
InitConnection();
SqlCommand command = new SqlCommand(sqlStr,Conn);
object obj = command.ExecuteScalar();
Conn.Close();
return obj;
}
}
知识点二:类的静态成员
类成员:字段,属性,方法
类静态成员:静态字段,静态属性,静态方法;使用 static 关键字修饰类的成员,类的成员就变成了静态成员
举例:
实例字段(没有用static修饰的字段)可以理解为篮球队员(对象)每个人都有自己的篮球(字段),自己的篮球漏气了,不影响其他人的篮球
静态字段(使用static修饰的字段)理解为篮球队员(对象)在训练的时候使用一个篮球(静态字段),篮球漏气了意味着所有队员在打的篮球(此刻篮球场上就只有一个篮球,共享的概念)都漏气
静态字段
使用关键字 static修饰
类的内部直接使用 字段名 访问;类的外部使用 类名.字段名 访问
修改后应影响的同一个类实例化的所有对象
静态方法
使用关键字 static修饰
类的内部直接使用 方法名 访问;类的外部使用 类名.方法名 访问
只能够访问静态成员:就是在方法体中,也就是{},中只能够访问静态字段和静态方法
语法:
class 类名
{
[访问控制符] static 类型 字段名;
[访问控制符] static 返回值类型 方法名(参数列表)
{
//方法体
}
}
代码演示:
1,Pet 举例:静态字段的访问;指向相同内存的概念
实例字段
class Pet
{
public string name;
public string color;
public void PrintInfo()
{
Console.WriteLine("name " + name + " color " + color);
}
}
class Program
{
static void Main(string[] args)
{
Pet daBai = new Pet();
daBai.name = "大白";
daBai.color = "白色";
Pet wuGui = new Pet();
wuGui.name = "乌龟"; //其实乌龟是只汪
wuGui.color = "乌黑";
//Console.WriteLine("name " + daBai.name + " color " + daBai.name); //变量名.字段名 访问类的字段
//Console.WriteLine("name " + wuGui.name + " color " + wuGui.name);
daBai.PrintInfo();
wuGui.PrintInfo();
}
}
静态字段
class Pet
{
public string name;
public static string color;
public void SetColor(string inputColor)
{
color = inputColor;
}
public void PrintInfo()
{
Console.WriteLine("name " + name + " color " + color);
}
}
class Program
{
static void Main(string[] args)
{
Pet daBai = new Pet();
daBai.name = "大白";
daBai.SetColor("白色");
Pet wuGUi = new Pet();
wuGUi.name = "乌龟";
wuGUi.SetColor("乌黑");
daBai.PrintInfo();
wuGUi.PrintInfo();
}
}
2,MathCustom 举例:静态方法,静态方法块中访问类的成员,那么类的成员必须被定义为静态的
归纳:
不管是静态字段还是静态方法在类加载的时候都会在内存中开辟一段空间,这个空间存放在静态字段,静态方法
通过类实例化出来的对象在内存中都是独立的,将类中的某个字段声明为静态的,那么该类下所有的对象的该字段的值都是指向同一内存;