四.Ado.Net
Ado.Net 笔记整理
Ado(ActiveX Data Objects) 一个用于c# 操作数据库的框架,是一个com组件库。
优点:执行效率高
缺点:开发效率慢
当前笔记开发环境为:vs2022、mysql8、.net 8
1.Connection连接对象
Connection是数据库连接对象,用于于数据库建立连接。sqlServer是SqlConnection,MySql是MySqlConnection,这些类都实现IDbConnection接口。
/**
* 1.nuget安装Mysql.Data
*/
/**
* 2.准备mysql连接字符串
*/
string server = "www.diandiandidi.club"; // 服务器地址
string port = "3306"; // 端口号
string database = "test"; // 数据库名称
string uid = "dddd"; // 用户名
string pwd = "@DianDianDiDi7933"; // 密码
string connStr = $"Server={server};Port={port};Database={database};Uid={uid};Pwd={pwd};";
/**
* 3.创建mysql连接对象
* MySqlConnection在MySql.Data.MySqlClient下
*/
var mySqlConnection = new MySqlConnection(connStr);
Console.WriteLine($"连接状态:{mySqlConnection.State}");
Console.WriteLine($"数据库:{mySqlConnection.Database}");
Console.WriteLine($"超时时间:{mySqlConnection.ConnectionTimeout}秒");
/**
* 4.打开连接
*/
mySqlConnection.Open();
Console.WriteLine($"mysql服务器版本:{mySqlConnection.ServerVersion}");
/**
* 5.最后一定要关闭连接
*/
mySqlConnection.Close();
/**
* 5.1 或者使用using语句自动关闭连接
*/
//using (var connection = new MySqlConnection(connStr))
//{
// connection.Open();
//}
2.SqlCommand命令对象
MySqlCommand和MySqlConnection同样属于非托管资源,需要手动释放
private static void TestInsertReturnId(MySqlConnection mySqlConnection)
{
string sql = "INSERT INTO roles (role_name, description) VALUES (@role_name, @description);SELECT LAST_INSERT_ID();";
using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@role_name", "Tourist2");
mySqlCommand.Parameters.AddWithValue("@description", "游客2,无权限");
var result = mySqlCommand.ExecuteScalar();
Console.WriteLine($"自增id:{result}");
}
/// <summary>
/// 测试获取首行首列
/// </summary>
/// <param name="mySqlConnection"></param>
/// <returns></returns>
private static void TestScalar(MySqlConnection mySqlConnection)
{
string sql = "SELECT COUNT(1) FROM users";
using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
var result = mySqlCommand.ExecuteScalar();
Console.WriteLine($"返回值:{result}");
}
/// <summary>
/// 测试插入(删除、更新和插入的方法一致)
/// </summary>
/// <param name="mySqlConnection"></param>
private static void TestInsert(MySqlConnection mySqlConnection)
{
string sql = "INSERT INTO roles (role_name, description) VALUES (@role_name, @description)";
using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@role_name", "Tourist");
mySqlCommand.Parameters.AddWithValue("@description", "游客,无权限");
int rowsAffected = mySqlCommand.ExecuteNonQuery();
Console.WriteLine($"插入成功 {rowsAffected} 条数据。");
}
3.SqlDataReader 数据读取
从数据库中只进的行流读取数据,整个过程需要一直保持与数据库连接。
/// <summary>
/// 测试查询
/// </summary>
private static void TestSelect(MySqlConnection mySqlConnection)
{
string sql = "SELECT * FROM users";
using var mySqlCommand = new MySqlCommand(sql, mySqlConnection);
using var mySqlDataReader = mySqlCommand.ExecuteReader();
while (mySqlDataReader.Read())
{
Console.WriteLine(mySqlDataReader["user_id"] + "--" + mySqlDataReader["username"]);
}
}
判断读取的某个数据是否为空
if(mySqlDataReader["user_id"] is not DBNull)
{
}
4.连接模式和断开模式
连接模式:需要一直保持与数据库连接,适用于大量数据,例如SqlDataReader
断开模式:可以一次性读取数据,之后断开连接,适用于小量数据,例如SqlDataAdapter
5.SqlDataAdapter 适配器
private static void TestSelect(MySqlConnection mySqlConnection)
{
using var adapter = new MySqlDataAdapter();
using var cmd = new MySqlCommand("SELECT * FROM users", mySqlConnection);
adapter.SelectCommand = cmd;
/**
* DataSet:小型数据集。
* DataSet类实现了IDisposable接口,主要管理的是内存中的数据,
* 不直接持有非托管资源,大多数情况下不需要为 DataSet 使用 using 语句
*/
using var ds = new DataSet();
// 适配器填充数据集
adapter.Fill(ds);
// 获取第一个表
DataTable table = ds.Tables[0];
// 获取第一行第一列的值
object value = table.Rows[0][0];
// 获取第一行"Name"列的值
string name = table.Rows[0]["username"].ToString();
// 遍历所有行
foreach (DataRow row in table.Rows)
{
Console.WriteLine($"ID: {row["user_id"]}, Name: {row["username"]}");
}
}
6.数据连接池
通过复用数据库连接来减少创建和销毁连接的开销
工作原理:
1.当应用程序请求连接时,连接池首先检查是否有可用的空闲连接 2.如果有则直接返回,没有则创建新连接 3.使用完毕后连接返回连接池而非真正关闭 4.连接池维护一定数量的活跃连接
SqlClient(SQL Server)、OracleClient、MySqlClient、Npgsql(PostgreSQL)均默认开启连接池,默认最大连接数为100。
Pooling=true; // 是否启用连接池(默认true) Min Pool Size=5; // 最小连接数(默认0) Max Pool Size=100; // 最大连接数(默认100)
7.事务操作
基本事务模式
var myTransaction = mySqlConnection.BeginTransaction();
try
{
myTransaction.Commit();
}
catch (Exception e)
{
Debug.WriteLine(e);
myTransaction.Rollback();
}
finally
{
mySqlConnection.Close();
}
事务隔离级别
var isoLevel = System.Data.IsolationLevel.ReadCommitted;
var myTransaction = mySqlConnection.BeginTransaction(isoLevel);
隔离级别 脏读 不可重复读 幻读 描述
ReadUncommitted ✓ ✓ ✓ 最低隔离级别
ReadCommitted × ✓ ✓ 默认级别,防止脏读
RepeatableRead × × ✓ 防止不可重复读
Serializable × × × 最高隔离级别
Snapshot × × × 使用行版本控制
保存点
var myTransaction = mySqlConnection.BeginTransaction();
try
{
// ······
//创建保存点
myTransaction.Save("AfterOrderCreated");
// ······
myTransaction.Commit();
}
catch (Exception e)
{
// 只回滚到保存点
myTransaction.Rollback("AfterOrderCreated");
}
finally
{
myTransaction.Rollback();
}
8.DbHelper
public class DbHelper
{
private readonly string _connectionString;
public DbHelper(string connectionString)
{
_connectionString = connectionString;
}
// 打开数据库连接
private MySqlConnection GetConnection()
{
var connection = new MySqlConnection(_connectionString);
connection.Open();
return connection;
}
/// <summary>
/// 执行查询并返回 MySqlDataReader
/// </summary>
public MySqlDataReader ExecuteReader(string query, params MySqlParameter[] parameters)
{
var connection = GetConnection();
var command = new MySqlCommand(query, connection);
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
return command.ExecuteReader(CommandBehavior.CloseConnection);
}
/// <summary>
/// 执行查询并返回 DataTable
/// </summary>
public DataTable ExecuteQuery(string query, params MySqlParameter[] parameters)
{
using (var connection = GetConnection())
using (var command = new MySqlCommand(query, connection))
{
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
using (var adapter = new MySqlDataAdapter(command))
{
var dataTable = new DataTable();
adapter.Fill(dataTable);
return dataTable;
}
}
}
/// <summary>
/// 执行非查询命令(如 INSERT、UPDATE、DELETE),返回受影响的行数
/// </summary>
/// <returns></returns>
public int ExecuteNonQuery(string query, params MySqlParameter[] parameters)
{
using (var connection = GetConnection())
using (var command = new MySqlCommand(query, connection))
{
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
return command.ExecuteNonQuery();
}
}
/// <summary>
/// 执行单一结果查询(如 COUNT、SUM),返回结果
/// </summary>
public object ExecuteScalar(string query, params MySqlParameter[] parameters)
{
using (var connection = GetConnection())
using (var command = new MySqlCommand(query, connection))
{
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
return command.ExecuteScalar();
}
}
}