• ibatis.net之我的调整:Update语句的动态set字段


    动态Update语句

    如果Map中指定多个字段

        <update id="UpdateStaff">
          update Staff set Name=#Name#,InDate=#InDate# where StaffId=#StaffId#
        </update>
    

    使用以下代码会有麻烦

    第25行注释掉的话,你会发现InDate会被设置为null.而实际的工作我们并不希望一行数据所有字段都刷新一次,因为在大型系统里每次都这样做的话,风险太高。

    如果只更新指定的字段的内容呢,已有人做出尝试,我觉得不错。
    https://www.cnblogs.com/myitroad/p/5516963.html

    但我觉得应调整原有的机制(改源代码),减少日常的开发工作。我准备使用“UpdateSetClip"代替Set部分

        <update id="UpdateStaff">
          update Staff set [UpdateSetClip] where StaffId=#StaffId#
        </update>
    

    好了,修改好sqlMap,不断的跑代码,不断的调整程序,直到满意:)

    这是调整的位置,使用了一个新增的方法CreateDync,意思为动态创建

    以下是主要代码,源代码文件:IBatisNet.DataMapper.Commands.DefaultPreparedCommand.cs

    public void CreateDync(RequestScope request, ISqlMapSession session, IStatement statement, object parameterObject)
            {
                request.IDbCommand = new DbCommandDecorator(session.CreateCommand(statement.CommandType), request);
                //request.PreparedStatement.()
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Statement Id: [" + statement.Id + "] PreparedStatement : [" + request.IDbCommand.CommandText + "]");
                }
    
                ApplyParameterMap(session, request.IDbCommand, request, statement, parameterObject);
                //
                string lastSql = applyParameterDyncSetClip(session, request.IDbCommand, request, statement, parameterObject);
                request.IDbCommand.CommandText = lastSql;
            }
            /// <summary>
            /// 应用动态字段set语句
            /// </summary>
            /// <param name="session"></param>
            /// <param name="command"></param>
            /// <param name="request"></param>
            /// <param name="statement"></param>
            /// <param name="parameterObject"></param>
            private string applyParameterDyncSetClip(ISqlMapSession session, IDbCommand command,
                RequestScope request, IStatement statement, object parameterObject)
            {
                Dictionary<string, object> dict = parameterObject as Dictionary<string, object>;//将参数转为字典
                if (dict == null)
                    return request.PreparedStatement.PreparedSql;
    
                string _updateStr = "";//动态Set部分,以空格开始
                int index = request.PreparedStatement.DbParametersName.Count;
                foreach (var one in dict)//build command set DataParameter
                {
                    if (request.PreparedStatement.DbParametersName.Contains(one.Key))
                        continue;
                    index++;
                    IDbDataParameter parameterCopy = request.IDbCommand.CreateParameter();
                    parameterCopy.ParameterName = string.Format("{0}param{1}", session.DataSource.DbProvider.ParameterPrefix, index);
                    parameterCopy.Value = one.Value;
                    request.IDbCommand.Parameters.Add(parameterCopy);
                    _updateStr += string.Format("{0} = {1},", one.Key, parameterCopy.ParameterName);
                }
                _updateStr = _updateStr.TrimEnd(',');
                return request.PreparedStatement.PreparedSql.Replace("[UpdateSetClip]", _updateStr);
            }
    

      细心的朋友会发现这个只支持字典,是的。字典(key/value)将是开源HIS中经常会见到。其实XML、Json都可以使用key/value来表示。所以自定义类似乎并不是必选项。当然实体类(属性对应表的字段)依然是推荐的技术手段。真正讨论开源HIS源码的时候再详谈。

  • 相关阅读:
    关于WPF中Popup控件的小记
    javascript调用外部wpf的方法
    html+ashx 缓存问题
    『Linux学习笔记』8. 权限
    LeetCode 2.两数相加
    C# 标签打印示例 1
    检索COM 类工厂中CLSID 为 {0002450000000000C000000000000046}的组件时失败
    C# 文件操作(一)
    Nginx 事件基本处理流程分析
    Spring学习笔记1:概论
  • 原文地址:https://www.cnblogs.com/kevin-Y/p/8901545.html
Copyright © 2020-2023  润新知