在实际的.net mvc 项目中,会有多个类库,生成不同的dll文件。
比如model类库存放基本类,bussiness类库存放业务操作,dao类库存放数据库去数操作,utils类库存放工具类等。
为了方便,会将操作MySQL的过程单独放在一个类库中。只在这个类库中引用MySQL提供的类库-MySql.Data。
而其他的数据操作类库需要操作数据库的时候,只需要引用这个操作类就可以,不需要再引用-MySql.Data。防止在应用过程中版本不一致而导致项目运行失败。
直接上代码:
/// <summary> /// 数据库操作类 /// </summary> public class MySqlOperation { public MySqlConnection conn; MySqlTransaction mySql_Tran; public MySqlOperation(string connStr) { conn = new MySqlConnection(connStr); } /// <summary> /// 打开服务器 /// </summary> public bool ConnOpen() { bool isOpen = false; try { if (conn.State != ConnectionState.Open) { conn.Open(); //isOpen = true; } if (conn.State == ConnectionState.Open) isOpen = true; } catch (Exception ex) { //LogTool.ExceptionLog(ex, "open database"); } return isOpen; } /// <summary> /// 关闭服务器 /// </summary> public void ConnClose() { if (conn.State != ConnectionState.Closed) conn.Close(); } /// <summary> /// 打开事务 /// </summary> /// <param name="cmd"></param> public void TranOpen(ref MySqlCommand cmd) { mySql_Tran = conn.BeginTransaction(); if (mySql_Tran != null) cmd.Transaction = mySql_Tran; } /// <summary> /// 关闭事务 /// </summary> /// <param name="as_Error"></param> public void TranClose(bool b) { if (mySql_Tran != null) { if (b) mySql_Tran.Commit(); else mySql_Tran.Rollback(); } } /// <summary> /// 获取存储过程cmd /// </summary> /// <param name="procName">存储过程名</param> /// <returns></returns> private MySqlCommand GetProcCommand(string procName, MySqlParameter[] paraList) { MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = procName; cmd.CommandType = CommandType.StoredProcedure; if (paraList != null) { foreach (MySqlParameter para in paraList) cmd.Parameters.Add(para); } cmd.Connection = conn; return cmd; } public MySqlCommand GetTextCommand(string sql) { MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = sql; cmd.CommandType = CommandType.Text; cmd.Connection = conn; return cmd; } public MySqlDataReader GetDataReader(string sql, CommandBehavior comBehavior = CommandBehavior.CloseConnection, bool isTran = false) { MySqlDataReader dr = null; try { if (!ConnOpen()) return null; MySqlCommand cmd = GetTextCommand(sql); dr = cmd.ExecuteReader(comBehavior); } catch (Exception ex) { //LogTool.ExceptionLog(ex, "get datareader", sql); if (isTran) TranClose(false); if (conn.State == ConnectionState.Open) { ConnClose(); } } return dr; } public MySqlCommand Cmd_Proc(string procName, MySqlParameter[] paraList, bool isTran = true) { MySqlCommand cmd = null; try { if (!ConnOpen()) return null; cmd = GetProcCommand(procName, paraList); if (isTran) TranOpen(ref cmd); cmd.ExecuteNonQuery(); if (isTran) TranClose(true); ConnClose(); } catch (Exception ex) { cmd = null; //LogTool.ExceptionLog(ex, "exec proc:" + procName); if (isTran) TranClose(false); if (conn.State == ConnectionState.Open) { ConnClose(); } } finally { ConnClose(); } return cmd; } public DataSet GetDataSet(string sql, bool isTran = false) { DataSet ds = null; try { if (!ConnOpen()) return null; MySqlCommand cmd = GetTextCommand(sql); if (isTran) TranOpen(ref cmd); ds = new DataSet(); MySqlDataAdapter da = new MySqlDataAdapter(cmd); da.Fill(ds); if (isTran) TranClose(true); } catch (Exception ex) { //LogTool.ExceptionLog(ex, "get datatable:" + sql); if (isTran) TranClose(false); } finally { ConnClose(); } return ds; } public int ExecSQL(string sql, bool isTran = true, int cmdTimeoutSec = 0) { int res = -1; try { ConnOpen(); MySqlCommand cmd = GetTextCommand(sql); if (isTran) TranOpen(ref cmd); res = cmd.ExecuteNonQuery(); if (isTran) TranClose(true); } catch (Exception ex) { //LogTool.SqlLog(sql); //LogTool.ExceptionLog(ex, "Exce sql:" + sql); if (isTran) TranClose(false); } finally { ConnClose(); } return res; } public DataTable GetDataTable(string sql, bool isTran = false) { DataTable dt = null; try { ConnOpen(); MySqlCommand cmd = GetTextCommand(sql); if (isTran) TranOpen(ref cmd); dt = new DataTable(); MySqlDataAdapter da = new MySqlDataAdapter(cmd); da.Fill(dt); if (isTran) TranClose(true); } catch (Exception ex) { //LogTool.ExceptionLog(ex, "get datatable:" + sql); if (isTran) TranClose(false); } finally { ConnClose(); } return dt; } /// <summary> /// 单条查询结果转换成类 /// </summary> /// <param name="conStr">数据库连接串</param> /// <param name="sql">数据库操作语句</param> /// <returns></returns> public T getClass<T>(string sql) where T : class,new() { T tClass = null; try { MySqlDataReader reader = GetDataReader(sql); if (reader != null) { tClass = DataReaderUtils.DataReaderToClass<T>(reader); } reader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { ConnClose(); } return tClass; } /// <summary> /// 多条结果转化为List列表 /// </summary> /// <param name="conStr"></param> /// <param name="sql"></param> /// <returns></returns> public List<T> getClassList<T>(string sql) where T : class, new() { List<T> tClassList = null; try { MySqlDataReader reader = GetDataReader(sql); if (reader != null) { tClassList = DataReaderUtils.DataReadertoList<T>(reader); } reader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { ConnClose(); } return tClassList; } }
以上这个类删除getClass()和getClassList()方法,完全可以直接拿来用,也不用做其他操作。select语句操作结果,用datatable表处理。update,insert,delete语句,直接用ExecSQL()方法处理。
但是,用datatable来对数据进行处理,总觉的很不方便。如果能直接返回到类或者List,你这样的话就对数据进行操作就方便了许多。
所以,我们要结合Attribute和反射对取出来的数据进行处理,MySQL取出来的数据都是放在MySqlDataReader这个类里。
思路是
1. 对拿类里的属性上的特性对数据库取出来的数据列头名进行比对,
2. 属性的类型对数据类型进行比对。
3. 满足的话,将数据赋值到属性的value中。不满足跳过,进行下一个比对,直至结束。
但是类又不固定,各个类里的属性,成员,方法又不一样,所以,我们还要使用泛型。由于只是select语句操作会使用到泛型。所以,我将这两个情况单独提出来放到其他的一个工具类里。
首先,利用特性取class数据或list数据
/// <summary> /// Datareader反射使用 标记 /// 标记 属性在Datareader 中的字段名 以便反射赋值 /// </summary> [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class DataReaderModelAttribute : Attribute { private string datareaderfieldname; public string Datareaderfieldname { get { return this.datareaderfieldname; } } public DataReaderModelAttribute(string datareaderfielname) { this.datareaderfieldname = datareaderfielname; } }
这个特性是用在类上的属性上,用法如下
其中,红框和蓝框的值不一定一致,但红框里的值一定要和数据库里对应的字段值保持一致。
接下来,将MySqlDataReader里数据循环放到类里。
/// <summary> /// dataReader转换工具 /// </summary> public class DataReaderUtils { /// <summary> /// 放到最后 转换 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="DataReader"></param> /// <returns></returns> public static List<T> DataReadertoList<T>(MySqlDataReader DataReader) where T : new() { List<T> t_lis = new List<T>(); if (DataReader != null) { if (!DataReader.IsClosed) {//暂未关闭 while (DataReader.Read()) { List<string> DataReaderColumnNames = ColumnNames(DataReader); T t = new T(); Type type = t.GetType(); PropertyInfo[] p_list = type.GetProperties(); FieldInfo[] fieldInfos = type.GetFields(); if (p_list != null && p_list.Length > 0) { foreach (var i in p_list) { Attribute datareaderattr = i.GetCustomAttribute(typeof(DataReaderModelAttribute), false); if (datareaderattr != null) { DataReaderModelAttribute dataattr = (DataReaderModelAttribute)datareaderattr; DataReader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= ‘" + dataattr.Datareaderfieldname + "‘"; if (!DataReaderColumnNames.Contains(dataattr.Datareaderfieldname)) { continue; } if (DataReader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) {//如果是dbnull continue; } if (DataReader[dataattr.Datareaderfieldname].GetType().Name == "Int32") { int vals = Convert.ToInt32(DataReader[dataattr.Datareaderfieldname]); i.SetValue(t, vals, null); } if (DataReader[dataattr.Datareaderfieldname].GetType().Name == "Int64") { int vals = Convert.ToInt32(DataReader[dataattr.Datareaderfieldname]); i.SetValue(t, vals, null); } else { i.SetValue(t, DataReader[dataattr.Datareaderfieldname], null); } } else { continue; } } t_lis.Add(t); } else { if (fieldInfos != null && fieldInfos.Length > 0) { foreach (var i in fieldInfos) { Attribute datareaderattr = i.GetCustomAttribute(typeof(DataReaderModelAttribute), false); if (datareaderattr != null) { DataReaderModelAttribute dataattr = (DataReaderModelAttribute)datareaderattr; DataReader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= ‘" + dataattr.Datareaderfieldname + "‘"; if (!DataReaderColumnNames.Contains(dataattr.Datareaderfieldname)) { continue; } if (DataReader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) {//如果是dbnull continue; } if (DataReader[dataattr.Datareaderfieldname].GetType().Name == "Int32") { int vals = Convert.ToInt32(DataReader[dataattr.Datareaderfieldname]); i.SetValue(t, vals); } if (DataReader[dataattr.Datareaderfieldname].GetType().Name == "Int64") { int vals = Convert.ToInt32(DataReader[dataattr.Datareaderfieldname]); i.SetValue(t, vals); } else { i.SetValue(t, DataReader[dataattr.Datareaderfieldname]); } } else { continue; } } t_lis.Add(t); } //DataReader.Close(); //break; } } // DataReader.Close(); return t_lis; } else { //关闭 return t_lis; } } else { return t_lis; } } /// <summary> /// 获取datareader 列字段名称集合 /// </summary> /// <param name="pReader"></param> /// <returns></returns> private static List<string> ColumnNames(MySqlDataReader pReader) { List<string> Columnnames = new List<string>(); for (int i = 0; i < pReader.FieldCount; i++) { Columnnames.Add(pReader.GetName(i)); } return Columnnames; } /// <summary> /// datareader to class object datareader 转成 一个对象 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T DataReaderToClass<T>(MySqlDataReader datareader) where T : class, new() { T t = new T(); Type type = t.GetType(); if (datareader != null) { PropertyInfo[] infos = type.GetProperties(); FieldInfo[] fieldInfos = type.GetFields(); if (infos != null && infos.Length > 0) { if (datareader.Read()) { List<string> DataReaderColumnNames = ColumnNames(datareader); foreach (var i in infos) { Attribute attr = i.GetCustomAttribute(typeof(DataReaderModelAttribute)); if (attr != null) { DataReaderModelAttribute dataattr = (DataReaderModelAttribute)attr; if (!DataReaderColumnNames.Contains(dataattr.Datareaderfieldname)) { continue; } if (datareader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) {//如果是dbnull continue; } if (!datareader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) { i.SetValue(t, datareader[dataattr.Datareaderfieldname]); } else { continue; } } else { continue; } } return t; } else { return null; } } else { if (fieldInfos != null && fieldInfos.Length > 0) { if (datareader.Read()) { List<string> DataReaderColumnNames = ColumnNames(datareader); foreach (var i in fieldInfos) { Attribute attr = i.GetCustomAttribute(typeof(DataReaderModelAttribute)); if (attr != null) { DataReaderModelAttribute dataattr = (DataReaderModelAttribute)attr; if (!DataReaderColumnNames.Contains(dataattr.Datareaderfieldname)) { continue; } if (datareader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) {//如果是dbnull continue; } if (!datareader[dataattr.Datareaderfieldname].Equals(DBNull.Value)) { i.SetValue(t, datareader[dataattr.Datareaderfieldname]); } else { continue; } } else { continue; } } return t; } else { return null; } } else { return null; } } } else { return null; } } }
然后,在MySqlOperation里的getClass()方法和getClassList()方法就可以直接用了。
使用方法如下:
先实例化MySqlOperation类,然后调用。
class PersonDao { string conStr = "server=localhost;port=3306;database=XXX;uid=root;password=root;Allow User Variables=True"; public List<Person> GetAllPersonList(int index = 1, int pageSize = 10) { index = (index - 1) * 10; string sql = $"SELECT * FROM t_appoint_user limit {index},{pageSize}"; MySqlOperation sqlOperation = new MySqlOperation(conStr); return sqlOperation.getClassList<Person>(sql); } public Person GetPersonById(string id) { string sql = $"SELECT * FROM t_appoint_user WHERE rID = ‘{id}‘"; MySqlOperation sqlOperation = new MySqlOperation(conStr); return sqlOperation.getClass<Person>(sql); } }
注:打日志,加try-catch
原文:https://www.cnblogs.com/wjtstudy/p/12435808.html
如果您也喜欢它,动动您的小指点个赞吧