ADO.Net基礎mysql
1、ADO.Net簡介
1,程序要經過SQL語句自動化的操做數據庫,必需要用一個類庫,
類庫要提供execute("insert into ...")/executeQuery("select * from ...")相似的方法
2,ADO.Net是.Net中提供的標準訪問數據庫的接口,訪問不一樣的DBMS的底層方法是不同的,ADO.Net把訪問數據庫的方法進行了統一,
訪問MYSql、Oracle、SqlServer等不一樣數據庫的方法幾乎是同樣的
3,ADO.Net是規範,被不一樣的數據庫廠商提供ADO.Net的實現,稱之爲ADO.Net驅動,每一個廠商提供的驅動能夠用來操做本身的數據庫
2、ADO.Net鏈接MYSQLsql
1,安裝MySql的.Net驅動mysql-connector-net-***.msi添加到項目的庫中。
若是安裝遇到問題,則直接下載mysqlnetconnection(V4.5).zip。
2,新建項目,添加引用——「擴展」,添加Mysql.Data;若是是直接解壓版,而後直接添加對MySql.Data.dll的文件的引用
static void Main(string[] args)
{
string connStr = ConfigurationManager.ConnectionStrings["connStr"].ToString();
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "insert into t_fuxi ";
int count = cmd.ExecuteNonQuery();
Console.WriteLine(count+"受到影響");
Console.ReadKey();
}
}
代碼解釋:
1,MySQLConnection、MySQLCommend實現了IDisposable接口,所以使用using進行資源回收
2,"Server=localhost;Database=study1;uid=root;pwd=root;Charset=utf8"叫鏈接字符串,
Server是Mysql服務器的地址,Database是鏈接的數據庫,uid、pwd是用戶名和密碼,採用utf8編碼
3,conn.Open();在執行MySqlCommand以前必定要先打開數據庫鏈接,不然會報錯數據庫
4,ExecuteNoQuery是執行Update、Insert、Delete等非查詢語句,返回值爲受影響的行數
3,ExecuteScalar
執行查詢,並返回查詢所返回的結果集中第一行的第一列,忽略其餘行列。通常用來簡單的得到自由一行一列的查詢結果的值
案例1
cmd.CommandText = "Select count(*) from T_Users";
long count = (long)cmd.ExecuteScalar();
案例2
cmd.CommandText = "Select Password from T_Users where UserName = 'admin'";
string pwd = (string)cmd.ExecuteScalar();
if(string.isNullOrEmpty(pwd))
{
Console.WriteLine("找不到admin");
}
else
{
Console.WriteLine("admin的密碼:"+pwd);
}
4,執行查詢 MySqlDataReader編程
cmd.CommandText = "select * from T_Users";
using(MySqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
long id = reader.GetInt64("Id");
string userName = reader.GetString("UserName");
string passWord = reader.GetString("Password");
Console.WriteLine("id="+id+";UserName="+userName+";Password="+passWord);
}
}
注意:
Reader的遍歷、讀取時須要Connection保持鏈接,若是關閉了Connection,使用會出錯
也能夠根據列序號獲取列的值,效率略高,不過程序不容易讀;經過reeder.GetOrdinal("Age")獲取列名對應的序列號
3、SQL注入漏洞服務器
1,是因爲Sql語句的拼接形成的,
在程序接收用戶的輸入時,須要考慮用戶輸入的內容對數據庫操做產生的影響,
2,對應的解決方法,參數化查詢
cmd.CommandText = "select count(*) from TUsers where username=@username and password=@password";
cmd.Parameters.Add(new SqlParameter() { ParameterName = "@UserName", Value = username });
cmd.Parameters.Add(new SqlParameter() { ParameterName = "@Password", Value = password });
爲何這樣能夠避免「SQL注入漏洞」,
所以使用參數化查詢,就能夠對用戶輸入的內容進行判斷和處理了,本質上是參數賦值
注意:
1,全部SQL中均可以使用參數化查詢傳遞;表名、字段名等不能使用參數化進行替換
2,不要用SqlParameter(string parameterName,object value)這個構造函數,
由於("Age",0)會被匹配成Sqlparameter(string parameterName,SqlDbType dbType)這個構造函數
4、基本數據類型爲空的問題併發
1,把T_Persons表的Name、Age列修改成「容許爲空」,插入一條Name、Age爲空的行
執行後發現,對於空數據reader.Get**方法會拋異常SqlNullValueException,
至關於問數據庫「當前行的Name」是什麼,數據庫告訴你「不知道」。
怎麼解決?
使用ISDBNull獲取指定序號的列的值是否爲null
int? age = null;
if(!reader.IsDBNull(reader.GetOrdinal("Age")))
{
age = reader.GetInt32("Age");
}
5、離線結果集DataSet分佈式
DATAReader是服務器結果集遊標的體現,全部查詢出來的數據都在MySql服務器上。
好處是:當查詢結果數據量打的時候避免佔用本地內存。
不過大部分項目中都會避免大查詢結果,所以缺點就明顯了
讀取的時候必須保持Connection,不只用起來麻煩,並且會較長時間佔用MySql服務器的鏈接資源ide
DataSet是一個離線結果集容器,它把結果數據放到本地內存中。
由於查詢結果可能會包含多個表,所以DataSet包含若干DataTable(ds.Tables),
DataTable包含若干DataRow(dt.Rows)
用法1:
DataSet ds = new DataSet();
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
adapter.Fill(ds);
DataTable table = ds.Tables[0];
6、DataTable
DataSet能夠盛放多個查詢結果集到DataTable
DataAdapter還能夠對結果進行傻瓜化更新、刪除、修改。
咱們通常查詢結果集就一個DataTable,DataAdapter的傻瓜化更新不適合正式的項目,所以有更簡單的用法
DataTable dt = new DataTable();
dt.Load(reader);
注意: 把DataTable聲明到using外,using外再使用查詢結果
遍歷DataTable
for(int i =0;i<dt.Rows.Count;i++)
{
DataRow row = dt.Rows[i];
string name = row.IsNull("name")?null:(string)row["Name"];//NULL處理
Console.WriteLine("name="+name);
}
7、封裝一個庫:分析函數
1,ADO.Net的鏈接字符串寫到配置文件中。
2,每次操做數據庫都要寫一坨代碼,太累,所以封裝一個簡化ADO.Net操做的庫出來:
配置文件的設置鏈接字符串;簡化鏈接的建立;簡化SQL的執行
3,若是一個操做要執行多條SQL語句,若是每條都打開一個鏈接——執行——關閉鏈接的話,效率會很是低,並且會有「事務」的問題。
所以應該提供「打開、執行、關閉」這樣的方法,也要提供「使用後現有鏈接執行的方法」。
4,參數化查詢的查詢參數個數不肯定,可變長度參數會更方便
5,爲了方便大部分狀況下的小結果集,執行查詢返回DataTable
8、MySqlHelper方法規劃工具
1,public static MySqlConnection CreateConnection()
2,public static int ExecuteNonQuery(MySqlConnection conn,string sql,params MySqlParameter[] parameters)
3,public static int ExecuteNonQuery(string sql,params MySqlParameter[] parameters)
4,public static object ExecuteScalar(MySqlConnection conn,string sql,params MySqlParameter[] parameters)
5,public static object ExecuteScalar(string sql,params MySqlParameter[] parameters)
6,public static DataTable ExecuteQuery(MySqlConnection conn, string sql, params MySqlParameter[] parameters)
7,public static DataTable ExecuteQuery(string sql, params MySqlParameter[] parameters)
9、實現MySqlHelper
1,鏈接字符串通常配置到App.config(網站是Web.config)中的<connectionStrings>段中
而後使用ConfigurationManager類(須要添加對System.Configuration的引用)讀取
string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString
注意:
必定要保證代碼中的名字和配置文件中的名字是一致的
2,其餘方法的實現
3,測試幾個方法,調用不須要本身控制鏈接的,再調用公用一個鏈接的
10、得到自動增加字段的值
1,不能用插入後獲取最大值的方法,有併發問題
2,要在同一個鏈接中:select LAST_INSERT_ID()
3,能夠Insert、LAST_INSERT_ID()在同一個鏈接中單獨執行,也能夠把LAST_INSERT_ID()放到insert語句後面用;
分割(使用ExecuteScalar執行便可)
11、事務基礎
1,有一個需求,相似於轉帳,從Tom的工資上轉走10元,轉到Jerry的工資上增長10元
Update T_Employees Set Salary = Salary - 10 where Name = 'Tom'
Update T_Employees Set Salary = Salary + 10 where Name = 'Jerry'
若是執行從Jerry帳上加10元的時候執行出錯(使用SQL語法寫錯誤模擬),那麼就會出現整體丟失10元的問題,若是是轉帳呢?
2,事務(Transaction)有四大特徵:
原子性、一致性、隔離性、持久性
原子性指的是:幾個操做要麼都成功,要麼都失敗
12、ADO.Net事務
1,要在一個鏈接中(不然要涉及到分佈式事務)
MySqlTransaction tx = conn.BeginTransaction();
操做結束後執行tx.Commit()提交事務;
若是執行出錯,則tx.Rollback()回滾(當前事務的操做所有取消)
示例代碼:
MySqlTransaction tx = conn.BeginTransaction();
try
{
MySqlHelper.ExecuteNonQuery(conn,"Update T_Accounts set Amount = Amount-1000 where Number ='0001'");
string s = null;
s.ToLower();//製造異常
MySqlHelper.ExecuteNonQuery(conn, "Update t_accounts Set Amount=Amount+1000 where Number='0002'");
tx.Commit();
}
catch(Exception ex)
{
tx.Rollback();
}
事務還有隔離級別、嵌套事務等問題
十3、SQLServer的使用
1,安裝,版本:2008有兼容性的問題,有bug、所以推薦安裝SQLServer 2008 R2
2,Management Studio的使用
SQLServer的兩種鏈接方式:
Windows 身份驗證(互相信任的局域網中);
SQLServer身份驗證(使用SQLServer用戶名密碼驗證,密碼要複雜一點)。
Windows 身份驗證還有一個用途:忘了sa密碼,能夠本機進去改。
3,新建數據庫、新建表
SQLServer的數據類型
(varchar和nvarchar;nvarchar(n)和nvarchar(MAX);
long是bigint;
獲取前10條數據: select top 10 * from t_persons )、
SQLServer的自動增加(是標識)、不須要特殊指定編碼
4,保存表設計修改的時候,若是報錯「不容許保存更改」:
工具→選項→Designers→把「阻止保存要求從新建立表的更高」勾選掉。
遇到報錯信息:要先仔細閱讀。
5,執行SQL語句(數據庫上點右鍵「新建查詢」,不要點【調試】)
十4、ADO.Net鏈接SQLServer
1,ADO.Net如何鏈接SQLServer:
SQLServer驅動內置
2,鏈接字符串: server=ip;user id =sa;passWord = 密碼;database = db1 3,SQLHelper: 把MySql替換成Sql就能夠了 4,得到自動增加列的值: Insert into t1(...) output insert.Id values(....) 5,若是基於接口編程,只要改動CreateConnection就能夠了,查詢參數以Directory<string,object>傳遞 若是使用Provider,連代碼都不用改,改配置文件便可