C#用反射来封装数据库操作类

这几天在学习反射的应用,就有想法在封装数据库类的时候用上,下面就是这几天封装的类

用的泛型封装的,可以查询不同的表,不用每个表写不同的一长串的Sql语句了.感觉省事多了,

只是在多条件查询时Where后面的要自己手动输入传进去就OK了.

#define OLEDB_
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Reflection;

namespace WindowsFormsApp_反射的应用
{
#if OLEDB_
    using MyCommand = OleDbCommand;
    using MyConnection = OleDbConnection;
    using MyDataAdapter = OleDbDataAdapter;
    using MyDataReader = OleDbDataReader;
    using myParameter = OleDbParameter;
#elif SQL_
    using MyCommand = SqlCommand;
    using MyConnection =SqlConnection;
    using MyDataAdapter =SqlDataAdapter;
    using MyDataReader =SqlDataReader;
    using myParameter = SqlParameter;

#endif

    /// <summary>
    /// 泛型数据库操作类
    /// <para>泛型类要和操作的数据库中表的名称,字段名称都要一样</para>
    /// 
    /// 作者:       greenleaf1976
    /// 创建时间:   2017-07-17
    /// </summary>
    public class MYADO_T
    {
        private static readonly string myDataFileName = @"D:\MyAccessFile\myTonxilu.accdb";

        private static readonly string CONN_STRING = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={myDataFileName};Persist Security Info=False";

        public static MyConnection conn = null;

        public MYADO_T() { }
        ~MYADO_T() { conn.Dispose(); }

        /// <summary>
        /// 初始化conn对象(保证打开连接状态)
        /// </summary>
        private static void InitConnection()
        {
            if (conn == null)
                conn = new MyConnection(CONN_STRING);

            if (conn.State == ConnectionState.Closed)
                conn.Open();

            if (conn.State == ConnectionState.Broken)
            {
                conn.Close();
                conn.Open();
            }
        }

        /// <summary>
        /// 获得表中的数据
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="conditionsSql">多种查询条件,格式(mName='张三')</param>
        /// <returns>返回查询结果表</returns>
        public static DataTable GetDataTableAll<T>(string conditionsSql = null)
        {
            DataTable dt = new DataTable();
            MyCommand cmd = null;
            MyDataAdapter da = null;

            Type ty = typeof(T);//获得泛型类型

            //拼接Sql字符串
            string sql = $"SELECT * FROM [{ty.Name}]";
            if (conditionsSql != null)
                sql += $" WHERE {conditionsSql}";

            InitConnection();

            try
            {
                cmd = new MyCommand(sql, conn);
                da = new MyDataAdapter(cmd);
                da.Fill(dt);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                da.Dispose();
                cmd.Dispose();
                conn.Close();
            }
            return dt;

        }

        /// <summary>
        /// 更新指定条件的数据
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="conditionsSql">多种查询条件,格式(mName='张三' and ...)</param>
        /// <param name="t">用于更新数据库中的新数据</param>
        /// <returns>返回受影响的行数</returns>
        public static int UpdateDataTable<T>(string conditionsSql, T t)
        {
            int nRet = 0;
            string intoSql = null;
            string fileName = null;
            MyCommand cmd = null;
            List<myParameter> parList = new List<myParameter>();

            Type ty = t.GetType();  //获得泛型的类型

            //获得Sql查询语句和添加参数列表
            foreach (FieldInfo v in ty.GetFields())
            {
                fileName += v.Name + $"=@{v.Name},";    //拼接字段名和值的查询字符串
                myParameter par = new myParameter($"@{v.Name}", v.GetValue(t)); //添加参数列表到parList中
                parList.Add(par);
            }
            fileName = fileName.Substring(0, fileName.Length - 1);  //去掉最后一个,号

            //拼接Sql查询语句字符串
            intoSql = $"UPDATE [{ty.Name}] SET {fileName} WHERE {conditionsSql}";

            InitConnection();

            try
            {
                cmd = new MyCommand(intoSql, conn);
                cmd.Parameters.Clear();
                cmd.Parameters.AddRange(parList.ToArray());//添加参数列表
                nRet = cmd.ExecuteNonQuery();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {

                cmd.Dispose();
                conn.Close();
            }

            return nRet;

        }

        /// <summary>
        /// 删除指定条件的数据
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="conditionsSql">多种查询条件,格式(mName='张三' and ...)</param>
        /// <returns>返回受影响的行数</returns>
        public static int DeleatDataTable<T>(string conditionsSql)
        {
            int nRet = 0;
            MyCommand cmd = null;

            Type typ = typeof(T);
            string sql = $"DELETE FROM {typ.Name} WHERE {conditionsSql}";
            try
            {
                InitConnection();
                cmd = new MyCommand(sql, conn);
                nRet = cmd.ExecuteNonQuery();

            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
                conn.Close();
            }

            return nRet;
        }

        /// <summary>
        /// 插入新的数据
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="t">要插入的新数据对象</param>
        /// <returns>成功返回True,失败False</returns>
        public static bool InsertDataTable<T>(T t)
        {
            int nRet = 0;
            string intoSql = null;
            string fileName = null;
            string fileValue = null;
            MyCommand cmd = null;
            List<myParameter> parList = new List<myParameter>();

            Type ty = t.GetType();

            foreach (FieldInfo v in ty.GetFields())
            {
                fileName += v.Name + ",";   //拼接列名字符串
                fileValue += $"@{v.Name},"; //拼接参数化值的字符串

                //创建新的参数化查询,并添加到列表中
                myParameter par = new myParameter($"@{v.Name}", v.GetValue(t));
                parList.Add(par);
            }
            fileName = fileName.Substring(0, fileName.Length - 1);  //去除最后的,号
            fileValue = fileValue.Substring(0, fileValue.Length - 1);   //去除最后的,号

            //拼接添加数据的Sql语句
            intoSql = $"INSERT INTO [{ty.Name}] ({fileName}) VALUES ({fileValue})";
           
            try
            {
                InitConnection();
                cmd = new MyCommand(intoSql, conn);
                cmd.Parameters.Clear();
                cmd.Parameters.AddRange(parList.ToArray());//添加参数列表
                nRet = cmd.ExecuteNonQuery();  
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                cmd.Dispose();
                conn.Close();
            }



            return nRet == 1;
        }

        /// <summary>
        /// 不断开连接的读取数据,多用于递归查询的调用
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="conditionsSql">多种查询条件,格式(mName='张三' and ...)</param>
        /// <returns>返回DataReader对象</returns>
        public static MyDataReader GetDataReaddr<T>(string conditionsSql)
        {
            MyDataReader drRead = null;
            MyCommand cmd = null;


            Type ty = typeof(T);
            string sql = $"SELECT * FROM [{ty.Name}]";
            if (conditionsSql != null)
                sql += $" WHERE {conditionsSql}";

            InitConnection();

            try
            {
                cmd = new MyCommand(sql, conn);
                drRead = cmd.ExecuteReader();
            }
            catch (Exception ex)
            {
                throw ex;
            }
           
            return drRead;
        }

        /// <summary>
        /// 查找指定条件,并返回单个对象
        /// </summary>
        /// <typeparam name="T">和表中相对应的类或结构体</typeparam>
        /// <param name="conditionsSql">多种查询条件,格式(mName='张三' and ...)</param>
        /// <returns>返回单个对象的数据</returns>
        public static T FindDataTable<T>(string conditionsSql)
        {
            
            MyDataReader drRead = null;

            Type ty = typeof(T);    //获得泛型的类型
            object obj =Activator.CreateInstance(ty);//根据类型创建新的object实例对象(不要实例成具体的类型)

            
            try
            {
                drRead = GetDataReaddr<T>(conditionsSql);    //读取数据库中的数据         
                if(drRead.Read())
                {
                    foreach (FieldInfo v in ty.GetFields())
                    {
                        //根据字段类型给字段赋值
                        switch(v.FieldType.FullName)
                        {
                            case "System.Int32"://int         
                                v.SetValue(obj, int.Parse(drRead[v.Name].ToString()));
                                break;

                            case "System.Double"://double
                                v.SetValue(obj, double.Parse(drRead[v.Name].ToString()));
                                break;

                            case "System.String"://string
                                v.SetValue(obj, drRead[v.Name].ToString());
                                break;

                            case "System.Object"://object
                                v.SetValue(obj, drRead[v.Name]);
                                break;

                            case "System.Boolean"://bool
                                v.SetValue(obj, bool.Parse(drRead[v.Name].ToString()));
                                break;

                            case "System.Char"://char
                                v.SetValue(obj, char.Parse(drRead[v.Name].ToString()));
                                break;

                            default:    //其他类型,以后用的时候再加上
                                throw new Exception("没有指定转换的类型!!!");

                        }                
                    }
                }
                else
                    return default(T);  //没有找到返回默认的泛型对象,不是null
                
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                drRead.Close();
                conn.Close();
            }
            //返回时转换成对应的泛型类型
            return (T)obj;
        }
    }
}

在程序中调用:

1.显示全部数据

 DataTable dt = MYADO_T.GetDataTableAll<mTable>();
            foreach (DataRow dr in dt.Rows)
            {
                foreach (object v in dr.ItemArray)
                {

                    Console.Write(v.ToString() + "\t");
                }
                Console.WriteLine();
            }

2.查询指定条件

返回一个对象

Form2 frm = new Form2();
            if(frm.ShowDialog()==DialogResult.OK)
            {
                mTable tl = MYADO_T.FindDataTable<mTable>("mName='张三2');
                if (tl.mName == null)
                    MessageBox.Show("没有找到数据");
                else
                    MessageBox.Show(tl.ToString());
            }

 

返回多个对象就返回DataTable 

DataTable dt = MYADO_T.GetDataTableAll<mTable>("mAge>30");
            foreach (DataRow dr in dt.Rows)
            {
                foreach (object v in dr.ItemArray)
                {

                    Console.Write(v.ToString() + "\t");
                }
                Console.WriteLine();
            }

 3.删除数据,这可以删除多个数据,只要符合条件的都会删除

int nRet = MYADO_T.DeleatDataTable<mTable>("mName='张三'");
            Console.WriteLine(nRet);

4.插入数据

 mTable tl = new mTable()
            {
                mName = "李雪琴",
                mSex = "女",
                mAge = 20,
                mFenlei = "明星",
                mTel = "132009833"
            };

//这名没有写泛型类型是因为编译器提示我简化了的.本来我是写了泛型类型的.
            bool bol = MYADO_T.InsertDataTable(tl);
            if (bol)
                MessageBox.Show("添加数据成功!");

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT是一种跨平台的开发框架,它提供了丰富的库和工具,用于开发图形用户界面和其他应用程序。在QT中,我们可以使用它的数据库模块来操作各种不同型的数据库。 为了更方便地操作数据库,我们可以封装一个接口。该接口可以提供一系列的方法和功能,用于连接数据库、执行数据库操作(如查询、插入、删除、更新等)和关闭数据库连接。 首先,我们可以在接口的构造函数中初始化数据库连接。根据需要,我们可以使用不同的数据库驱动程序来连接不同型的数据库,如MySQL、SQLite、Oracle等。接口可以提供方法,用于设置数据库连接参数,如主机名、端口号、数据库名、用户名和密码等。 接口还可以提供执行数据库操作的方法。例如,我们可以定义一个方法来执行查询操作,接收一个SQL语句作为参数,并返回一个结果集。我们可以在具体的实现中使用QT提供的API来执行SQL查询,并将结果转化为Qt数据结构,如QSqlQueryModel。 另外,我们可以定义其他方法来执行插入、删除和更新等操作。这些方法可以接收不同的参数,如表名、列名和值等。在具体的实现中,我们可以使用QT提供的API来执行相应的数据库操作。 最后,为了防止资源泄漏,我们需要在接口的析构函数中关闭数据库连接。这样,在接口的对象被销毁时,数据库连接也会随之关闭。 综上所述,通过封装一个操作数据库的接口,我们能够更加方便地使用QT来操作不同型的数据库。这样可以提高开发效率,并且使得代码更加易于维护和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值