码农一定会遇到写库的繁琐操作,字段少的话数据访问层的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);
}
}
}
}
亲测过!!