发表于2015-11-14
在系统开发的中,经常会有多条件的列表查询,需求是这样的:界面有多个条件输入框,用户可以选择任意组合输入,这些条件也可以不输入,如果没有输入值就不包含这个条件。要实现这样的需求一般思路是动态拼接sql语句中的where条件,我们知道拼接sql语句有sql注入风险,最简单的防sql注入就是采用参数查询。今天我就来介绍一下使用dapper命令参数动态拼接出最安全的sql语句。dapper是一个轻量级的、性能很好的orm框架,对dapper还不认识的可以看看我之前写的文章,.net平台性能很不错的轻型ORM类Dapper,相信你知道b 这个dapper肯定就会喜欢上的。
创建表:
CREATE TABLE Sys_Admin( [UID] [varchar](50) NOT NULL PRIMARY KEY NONCLUSTERED, [Name] [nvarchar](200) NOT NULL, [LoginName] [varchar](100) NOT NULL, [Pwd] [varchar](100) NOT NULL, [CreateTime] [datetime] NOT NULL default getdate() )插入数据:
insert into Sys_Admin(UID,Name,LoginName,Pwd,CreateTime) select newid(),'蓝狐seo管理系统','www.lanhuseo.com','lanhuseo',getdate() union all select newid(),'蓝狐','lanhu','lanhu',getdate() union all select newid(),'蓝狐软件工作室','www.lanhusoft.com','lanhusoft',getdate()查询数据:
select * from Sys_Admin结果如下图:
public List<MSys_Admin> GetAdminList(MSys_Admin model) { string sqlText = "select count(1) from Sys_Admin where 1=1"; var p = new DynamicParameters(); if (!string.IsNullOrEmpty(model.LoginName)) { sqlText += " and LoginName like @LoginName"; p.Add("LoginName", model.LoginName+"%"); } if (!string.IsNullOrEmpty(model.Name)) { sqlText += " and Name like @Name"; p.Add("Name","%"+ model.Name+"%"); } using (var conn = Common.GetConn()) { conn.Open(); var r = conn.Query<MSys_Admin>(sqlText, p); conn.Close(); return r.ToList(); } }
上面的GetAdminList传入了一个MSys_Admin类型的参数,查询结果会根据传入,也就是用户在界面是否输入了LoginName和Name两个值,当其不为null且不为空了字符串时才加上对应字段的条件过滤。这要用到了Dapper的DynamicParameters动态参数集合类,从上面可以看到可以能过Add方法加入参数。最后通过conn.Query<MSys_Admin>(sqlText, p)执行sql,,返回结果。因为用的是命令参数的形式,让sql注入无机可乘,所以这种方案是安全的。
当然ASP.NET mvc的防sql注入也可以通过AOP技术对所有的Action参数进行危险sql过滤,具体实现方案请看我之前写的文章:AOP实践--ASP.NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁
相关dapper实际项目源码下载:
基于ASP.NET MVC5和dapper的SEO关键词按天计费系统源码