码农一定会遇到写库的繁琐操作,字段少的话数据访问层的SQL语句封装还好实现,可是字段一旦多起来,比如十多个二十多个字段的话,SQL的封装将会是一个巨大的难题,并不是说难度有多大,而是这样的操作很繁琐,况且极容易出错,SQL语句一旦出错很难排查。我也是在开发中遇到了相同的问题,这样的问题总会浪费很多不必要的时间,所以我就想能不能提供一个公共的基础组件来实现繁琐的底层SQL语句操作,我们只需要调用一些简单的借口就能实现数据库的快捷的写库。
首先,写库时必要的信息包含:要写入的列名,还有就是数据实体。
(1)要写入的列名是根据业务需求会有所变化的,因此这个参数需要用户传入,数据模型必然是需要用户传入的。
(2)基础组件必然要有一个比较宽的使用范围,因此数据模型必然不可能是定值,因此这里需要泛型来实现。
(3)怎么从数据模型中获取我们需要写入的字段值?可以用反射的方法从用户输入的插入列名来反射对象的属性值。这就要求数据实体的属性名要和数据库的列名相一致。
其实该组件所用到的技术点就包括:泛型、反射、ADO.NET以及一些基础的数据处理的技术,比如LINQ、Lambda表达式。
基础组件代码如下:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; namespace Yibaobao.BasicKit { public class SqlHelper { /// <summary> /// 向数据库插入单个对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="conn">数据库链接</param> /// <param name="tablename">表名</param> /// <param name="columns">插入的列</param> /// <param name="obj">参数对象</param> /// <returns>影响行</returns> public static int Add<T>(IDbConnection conn, string tablename, string columns, T obj) { using (IDbCommand cmd = conn.CreateCommand()) { conn.Open(); string sql = string.Empty; sql = string.Format("insert into {0}({1}) values(", tablename, columns); var fields = columns.Split(','); var t = typeof(T); sql = fields.Aggregate(sql, (current, item) => current + string.Format("'{0}',", obj.GetType().GetProperty(item).GetValue(obj, null))); sql = sql.Substring(0,sql.Length - 1); sql += ");"; cmd.CommandText = sql; int res = cmd.ExecuteNonQuery(); return res; } } /// <summary> /// 向数据库插入一个数据集 /// </summary> /// <typeparam name="T">集合子类型</typeparam> /// <param name="conn">数据库链接</param> /// <param name="tablename">表名</param> /// <param name="columns">插入列</param> /// <param name="obj">参数列表对象</param> /// <returns>数据库操作影响行</returns> public static int Add<T>(IDbConnection conn, string tablename, string columns, List<T> obj) { using (IDbCommand cmd = conn.CreateCommand()) { conn.Open(); string sql = string.Empty; sql = string.Format("insert into {0}({1}) values", tablename, columns); var fields = columns.Split(','); var t = typeof(T); foreach (var buff in obj) { sql += "("; sql = fields.Aggregate(sql, (current, item) => current + string.Format("'{0}',", buff.GetType().GetProperty(item).GetValue(buff, null))); sql = sql.Substring(0, sql.Length - 1); sql += "),"; } sql = sql.Substring(0, sql.Length - 1); cmd.CommandText = sql; int res = cmd.ExecuteNonQuery(); return res; } } } }
测试的表结构如下:
数据实体类定义如下:
namespace Yibaobao.Model { public class TreatementExp { /// <summary> /// 性别 /// </summary> public string Sex { get; set; } /// <summary> /// 年龄 /// </summary> public string Age { get; set; } /// <summary> /// 医院 /// </summary> public string HospitalName { get; set; } /// <summary> /// 科室 /// </summary> public string Department { get; set; } /// <summary> /// 医生 /// </summary> public string Doctor { get; set; } /// <summary> /// 就诊证明 /// </summary> public string Certificate { get; set; } /// <summary> /// 诊断结论 /// </summary> public string DiagnosisConclusion { get; set; } /// <summary> /// 症状 /// </summary> public string Symptom { get; set; } /// <summary> /// 备注 /// </summary> public string Remark { get; set; } /// <summary> /// 创建时间 /// </summary> public string CreateTime { get; set; } } }
调用示例 代码:
using System; using System.Collections.Generic; using System.Data; using System.Data.Odbc; using System.Linq; using System.Text; using MySql.Data.MySqlClient; using Yibaobao.BasicKit; using Yibaobao.Model; namespace ConsoleTest { class Program { static void Main(string[] args) { var data=new TreatementExp(); data.Age = "23"; data.HospitalName = "华西医院"; data.Certificate = "XXXXX"; data.CreateTime = DateTime.Now.ToString(); data.Department = "五官科科"; data.Doctor = "XXX"; data.Sex = "男"; data.Symptom = "XXXXXX"; data.DiagnosisConclusion = "XXXXXX"; data.Remark = "XXXXX"; string connstr = "your mysql connection string"; using (IDbConnection conn =new MySqlConnection(connstr)) { var res = SqlHelper.Add<TreatementExp>(conn, "Treatmentexperience", "Sex,Age,HospitalName,Department,Doctor,Certificate,DiagnosisConclusion,Symptom,Remark,CreateTime",data); } } } }
亲测过!!