在System.Data.dll中,System.Data命名空间,提供不同Ado.Net类
SQLSever数据提供程序 System.Data.SqlClient命名空间
OLEDB数据提供程序 System.Data.Oledb命名空间
ODBC数据提供程序 System.Data.Odbc命名空间
Oracle数据提供程序 System.Data.OracleClient命名空间
MySql:
using MySql.Data;
using MySql.Data.MySqlClient;
每一种数据提供程序包括:
Connection对象:数据库连接 sqlConnection类
Command:执行数据库命令的对象 SqlCommand
DataReader: 从数据源中提供快速的,只读的数据流 SqlDataReader
DataAdapter:提供DataSet对象(临时数据库、内存中的数据库)与数据源的桥梁
Ado.Net访问数据的步骤
MySqlConnection conn= new MySqlConnection();
//打开门--钥匙,连接字符串=钥匙
conn.ConnectionString = ""; //连接字符串
// conn.Database; 要连接的数据库的名称,只读
// conn.DataSource; 数据源 local/IP,端口号
//conn.State; 连接的状态
// conn.ConnectionTimeout; 15s
State: Closed关闭 Open打开 Connecting正在连接 Executing正在执行命令 Broken连接中断 Fetching正在检索
static void Main(string[] args)
{
//创建连接
MySqlConnection conn= new MySqlConnection();
conn.ConnectionString =
"sever=.;database=TestBase;uid=hzt;pwd=123456"; //连接字符串
//打开连接
conn.Open();
//创建执行命令对象
conn.CreateCommand(); //创建一个与conn关联的MySqlCommand对象
//执行命令
//关闭连接
conn.Close();//区别:conn.Close()没有清除连接字符串,可以直接再Open conn.Dispose();清除连接字符串,需要重新设立
}
1)手动写 前面代码
2)专门的类来构建字符串
MySqlConnection conn= new MySqlConnection();
MySqlConnectionStringBuilder connStringBuilder = new MySqlConnectionStringBuilder();
connStringBuilder.Server = ".";
connStringBuilder.Database = "TestBase";
connStringBuilder.UserID = "hzt";
connStringBuilder.Password = "123456";
conn.ConnectionString = connStringBuilder.ConnectionString;
3)
配置文件中存储
在程序代码中写连接字符串,如果要修改,过后重新编译,灵活性很差,如何修改?
放到文件的配置文件中 <connectionStrings>或者
App.config
//引用 System.configuration
//创建连接
MySqlConnection conn= new MySqlConnection();
//读取配置文件中的配置字符串
conn.ConnectionString= ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
//打开连接
conn.Open();
static void Main(string[] args)
{
string connStr=ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
//或者 conn.ConnectionString = connStr;
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
// Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
conn.Open(); //打开连接,进行与数据库的交互,增删改查
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
}
Try catch finally
MySqlConnection conn = null;
try //可能会出错的代码
{
string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
conn = new MySqlConnection(connStr);
//或者 conn.ConnectionString = connStr;
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
// Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
conn.Open(); //打开连接,进行与数据库的交互,增删改查
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
}
catch(Exception ex) //捕捉异常
{
Console.WriteLine(ex.Message);
}
finally //释放 连接对象关闭
{
conn.Close();
}
using{} 自动释放空间 但是不能捕捉异常
连接对象自动关闭
MySqlConnection conn = null;
string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
using (conn=new MySqlConnection(connStr) { //使用using进行释放的对象,它必须继承于IDispossable接口
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
// Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
conn.Open(); //打开连接,进行与数据库的交互,增删改查
Console.WriteLine($"连接数据打开之前:");
Console.WriteLine($"Data Source:{conn.DataSource}");
Console.WriteLine($"DataBase:{conn.Database}");
Console.WriteLine($"ServerVersion:{conn.ServerVersion}");
Console.WriteLine($"State:{conn.State}");
}
为什么要使用连接池?
要连接数据库非常耗时耗力,要经历几个阶段:建立物理通道,与服务器初次握手,服务器身份验证,运行检查······
连接池可以重复利用已有连接
连接池是什么?
容器:存放了一定数量的与数据库服务器的物理连接
需要——容器里取出一条空闲的连接,而非创建一条新的连接
作用:减少连接数据库的开销,从而提高应用程序性能
分类:同一时刻同一应用程序域可以有多个不同类型的连接池。
区分标准:连接字符串(打开一条连接,如果这条链接与现有链接不匹配,会创建一个新的连接池,否则共用一个连接池)、进程、应用程序域
如何分配:
根据连接请求的类型,找到与它相匹配的连接池
1、有空闲,返回这条连接
2、未达到最大连接数,空闲连接已用完,创建新连接
3、已达到最大连接数,等待,直到有空闲连接可用
4、移除无效链接:不能正确连接到数据库服务器的连接。连接池管理器处理
5、回收连接:使用完连接,应当及时关闭或释放 close() dispose() 连接回到连接池
Ado.Net默认启用连接池
连接字符串可以控制连接池的行为
static void Main(string[] args)
{
string connStr = "server= 127.0.0.1;Database= apolloconfigdb;uid = root;pwd= 123456;Charset=utf8;Pooling=true;Max Pool Size=5";
for(int i=0;i<5;i++)
{
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
Console.WriteLine($"第{i+1}个连接已经打开");
}
Console.ReadKey();
}
2、三个属性
Max Pool Size最大连接数\Min Pool Size最小连接数\Pooling是否启用连接池
3、测试连接池使用与否的耗时
static void Main(string[] args)
{
//启用连接池
string connStr = "server= 127.0.0.1;Database= apolloconfigdb;uid = root;pwd= 123456;Charset=utf8;Pooling=true;Max Pool Size=5";
Stopwatch sw = new Stopwatch();
sw.Start();
for(int i=0;i<100;i++)
{
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();
//Console.WriteLine($"第{i+1}个连接已经打开");
conn.Close();
}
sw.Stop();
Console.WriteLine($"启用连接池,耗时:{sw.ElapsedMilliseconds}ms"); //782ms
//不启用连接池
string connStr1 = "server= 127.0.0.1;Database= apolloconfigdb;uid = root;pwd= 123456;Charset=utf8;Pooling=false;Max Pool Size=5";
Stopwatch sw1 = new Stopwatch();
sw1.Start();
for (int i = 0; i < 100; i++)
{
MySqlConnection conn = new MySqlConnection(connStr1);
conn.Open();
//Console.WriteLine($"第{i+1}个连接已经打开");
conn.Close();
}
sw1.Stop();
Console.WriteLine($"不启用连接池,耗时:{sw1.ElapsedMilliseconds}ms"); //1746ms
Console.ReadKey();
}
4、连接池类别区分测试 在连接格式上有较大的不同是区分不同连接池的标准
static void Main(string[] args)
{
//启用连接池
string connStr1 = "server= .;Database= apolloconfigdb;uid = root;pwd= 123456;Charset=utf8;Pooling=true;Max Pool Size=5";
string connStr2= "server= .; Database= apolloconfigdb;uid = root;pwd= 123456;Pooling=true;Max Pool Size=5";
string connStr3= "server= .;Database= apolloconfigdb;uid = root;pwd= 123456;Charset=utf8;Pooling=true;Max Pool Size=5";
for(int i=0;i<10;i++)
{
MySqlConnection conn1 = new MySqlConnection(connStr1);
conn1.Open();
Console.WriteLine($"conn1 第{i+1}个连接已经打开");
MySqlConnection conn2 = new MySqlConnection(connStr2);
conn2.Open();
Console.WriteLine($"conn2 第{i + 1}个连接已经打开");
MySqlConnection conn3 = new MySqlConnection(connStr3);
conn3.Open();
Console.WriteLine($"conn3 第{i + 1}个连接已经打开");
}
Console.ReadKey();
}
重要属性:
connection:SqlCommand对象使用的SqlConnection
CommendText:获取或设置要执行的T-SQL语句或存储过程名
CommendType:CommandType.Text 执行的是一个sql语句 //默认不设置
CommandType.StoredProcedure 执行的是一个存储过程 带参的必须设置为此句
Parameters:SqlCommand对象的命令参数集合 空集合
Transaction:获取或设置要在其中执行的事务
using (MySqlConnection conn=new MySqlConnection(connStr)) {
conn.Open();
//创建命令,执行命令对象
//命令 T-SQL或存储过程 --后者数据库里已经创建好
//SqlCommend 对SqlServer数据库执行的一个T-SQL语句或存储操作
//SqlCommend对象 是执行数据库的对象
string sql = "select* from Userinfos";
//初始化sqlcommand对象的操作
//1.
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = sql;
//2.
MySqlCommand cmd1 = new MySqlCommand(sql);
cmd1.Connection = conn;
//3.
MySqlCommand cmd2 = new MySqlCommand(sql, conn);
//4.
MySqlCommand cmd3 = conn.CreateCommand();
cmd3.CommandText = sql;
//5.
string delsql = "";
MySqlCommand cmd4 = new MySqlCommand(delsql, conn, null);
ExecuteNonQuery()
static void Main(string[] args)
{
string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
int count = 0;
using (MySqlConnection conn=new MySqlConnection(connStr)) {
string UserName = "Peter";
int Age = 16;
string Adress = "Japan";
int Phone_number = 1453336656;
string Sex = "Man";
//创建命令
string sql = "INSERT INTO `t1`.`userinformation`(UserName,Age," +
"Adress,Phone_number,Sex)VALUES('"+UserName+"','"+Age+"','"+Adress+"','"+Phone_number+"','"+Sex+"') ";
//创建命令对象
MySqlCommand cmd = new MySqlCommand(sql,conn);
//执行命令
//执行T-SQL语句或者存储过程并返回受影响的行数 增删改
//共有条件:conn状态为打开
//连接使用原则:最晚打开,最早关闭
conn.Open();
count=cmd.ExecuteNonQuery();
conn.Close();
//
//cmd.ExecuteScalar();
//cmd.ExecuteReader();
}
if(count>0)
{
Console.WriteLine($"{count}");
}
Console.ReadKey(); //运行完后随便按一个键才会退出
}
ExecuteScalar()
执行查询语句或存储过程,返回查询结果集中的第一行第一列的任意值
有时候,插入数据后,想返回自动生成的标志列的值,我们也可以用这种方法
private static void TestExecuteScalar()
{
object o = null;
using(MySqlConnection conn=new MySqlConnection(connStr))
{
string sql = "select count(1) from `t1`.`userinformation`";
MySqlCommand cmd = new MySqlCommand(sql, conn);
conn.Open();
o = cmd.ExecuteScalar();
conn.Close();
}
if(o!=null)
{
Console.WriteLine($"o={o}");
}
}
ExecuteReader()
查询,返回一个对象:SqlDataReader 数据阅读器,阅读数据流
SqlDataReader数据少的时候,高效,内存小,实时读取 游标 读取方式固定--只前进不后退
private static void TestExecuteReader()
{
MySqlDataReader dr = null;
using (MySqlConnection conn = new MySqlConnection(connStr))
{
string sql = "select UserName,Age,Adress,Phone_number,Sex from `t1`.`userinformation`";
MySqlCommand cmd = new MySqlCommand(sql, conn);
conn.Open();
dr = cmd.ExecuteReader(); //读取整个过程conn要保持open
//dr读取数据过程中,要及时保存,读一条丢一条
while(dr.Read()) //如果可以前进到后一条记录
{
string uname = dr["UserName"].ToString();
int age = int.Parse(dr["Age"].ToString());
string adress = dr["Adress"].ToString();
int pnumber = int.Parse(dr["Phone_number"].ToString());
string sex = dr["Sex"].ToString();
Console.WriteLine($"UserName:{uname},Age:{age},Adress:{adress},Phone_number:{pnumber},Sex:{sex}");
}
dr.Close();
conn.Close();
}
如果你需要在一个程序中获得SqlDataReader,另一个程序使用,则conn不能这么早关闭,用try catch
private static void TestExecuteReaderNoUsing()
{
MySqlDataReader dr = null;
MySqlConnection conn = new MySqlConnection(connStr);
string sql = "select UserName,Age,Adress,Phone_number,Sex from `t1`.`userinformation`";
MySqlCommand cmd = new MySqlCommand(sql, conn);
try
{
conn.Open();
dr = cmd.ExecuteReader(); //读取整个过程conn要保持open
}
catch(Exception ex)
{
Console.WriteLine("执行查询异常");
conn.Close();
}
//dr读取数据过程中,要及时保存,读一条丢一条
while(dr.Read()) //如果可以前进到后一条记录
{
string uname = dr["UserName"].ToString();
int age = int.Parse(dr["Age"].ToString());
string adress = dr["Adress"].ToString();
int pnumber = int.Parse(dr["Phone_number"].ToString());
string sex = dr["Sex"].ToString();
Console.WriteLine($"UserName:{uname},Age:{age},Adress:{adress},Phone_number:{pnumber},Sex:{sex}");
}
dr.Close();
conn.Close();
}
注:dr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);//关闭连接,即一起关闭
表示SqlCommand对象的参数,或与DataSet中列的映射
static void Main(string[] args)
{
//参数的构造方法
//1.参数
MySqlParameter pral = new MySqlParameter();
pral.ParameterName = "@EyesColor"; //参数名
pral.MySqlDbType = MySqlDbType.VarChar; //数据类型
pral.Value = "blue";
pral.Size = 20;
//2.参数名 值
MySqlParameter pral1 = new MySqlParameter("@EyesColor", "black");
//3.参数名 SqlDbType
MySqlParameter pral2 = new MySqlParameter("@EyesColor", MySqlDbType.VarChar);
//4.参数名 类型 大小
//5.参数名 类型 大小 源列名(对应DataTable中的)
MySqlParameter pral4 = new MySqlParameter("@EyesColor", MySqlDbType.VarChar,20,"EyesColor");
}
问题:
object转换成int: Convert.ToInt32(o) 任何情况都可以转。