文章目录
ORM 简介
-
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 ORM在业务逻辑层和数据库层之间充当了桥梁的作用。
-
O起源于"对象"(Object)===>类, 而R则来自于"关系"(Relational) ===>关系型数据库。ORM旨在解决:程序员在自己的业务逻辑代码中夹杂很多SQL语句用来增加、读取、修改、删除相关数据,而这些代码通常都是重复的,通过ORM可以直接操作对象完成对数据库的操作。
对象关系映射
对象模型(类) | 关系模式(数据库) |
---|---|
类 | 表 |
属性名称 | 字段名称 |
属性类型 | 字段类型 |
实例 | 记录 |
ORM操作步骤
- 需要把数据库中表映射为程序的实体类
- 生成sql语句
- 调用ORM框架中提供的新增方法
1. 映射实体类
实体类与数据库表名、属性一致与不一致
在映射过程中通常会遇到一下几个问题:实体类的表名与数据库表名是否一致、实体类的属性名称与数据库表字段是否一致。这一问题使用特性处理。
特性设置举例
/// <summary>
/// 解决映射类名称与数据库表名称不一致标识
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute:Attribute
{
public string? TableName {
get; set; }
public TableAttribute(string? tablename)
{
TableName=tablename;
}
}
/// <summary>
/// 解决映射属性名称与表的字段名称不一致
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute:Attribute
{
public string? ColumnName {
get; set; }
public ColumnAttribute(string? columnName)
{
ColumnName = columnName;
}
}
/// <summary>
/// 解决映射属性名称与表的主键字段的标识
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class IdAttribute:Attribute
{
}
特性使用方法
/// <summary>
/// 获取真实表名
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
/// <returns></returns>
public static string? GetRealTableNmae(Type type)
{
//默认是类型名称
var tablename = type.Name;
//判断Type上面是否有TableAttribute特性
if (type.IsDefined(typeof(TableAttribute), true))
{
var tableAttr = type.GetCustomAttributes<TableAttribute>().FirstOrDefault();
//获取特性设置的映射表名称
var tableAlias = tableAttr!.TableName;
if (!string.IsNullOrEmpty(tableAlias))
{
tablename = tableAlias;
}
}
return tablename;
}
/// <summary>
/// 通过属性获取真实的列名
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static string? GetRealColumName(PropertyInfo propertyInfo)
{
string columname = propertyInfo.Name;
if(propertyInfo.IsDefined(typeof(ColumnAttribute)))
{
var columnAttr = propertyInfo.GetCustomAttribute<ColumnAttribute>();
var columnAlias = columnAttr?.ColumnName;
if (!string.IsNullOrEmpty(columnAlias))
{
columname = columnAlias;
}
}
return columname;
}
创建实体类
数据库表中字段
在数据库中创建表与字段
定义与数据库表中字段对应的实体类
/// <summary>
/// 定义了映射tb_stu表映射实体
/// </summary>
[Table("tb_stu")]
public class Student : BaseModel
{
[Id]
[ColumnAttribute("id")]
public int StuId {
get; set; }
public string? StuName {
get; set; }
public int StuAge {
get; set; }
public string? StuGender {
get; set; }
public DateTime StuBirthday {
get; set; }
}
2.生成Sql语句
创建SqlBuilder类,SQL语句生成。
创建BaseModel做实体类限定。
创建IDBHelper接口,定义MySql需要用到的操作方法。
创建MySqlDBHelper继承IDBHelper,实现方法
定义sql操作类型
/// <summary>
/// 生成sql语句类型的枚举
/// </summary>
public enum SqlType
{
Insert,
Update,
Delete,
Select,
ID_Select,
Condition_Select
}
根据操作类型生成Sql语句
根据sql语句类型可知,生成正确的sql语句需要:
1.通过类获取对应到数据库真实的表名、字段名
2.生成对应sql语句----(用@+字段名)占位
3.获取字段对应的数值。并添加到mysql的值(MySqlParameter[])列表
以上内容封装到SqlBuilder类中
public class SqlBuilder
{
/// <summary>
/// 生成 SQL语句
/// </summary>
/// <param name="type"></param>
/// <param name="sqlType"></param>
/// <returns></returns>
public static string? GenerateSql(Type type,SqlType sqlType)
{
//拼接sql语句的对象
StringBuilder stringBuilder= new StringBuilder();
switch (sqlType)
{
case SqlType.Insert:
GenerateInsertSql(type,stringBuilder);
break;
case SqlType.Update:
GenerateUpdateSql(type, stringBuilder);
break;
case SqlType.Delete:
GenerateDeleteSql(type, stringBuilder);
break;
case SqlType.Select:
GenerateSelectSql(type, stringBuilder);
break;
case SqlType.ID_Select:
GenerateID_SelectSql(type, stringBuilder);
break;
//case SqlType.Condition_Select:
// GenerateCondition_SelectSql(type, stringBuilder);
// break;
}
return stringBuilder.ToString();
}
/// <summary>
/// 根据对象实例生成mysql值组成的列表
/// </summary>
/// <param name="instance"></param>
/// <param name="sqltype"></param>
/// <returns></returns>
public static MySqlParameter[] GetSqlParameters(object instance, SqlType sqltype)
{
IEnumerable<MySqlParameter> parameters = new List<MySqlParameter>();
switch (sqltype)
{
case SqlType.Insert:
parameters = GetNoPrimaryParameters(instance);
break;
case SqlType.Update:
var parameterslist = GetNoPrimaryParameters(instance).ToList();
var idparamlist = GetPrimaryParameters(instance);
parameterslist.AddRange(idparamlist);
parameters = parameterslist;
break;
case SqlType.Delete:
parameters = GetPrimaryParameters(instance);
break;
case SqlType.Condition_Select:
parameters = GetNotNULLParameters(instance);
break;
}
return parameters.ToArray();
}
#region sql语句生成--获取字段
/// <summary>
///添加 insert into 表名 (字段1,字段2,字段3,...) values (@字段1,@参数2,@参数3,....)
/// insert into tb_stu (stuName,stuGender,stuAge,stuBirthday) values ('李四','男',23,'1920-11-22')
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
private static void GenerateInsertSql(Type type, StringBuilder stringBuilder)
{
#region 表名与类名、属性名一致
获取表名称
//string tablename = type.Name;
//var props = type.GetProperties();
获取字段字符串 ///该语句相当于for循环进行属性获取 ``起到屏蔽关键字作用
//string filestring = string.Join(",", props.Select(propinfor => $"`{propinfor.Name}`"));
获取参数字符串 @为占位符作用
//string paramtring = string.Join(",", props.Select(propinfor => $"@{propinfor.Name}"));
//stringBuilder.Append($"Insert into {tablename} ({filestring}) values {paramtring}");
#endregion
#region 表名与类名、属性名不一致
string tablename = GetRealTableNmae(type)!;
var props = type.GetProperties();
string filestring = string.Join(",", props.Where(propinfor => !propinfor.IsDefined(typeof(IdAttribute)))
.Select(propinfor => $"`{
GetRealColumName(propinfor)}`"));
string parastring = string.Join(",", props.Where(propinfor => !propinfor.IsDefined(typeof(IdAttribute))).Select(propinfor => $"@{
propinfor.Name}"));
stringBuilder.Append($"Insert into {
tablename} ({
filestring}) values ({
parastring})");
#endregion
Console.WriteLine(stringBuilder.ToString());
}
/// <summary>
/// 删除
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
private static void GenerateDeleteSql(Type type, StringBuilder stringBuilder)
{
//获取表名称或者TableAttribute设置的名称
string tablename = GetRealTableNmae(type)!;
var props = type.GetProperties();
//筛选主键字段
var updateIdFileString = string.Join(",", props.Where(propinfor => propinfor.IsDefined(typeof(IdAttribute)))
.Select(propinfor => $"`{
GetRealColumName(propinfor)}`=@{
propinfor.Name}"));
//生成修改sql语句
stringBuilder.Append($"Delete From {
tablename} where {
updateIdFileString}");
Console.WriteLine(stringBuilder.ToString());
}
/// <summary>
///更新 update 表名 Set 字段1=@参数1,字段2=参数2,....... Where 主键字段=@主键字段
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
private static void GenerateUpdateSql(Type type, StringBuilder stringBuilder)
{
//获取表名称或者TableAttribute设置的名称
string tablename = GetRealTableNmae(type)!;
var props = type.GetProperties();
//筛选非主键字段
var updateFileString = string.Join(",", props.Where(propinfor => !propinfor.IsDefined(typeof(IdAttribute)))
.Select(propinfor => $"`{
GetRealColumName(propinfor)}`=@{
propinfor.Name}"));
//筛选主键字段
var updateIdFileString = string.Join(",", props.Where(propinfor => propinfor.IsDefined(typeof(IdAttribute)))
.Select(propinfor => $"`{
GetRealColumName(propinfor)}`=@{
propinfor.Name}"));
//生成修改sql语句
stringBuilder.Append($"Update {
tablename} Set {
updateFileString} where {
updateIdFileString}");
Console.WriteLine(stringBuilder.ToString());
}
/// <summary>
///查询 -- 获取所有字段
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
private static void GenerateSelectSql(Type type, StringBuilder stringBuilder)
{
//获取表名称
string tablename = GetRealTableNmae(type)!;
var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;
var props = type.GetProperties(flags);
//获取字段字符串
string filestring = string.Join(",", props.Select(propinfors => $"`{
GetRealColumName(propinfors)}`"));
stringBuilder.Append($"Select {
filestring} from {
tablename}");
Console.WriteLine(stringBuilder.ToString());
}
/// <summary>
/// 根据id(主键)查询信息
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
private static void GenerateID_SelectSql(Type type, StringBuilder stringBuilder)
{
//1.获取真实表名
string tablename = GetRealTableNmae(type)!;
var props = type.GetProperties();
//2.获取字段字符串
string filestring = string.Join(",", props.Select(propinfor => $"`{
GetRealColumName(propinfor)}`"));
//3.筛选主键字段
var selectIdFilestring = string.Join(",", props.Where(propinfor => propinfor.IsDefined(typeof(IdAttribute)))
.Select(propinfor => $"`{
GetRealColumName(propinfor)}`=@{
propinfor.Name}"));
stringBuilder.Append($"Select {
filestring} From {
tablename} where {
selectIdFilestring}");
}
/// <summary>
///查询-- 根据添加对象(非空属性都为查询条件)生成对应的条件查询语句
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
public static string GenerateByConditionSql(object instance)
{
StringBuilder stringBuilder = new StringBuilder();
var type = instance.GetType();
//获取表名称
string tablename = GetRealTableNmae(type)!;
var flages = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
var props = type.GetProperties(flages);
//获取字符串
string filestring = string.Join(",", props.Select(propinfor => $"`{
GetRealColumName(propinfor)}`"));
stringBuilder.Append($"Select {
filestring} From {
tablename} where 1=1");
//判断条件查询--赋值的属性都为条件
foreach (var prop in props)
{
//反射获取值
var propvalue = prop.GetValue(instance);
if (!object.Equals(propvalue, null))
{
stringBuilder.Append($" And `{
GetRealColumName(prop)}`=@{
prop.Name}");
}
}
return stringBuilder.ToString();
}
#endregion
#region 实体类与表名、字段名称不一致
/// <summary>
/// 获取真实表名
/// </summary>
/// <param name="type"></param>
/// <param name="stringBuilder"></param>
/// <returns></returns>
public static string? GetRealTableNmae(Type type)
{
//默认是类型名称
var tablename = type.Name;
//判断Type上面是否有TableAttribute特性
if (type.IsDefined(typeof(TableAttribute), true))
{
var tableAttr = type.GetCustomAttributes<TableAttribute>().FirstOrDefault();
//获取特性设置的映射表名称
var tableAlias = tableAttr!.TableName;
if (!string.IsNullOrEmpty(tableAlias))
{
tablename = tableAlias;
}
}
return tablename;
}
/// <summary>
/// 通过属性获取真实的列名
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static string? GetRealColumName(PropertyInfo propertyInfo)
{
string columname = propertyInfo.Name;
if(propertyInfo.IsDefined(typeof(ColumnAttribute)))
{
var columnAttr = propertyInfo.GetCustomAttribute<ColumnAttribute>();
var columnAlias = columnAttr?.ColumnName;
if (!string.IsNullOrEmpty(columnAlias))
{
columname = columnAlias;
}
}
return columname;
}
#endregion
#region 获取主键、非主键、非空字段的字段与值 并添加到MySql参数列表
/// <summary>
/// 获取主键的字段与值
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private static IEnumerable<MySqlParameter> GetPrimaryParameters(object instance)
{
Type type = instance.GetType();
List<MySqlParameter> mySqlParameters = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(PropInfo => PropInfo.IsDefined(typeof(IdAttribute)))
.Select(propinfor => new MySqlParameter
{
//占位符的名称
ParameterName = $"@{
propinfor.Name}",
//设置占位符的值(反射方式获取值)
Value = propinfor.GetValue(instance)
}).ToList();
return mySqlParameters;
}
/// <summary>
/// 获取非主键的字段与值
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private static IEnumerable<MySqlParameter> GetNoPrimaryParameters(object instance)
{
Type type=instance.GetType();
List<MySqlParameter> mySqlParameters=type.GetProperties(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly)
.Where(PropInfo=> !PropInfo.IsDefined(typeof(IdAttribute)))
.Select(propinfor=> new MySqlParameter
{
//占位符的名称
ParameterName = $"@{
propinfor.Name}",
//设置占位符的值(反射方式获取值)
Value = propinfor.GetValue(instance)
}).ToList();
return mySqlParameters;
}
/// <summary>
/// 获取非空字段与值的参数列表
/// </summary>
/// <param name="instance"></param>
/// <returns></returns>
public static IEnumerable<MySqlParameter> GetNotNULLParameters(object instance)
{
Type type = instance.GetType();
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
var props=type.GetProperties(flags);
List<MySqlParameter> mySqlParameters=new List<MySqlParameter>();
foreach (var prop in props)
{
//反射获取值
var propvalue = prop.GetValue(instance);
if (!object.Equals(propvalue,null))
{
MySqlParameter mySqlParameter = new MySqlParameter
{
ParameterName=$"@{
prop.Name}",
Value=propvalue
};
mySqlParameters.Add(mySqlParameter);
}
}
return mySqlParameters;
}
#endregion
}
3.封装方法
具体步骤为:
1.编写IDBHelper接口,规范MySql要用到的方法,其中各方法使用到的类BaseModel需要做限定(抽象类的使用)
2.编写类MySqlDBHelper,继承IDBHelper接口,实现各方法具体步骤
抽象类
/// <summary>
/// 做实体类限定
/// </summary>
public abstract class BaseModel
{
}
接口
internal interface IDBHelper
{
/// <summary>
/// 新增数据的方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
int? Insert<T>(T entity) where T : BaseModel;
/// <summary>
/// 修改数据方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
int? Update<T>(T entity) where T : BaseModel;
/// <summary>
/// 删除数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
int? Delete<T>(T entity)where T : BaseModel;
/// <summary>
/// 一次性查询所有数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
List<T>FindAll<T>() where T : BaseModel;
/// <summary>
/// 根据ID查询数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Findby_ID<T>(int ID) where T : BaseModel;
/// <summary>
/// 条件查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
List<T>? FindByCondition<T>(T entity)where T: BaseModel;
}
方法实现
public class MySqlDBHelper: IDBHelper
{
// 以配置文件方式读取
private static readonly string connectString = "Server=localhost;port=3306;Database=studb;Uid=root;Pwd=Yiqing7717";
public int? Delete<T>(T entity) where T : BaseModel
{
//1. 获取实体的类型
Type type = typeof(T);
//2. 生成SQL语句
var sql = SqlBuilder.GenerateSql(type, SqlType.Delete);
//3. 生成参数列表
var sqlparameters = SqlBuilder.GetSqlParameters(entity, SqlType.Delete);
//4.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if (connection.State == ConnectionState.Open)
{
//5.创建命令对象
var command = new MySqlCommand(sql, connection);
//6.添加参数列表
command.Parameters.AddRange(sqlparameters);
//7.执行sql语句
return command.ExecuteNonQuery();
}
return -1;
}
public List<T> FindAll<T>() where T : BaseModel
{
List<T> datalist = new List<T>();
//1.获取实体类型
Type type=typeof(T);
//2.生成sql语句
var sql = SqlBuilder.GenerateSql(type,SqlType.Select);
//3.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if(connection.State==ConnectionState.Open)
{
//4.创建命令对象
var command= new MySqlCommand(sql, connection);
//5.执行SQL语句获取阅读对象
using var reader=command.ExecuteReader();
//6.组装T对象添加到返回集合
while(reader.Read())
{
//7.在不知道运行时候类型的时候
var instance=Activator.CreateInstance(type);
//8.将阅读器中的数据转换为对应对象集合
RowTOObject(reader,instance);
datalist.Add((T)instance!);
}
}
return datalist;
}
public T Findby_ID<T>(int ID) where T : BaseModel
{
//1.获取实体类型
Type type = typeof(T);
T entity = (T)Activator.CreateInstance(type)!;
//获取主键字段
foreach (var prop in type.GetProperties())
{
if (prop.IsDefined(typeof(IdAttribute)))
{
//反射获取ID的值
prop.SetValue(entity, ID);
break;
}
}
//2.生成sql语句
var sql = SqlBuilder.GenerateSql(type,SqlType.ID_Select);
//3.获取参数值列表
var parameters = SqlBuilder.GetSqlParameters(entity,SqlType.Select);
//4.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if (connection.State == ConnectionState.Open)
{
//5.创建命令对象
var command = new MySqlCommand(sql, connection);
//6.设置参数值列表
command.Parameters.AddRange(parameters);
//7.执行SQL语句获取阅读对象
using var reader = command.ExecuteReader();
//8.组装T对象添加到返回集合
while (reader.Read())
{
//9.将阅读器中的一行数据转换为对应对象并封装到对应属性值,添加到对象集合
RowTOObject(reader, entity);
}
}
return entity;
}
private void RowTOObject(MySqlDataReader reader,object?instance)
{
//1.获取type类
var type=instance!.GetType();
//2.获取type类型中的所有的公共属性
var flags=BindingFlags.Instance | BindingFlags.Public| BindingFlags.DeclaredOnly;
var props=type.GetProperties(flags);
//3.循环属性集合为每一个属性赋值
foreach (var prop in props)
{
//获取属性对应真实的列名
var columnName=SqlBuilder.GetRealColumName(prop);
//反射获取属性的值
prop.SetValue(instance, reader[columnName] is DBNull? null : reader[columnName]);
}
}
public List<T>? FindByCondition<T>(T entity) where T : BaseModel
{
List<T> LSvalues= new List<T>();
//1.获取实体类型
Type type = typeof(T);
//2.生成sql语句
string sql = SqlBuilder.GenerateByConditionSql(entity);
//3.生成参数列表
var sqlparamters = SqlBuilder.GetSqlParameters(entity, SqlType.Condition_Select);
//4.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if (connection.State==ConnectionState.Open)
{
//5.创建命令对象
var command = new MySqlCommand(sql, connection);
//6.设置参数值列表
command.Parameters.AddRange(sqlparamters);
//7.执行SQL语句获取阅读对象
using var reader = command.ExecuteReader();
//8.组装T对象添加到返回集合
while (reader.Read())
{
var instance=Activator.CreateInstance(type);
//9.将阅读器中的一行数据转换为对应对象并封装到对应属性值,添加到对象集合
RowTOObject(reader, instance);
LSvalues.Add((T)instance!);
}
}
return LSvalues;
}
public int? Insert<T>(T entity) where T : BaseModel
{
//1. 获取实体的类型
Type type=typeof(T);
//2. 生成SQL语句
var sql = SqlBuilder.GenerateSql(type, SqlType.Insert);
//3. 生成参数列表
var sqlparameters = SqlBuilder.GetSqlParameters(entity,SqlType.Insert);
//4.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if(connection.State==ConnectionState.Open)
{
//5.创建命令对象
var command = new MySqlCommand(sql,connection);
//6.添加参数列表
command.Parameters.AddRange(sqlparameters);
//7.执行sql语句
return command.ExecuteNonQuery();
}
return -1;
}
public int? Update<T>(T Entity)where T : BaseModel
{
//1. 获取实体的类型
Type type = typeof(T);
//2. 生成SQL语句
var sql = SqlBuilder.GenerateSql(type, SqlType.Update);
//3. 生成参数列表
var sqlparameters = SqlBuilder.GetSqlParameters(Entity, SqlType.Update);
//4.连接数据库
using var connection = new MySqlConnection(connectString);
connection.Open();
if (connection.State == ConnectionState.Open)
{
//5.创建命令对象
var command = new MySqlCommand(sql, connection);
//6.添加参数列表
command.Parameters.AddRange(sqlparameters);
//7.执行sql语句
return command.ExecuteNonQuery();
}
return -1;
}
}
4.测试
#region 测试新增方法
{
//Student Student = new Student
//{
// StuName = "ib",
// StuGender = "女",
// StuAge = 30,
// StuBirthday = DateTime.Now
//};
//MySqlDBHelper MySqlDBHelper = new MySqlDBHelper();
//int? row = MySqlDBHelper.Insert(Student);
}
#endregion
#region 测试更新方法
{
//Student Student0 = new Student
//{
// StuId = 18,
// StuName = "dfd00",
// StuGender = "男",
// StuAge = 33,
// StuBirthday = DateTime.Now
//};
//var sqlhelper = new MySqlDBHelper();
//int? row0 = sqlhelper.Update(Student0);
}
#endregion
#region 测试删除方法
{
//Student Student0 = new Student
//{
// StuId = 18,
//};
//var sqlhelper = new MySqlDBHelper();
//int? row0 = sqlhelper.Delete(Student0);
}
#endregion
#region 测试全部查询方法
{
var sqlhelper = new MySqlDBHelper();
var result = sqlhelper.FindAll<Student>();
foreach (var item in result)
{
Console.WriteLine($"{
item.StuName}---{
item.StuBirthday}---{
item.StuGender}");
}
}
#endregion
#region 测试根据ID查询数据
{
//var sqlhelper = new MySqlDBHelper();
//var item = sqlhelper.Findby_ID<Student>(5);
//Console.WriteLine($"{item.StuName}---{item.StuBirthday}---{item.StuGender}");
}
#endregion
#region 根据条件查询
//var sqlhelper = new MySqlDBHelper();
//var stu = new Student
//{
// StuId = 25
//};
//var LSstu = sqlhelper.FindByCondition(stu);
//foreach (var stud in LSstu)
//{
// Console.WriteLine($"{stud.StuName}---{stud.StuAge}----{stud.StuBirthday}---{stud.StuGender}");
//}
#endregion