封装一个数据库操作的类,如果类包含有多条SQL语句,Parameters参数该怎么写吗?

蜗牛学编程 2021-01-24 08:52:44
练习封装类时发现困难点:
为避免SQL注入攻击,要给SQL传参。如果仅是单条SQL语句没问题,直接加一个Parameters SQLParameter[]作为占位就可以。
但如果是多条SQL,每条SQL都要有不同的参数,那该怎么加这个Parameters吗?占位符只允许放一个Parameters,放在最后面。
不知道我有没有说清楚。
请老师们指点。

...全文
1419 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lvwl-CN 2021-02-03
  • 打赏
  • 举报
回复
要是执行3条sql,你还得再写一个方法?4条5条、、、呢? 换个思路吧
正怒月神 2021-01-29
  • 打赏
  • 举报
回复
引用 14 楼 蜗牛学编程 的回复:
[quote=引用 13 楼 正怒月神 的回复:]我的建议是。。。 根本不需要封装,有多条sql语句的方法。。。 原因在于, 只是同一个方法,执行了2遍不同sql语句,仅此而已。 其次假设你拥有很复杂的逻辑,又不想在程序中完成,那就使用存储过程。
版主您好。 是这样一个情况,我写了一个系统,里面很多页面。然后要求数据在页面之间来回修改后传送,而传送完后要写一条记录,记录下修改了什么内容。为了方便,我就想封装成一个类,不想拆开成为两个。(拆开两个就没这个问题,但这样要多写一次方法,而且数据库也会多一次打开关闭,频繁操作,会不会影响效率?)[/quote] 方法多种多样, 与其把你的sqlhelper改的不这么简单通用, 还不如 1 将新增和记录,两个动作在逻辑层去聚合。 #15 已经说了很多种方法,就不赘述了。 2 将改记录动作,通过aop去实现,作为一个注解。 在需要的方法上,使用注解就能而不会影响到业务本身。
wanghui0380 2021-01-29
  • 打赏
  • 举报
回复
思维有很多种,聚合是一类。 通知也是一类。还是前面说的如果说你单纯就是走一步看一步,那就把自己给困死了。 我们来看几类应用 1.注册用户-------------------------------积分+50 2.荣誉系统-----------完成任务------------荣誉值+1,荣誉称号xxx 3.推荐系统---------------点击商品-------------生成推荐系统 如果说就走一步是一步。那么我说注册用户的积分+50,荣誉值+1,荣誉称号“超级新人”,生成新人推荐任务,这几个同时来,你打算怎么写sql?? 这时候还是各做各的,使用“中间件”订阅 “用户系统/新人注册”topic了。 所以当你说你的老板要求你在修改数据的时候记录一下谁修改的,那么你其实要做的事情是 给个“日志记录/db修改操作”topic通知,让日志系统去完成。而不是这里弄个sql1,sql2
xiaoxiangqing 2021-01-29
  • 打赏
  • 举报
回复
占位符只允许放一个Parameters
wanghui0380 2021-01-29
  • 打赏
  • 举报
回复
引用 14 楼 蜗牛学编程 的回复:
[quote=引用 13 楼 正怒月神 的回复:]我的建议是。。。 根本不需要封装,有多条sql语句的方法。。。 原因在于, 只是同一个方法,执行了2遍不同sql语句,仅此而已。 其次假设你拥有很复杂的逻辑,又不想在程序中完成,那就使用存储过程。
版主您好。 是这样一个情况,我写了一个系统,里面很多页面。然后要求数据在页面之间来回修改后传送,而传送完后要写一条记录,记录下修改了什么内容。为了方便,我就想封装成一个类,不想拆开成为两个。(拆开两个就没这个问题,但这样要多写一次方法,而且数据库也会多一次打开关闭,频繁操作,会不会影响效率?)[/quote] 这样回答很好,但是我们说请回答“封装的意义”,你为啥要封装,仅仅是为了你说的这个功能?仅仅是说,我嫌不好看,要多敲几句代码 封装是为了复用。那么sql1,sql2,如果说要复用为啥不是sql1,sql2,sql3,sqlN,你说对吧。 当然我们不是更那几个5年兄弟一样说这是批评你,我们只是告诉你如果要走这条路那就需要多看几步,单单走一步看一步的话其实坑的是自己。因为你就只看了一步,明天你领导说,写完sql2,在给我做个统计,你又打算怎么封装 所以他最终的事情结果就说版主告诉你的,别做走一步看一步的封装。这种封装看着很好,但是给自己挖坑 想不坑自己我们一次只做一件事情,只是用聚合类的手段聚合 比如pipeline,职责链。当然他叫什么不重要,重要的聚合的思维。 为了体现思维,我就特地不叫他为职责链。我就叫他批处理如何 批处理 批处理任务=new批处理() .add任务(new sql任务(sql1,参数)) .add任务(new sql任务(sql2,参数)) 任务上下文 =new 任务上下文() 批处理任务.执行(任务上下文 ) 这样就好,一个任务就是一个任务,我们只是聚合他,而不是改变他
wanghui0380 2021-01-29
  • 打赏
  • 举报
回复
同样的设计思路 Service.AddSocpe<数据库操作辅助类>() //本次Request有效 Service.Add<全局日志记录>() 这种设计依旧可以把 -------------------------------------------------------------- 在换个表现AOP [日志记录拦截属性] xxxAction() 还是可以接受把
wanghui0380 2021-01-29
  • 打赏
  • 举报
回复
实际项目不拘泥形式,只要你们不跟着那个园子走。能真正理解设计意图,就会发现那个园子的路太偏(包括动则各种这个vs那个,各种string血案,动则DDD典范ABP,动则一次连接数据库,多次连接数据库的无端折腾,动则改进系统性能的XXX建议) 回你的问题,我们来看看如果你理解设计意图了,你就算不跟着他们走,你的问题也不成为问题 Service.AddSocpe<数据库操作辅助类>() //本次Request有效 Service.AddTransient<聚合操作任务A>() //永远瞬时,当然我这里不过渡设计,仅仅表现微软这套框架的设计意图,所以把聚合操作任务直接放在全局ServiceCollection里 Service.AddTransient<聚合操作任务B>() class 聚合操作任务A(数据库操作辅助类) { 执行() { 数据库操作辅助类.sqlExecute() } } class XXXControl(聚合操作任务A,聚合操作任务B) { xxxxAction() { 聚合操作任务A.执行() 聚合操作任务B.执行() } } 我们做什么了?我们什么都没做,完完全全的netcore的标准执行代码。看他怎么样? 需要多余的操作么?不需要 Socpe的数据库操作类,在同一个Reqeust下他回实例几次?1次,所以你操心的问题,原本就不存在。 而写法上,你该怎么写就怎么写,不需要纠结那个园子里越走越窄的死胡同
code_long 2021-01-29
  • 打赏
  • 举报
回复
引用 19 楼 code_long 的回复:

    public class SqlHelper
    {
        public string GetSqlConnection()
        {
            return "";
        }

        public void Operate(params SqlParameterModel[] models)
        {
            using (SqlConnection con = new SqlConnection(this.GetSqlConnection()))
            {
                foreach (var item in models)
                {
                    using (SqlCommand cmd = new SqlCommand(item.StrSql, con))
                    {
                        cmd.Parameters.AddRange(item.Prm);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
    }

    public class SqlParameterModel
    {
        public SqlParameterModel()
        {
            StrSql = string.Empty;
        }
        public string StrSql { get; set; }
        public SqlParameter[] Prm { get; set; }
    }
执行的SQl,可以再加上SqlTransaction
code_long 2021-01-29
  • 打赏
  • 举报
回复

    public class SqlHelper
    {
        public string GetSqlConnection()
        {
            return "";
        }

        public void Operate(params SqlParameterModel[] models)
        {
            using (SqlConnection con = new SqlConnection(this.GetSqlConnection()))
            {
                foreach (var item in models)
                {
                    using (SqlCommand cmd = new SqlCommand(item.StrSql, con))
                    {
                        cmd.Parameters.AddRange(item.Prm);
                        cmd.ExecuteNonQuery();
                    }
                }
            }
        }
    }

    public class SqlParameterModel
    {
        public SqlParameterModel()
        {
            StrSql = string.Empty;
        }
        public string StrSql { get; set; }
        public SqlParameter[] Prm { get; set; }
    }
正怒月神 2021-01-28
  • 打赏
  • 举报
回复
我的建议是。。。 根本不需要封装,有多条sql语句的方法。。。 原因在于, 只是同一个方法,执行了2遍不同sql语句,仅此而已。 其次假设你拥有很复杂的逻辑,又不想在程序中完成,那就使用存储过程。
蜗牛学编程 2021-01-28
  • 打赏
  • 举报
回复
引用 13 楼 正怒月神 的回复:
我的建议是。。。 根本不需要封装,有多条sql语句的方法。。。 原因在于, 只是同一个方法,执行了2遍不同sql语句,仅此而已。 其次假设你拥有很复杂的逻辑,又不想在程序中完成,那就使用存储过程。
版主您好。 是这样一个情况,我写了一个系统,里面很多页面。然后要求数据在页面之间来回修改后传送,而传送完后要写一条记录,记录下修改了什么内容。为了方便,我就想封装成一个类,不想拆开成为两个。(拆开两个就没这个问题,但这样要多写一次方法,而且数据库也会多一次打开关闭,频繁操作,会不会影响效率?)
白衣如花 2021-01-27
  • 打赏
  • 举报
回复
引用 7 楼 蜗牛学编程 的回复:
[quote=引用 5 楼 白衣如花 的回复:]用list,别用params


public void operate(List<string> sqls, List<SqlParameter[]> param)

你好,可以帮忙完整的写一下这段代码吗?没用过list<>的方式,代码正文不知道该怎么写
[/quote]你试试走出舒适区,查一下List怎么用,认识一下尖括号

语法和逻辑和数组类似,很好理解,不难

如果学过数据结构就知道这是个线性表,而且很可能是链表

不查不学怎么进步呢
蜗牛学编程 2021-01-27
  • 打赏
  • 举报
回复
引用 10 楼 锤子馆长 的回复:
[quote=引用 楼主 蜗牛学编程 的回复:]练习封装类时发现困难点: 为避免SQL注入攻击,要给SQL传参。如果仅是单条SQL语句没问题,直接加一个Parameters SQLParameter[]作为占位就可以。 但如果是多条SQL,每条SQL都要有不同的参数,那该怎么加这个Parameters吗?占位符只允许放一个Parameters,放在最后面。 不知道我有没有说清楚。 请老师们指点。
为啥2个SQL语句 合并成一个字符串 统一执行 就可以了[/quote] 因为两条SQL语句是有不同作用的啊。譬如说我先把一组数据copy转移到另外一个表格,然后再在原表格上进行删除。这样没办法合并成一个字符串呀
datafansbj 2021-01-27
  • 打赏
  • 举报
回复
引用 6 楼 蜗牛学编程 的回复:
[quote=引用 4 楼 datafansbj 的回复:]

我两条SQL都有参数啊。用一条第二条参数就会报错,提示必须声明变量[/quote]

你需要把两条 SQL 的参数整合到一个数组里作为参数传递进来,两条 SQL 的参数可以是一样的,类似如下:
private void operate(string sql1, string sql2, params SqlParameter[] prm)
{
......
c1.Parameters.AddRange(prm);
c2.Parameters.AddRange(prm);
......
}
wllllll 2021-01-27
  • 打赏
  • 举报
回复
我的类,给你参考。类似于ASP的写法。又加入了NET的特性。其实在后台还有SQL缓存模块。
锤子馆长 2021-01-27
  • 打赏
  • 举报
回复
引用 楼主 蜗牛学编程 的回复:
练习封装类时发现困难点: 为避免SQL注入攻击,要给SQL传参。如果仅是单条SQL语句没问题,直接加一个Parameters SQLParameter[]作为占位就可以。 但如果是多条SQL,每条SQL都要有不同的参数,那该怎么加这个Parameters吗?占位符只允许放一个Parameters,放在最后面。 不知道我有没有说清楚。 请老师们指点。
为啥2个SQL语句 合并成一个字符串 统一执行 就可以了
蜗牛学编程 2021-01-26
  • 打赏
  • 举报
回复
引用 5 楼 白衣如花 的回复:
用list,别用params

public void operate(List<string> sqls, List<SqlParameter[]> param)
你好,可以帮忙完整的写一下这段代码吗?没用过list<>的方式,代码正文不知道该怎么写
蜗牛学编程 2021-01-26
  • 打赏
  • 举报
回复
引用 4 楼 datafansbj 的回复:
我两条SQL都有参数啊。用一条第二条参数就会报错,提示必须声明变量
白衣如花 2021-01-26
  • 打赏
  • 举报
回复
用list,别用params


public void operate(List<string> sqls, List<SqlParameter[]> param)
datafansbj 2021-01-26
  • 打赏
  • 举报
回复
加载更多回复(3)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧