zoukankan      html  css  js  c++  java
  • 关于Oracle的动态查询

          本来想用存储过程实现动态查询,但是我们直接拼接的sql还是无法避免sql注入攻击,并且不能使用绑定变量。思前想后还是写了个DynamicSQL的类用来实现动态拼接SQL。具体的怎么拼接通过实体的特性来实现。这个类代替我们原先的ParameterClass类,用来实现动态查询。

           下面大致说下特性的使用:

    View Code
        [EnitityMapping(TableName="bw_fuhedj_view")]
        public class FuHeDJSearchDTO
        {
            /// <summary>
            
    /// 站点号
            
    /// </summary>
            [DataMember]
            public string S_ST { getset; }

            /// <summary>
            
    /// 册本号
            
    /// </summary>
            [DataMember]
            public string S_CH { getset; }

            /// <summary>
            
    /// 用户编号
            
    /// </summary>
            [DataMember]
            public string S_CID { getset; }

            /// <summary>
            
    /// 客户编号
            
    /// </summary>
            [EnitityMapping(ColumnName="s_kehuid")]
            [DataMember]
            public string S_KeHuBH { getset; }

            /// <summary>
            
    /// 户名
            
    /// </summary>
            [EnitityMapping(ColumnName = "s_hm", Operater = Operater.Like)]
            [DataMember]
            public string S_HuMing { getset; }

            /// <summary>
            
    /// 地址
            
    /// </summary>
            [EnitityMapping(ColumnName = "s_dz",Operater= Operater.Like )]
            [DataMember]
            public string S_DiZhi { getset; }

        }

           首先在类上加入需要mapping的表名,如果是多表关联的则输入对应的视图名。entity中的字段名如果和查询的列名一致则什么都不用写,如果不一致则需要mapping对应的列名。如果操作是等于操作则不用修改,否则在Operater使用其他枚举。目前还不支持in、is等操作符,等到用到再说吧。字段的连接都使用and连接。如果以后有or操作的话可能在操作类型里面加个Operater.Other,然后自己写对应的sql了。目前暂不支持or操作。

           写完Entity后调用DynamicSQL的GetTable方法就可以了。注意代码中的DataMember特性是标识实体是WCF的数据成员可以不要,使用也没有问题。最终的检验代码也可以用特性实现。

    调用方法表现层:

            private void btnSearch_Click(object sender, EventArgs e)
            {
                BiaoWuGLService.BiaoWuGLClient bw = new BiaoWuGLService.BiaoWuGLClient();
                Entity.BiaoWuGL.FuHeDJSearchDTO dto = new Entity.BiaoWuGL.FuHeDJSearchDTO
                {
                    S_CID = txtZhangHao.Text,
                    S_HuMing = txtYongHuH.Text,
                    S_DiZhi = txtDiZhi.Text
                };
                DataTable dt = bw.FuHeDJ_ChaXun(dto);
                bw.Close();
            }

    应用层:

            /// <summary>
            
    /// 复核登记查询
            
    /// </summary>
            
    /// <param name="dto"></param>
            
    /// <returns></returns>
            public DataTable FuHeDJ_ChaXun(Entity.BiaoWuGL.FuHeDJSearchDTO dto) 
            {
                return DynamicSQL.GetTable(dto);
            }

    下面是部分代码的实现,写的比较仓卒,应该会有bug,碰到问题在修改了:

    View Code
    //********************************************************************************//
    //创建日期:<创建日期,2012-05-27>
    //创建作者:<张易,zhangyi@shanghai3h.com>
    //功能说明:动态拼接SQL,防注入攻击,绑定变量
    //********************************************************************************//
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using Platform.Data;
    using Oracle.DataAccess.Client;
    using System.Reflection;
    using CSMS2.Entity;

    namespace CSMS2.Service
    {
        public static class DynamicSQL
        {
            public static DataTable GetTable<T>(T dto)
            {
                string conn = Platform.Configuration.ConfigHelper.BusinessConnString;
                string where = "";
                string sql = "select * from " + GetTableName(dto);
                OracleParameter[] oracleParameter = GetOracleParameter(dto, out where);
                //return OracleHelper.ExecuteDataset(conn, CommandType.Text, sql + " where s_cid='1003287'").Tables[0];
                return OracleHelper.ExecuteDataset(conn, CommandType.Text, sql + where, oracleParameter).Tables[0];
            }

            /// <summary>
            
    /// 获取参数
            
    /// </summary>
            
    /// <typeparam name="T"></typeparam>
            
    /// <param name="dto"></param>
            
    /// <returns></returns>
            private static OracleParameter[] GetOracleParameter<T>(T dto, out string wheresql)
            {
                int length = 0;
                wheresql = "";
                foreach (PropertyInfo p in dto.GetType().GetProperties())
                {
                    if (null != p.GetValue(dto, null))
                    {
                        if (p.GetValue(dto, null).ToString() != "")
                            length++;
                    }
                }

                OracleParameter[] storedParams = new OracleParameter[length];
                int j = 0;
                for (int i = 0; i < dto.GetType().GetProperties().Length; i++)
                {
                    PropertyInfo p = dto.GetType().GetProperties()[i];
                    if (null != p.GetValue(dto, null))
                    {
                        if (p.GetValue(dto, null).ToString() == "")
                            continue;
                        Operater op = GetOperaterName(p);
                        if (op == Operater.Equal)
                            wheresql += " and " + GetColumnName(p) + " = :" + p.Name;
                        else if (op == Operater.Greater)
                            wheresql = " and " + GetColumnName(p) + " > :" + p.Name;
                        else if (op == Operater.GreaterEqual)
                            wheresql += " and " + GetColumnName(p) + " >= :" + p.Name;
                        else if (op == Operater.In)
                            wheresql += " and " + GetColumnName(p) + " = :" + p.Name;
                        else if (op == Operater.Is)
                            wheresql += " and " + GetColumnName(p) + " = :" + p.Name;
                        else if (op == Operater.Less)
                            wheresql += " and " + GetColumnName(p) + " < :" + p.Name;
                        else if (op == Operater.LessEqual)
                            wheresql += " and " + GetColumnName(p) + " <= :" + p.Name;
                        else if (op == Operater.Like)
                            wheresql += " and " + GetColumnName(p) + " like :" + p.Name + "";
                        else if (op == Operater.NotEqual)
                            wheresql += " and " + GetColumnName(p) + " != :" + p.Name;
                        else if (op == Operater.NotIn)
                            wheresql += " and " + GetColumnName(p) + " = :" + p.Name;



                        OracleParameter m = new OracleParameter();
                        if (p.PropertyType == typeof(string))
                        {
                            m = new OracleParameter(GetColumnName(p), OracleDbType.Varchar2, 8000);
                        }
                        else if (p.PropertyType == typeof(int))
                        {
                            m = new OracleParameter(GetColumnName(p), OracleDbType.Int32);
                        }
                        else if (p.PropertyType == typeof(decimal))
                        {
                            m = new OracleParameter(GetColumnName(p), OracleDbType.Decimal);
                        }
                        else if (p.PropertyType == typeof(DateTime))
                        {
                            m = new OracleParameter(GetColumnName(p), OracleDbType.Date);
                        }

                        if (op == Operater.Like)
                            m.Value = p.GetValue(dto, null) + "%";
                        else
                            m.Value = p.GetValue(dto, null);
                        storedParams[j] = m;
                        j++;
                    }
                }
                if (wheresql.Length > 0)
                    wheresql = " where" + wheresql.Substring(4);
                return storedParams;
            }

            /// <summary>
            
    /// 获取列名
            
    /// </summary>
            
    /// <param name="info"></param>
            
    /// <returns></returns>
            private static string GetColumnName(PropertyInfo info)
            {
                string columnname = string.Empty;
                foreach (object obj in info.GetCustomAttributes(typeof(EnitityMappingAttribute), true))
                {
                    if (obj.GetType() == typeof(EnitityMappingAttribute))
                    {
                        EnitityMappingAttribute attr = obj as EnitityMappingAttribute;
                        columnname = attr.ColumnName;
                        break;
                    }
                }
                if (string.IsNullOrEmpty(columnname))
                    columnname = info.Name;
                return columnname.ToUpper();
            }

            /// <summary>
            
    /// 获取列名
            
    /// </summary>
            
    /// <param name="info"></param>
            
    /// <returns></returns>
            private static Operater GetOperaterName(PropertyInfo info)
            {
                Operater op = Operater.Equal;
                foreach (object obj in info.GetCustomAttributes(typeof(EnitityMappingAttribute), true))
                {
                    if (obj.GetType() == typeof(EnitityMappingAttribute))
                    {
                        EnitityMappingAttribute attr = obj as EnitityMappingAttribute;
                        if (null != attr.Operater)
                        {
                            op = attr.Operater;
                            break;
                        }
                    }
                }
                return op;
            }


            /// <summary>
            
    /// 获取实体对应的表名
            
    /// </summary>
            
    /// <typeparam name="T"></typeparam>
            
    /// <param name="dto"></param>
            
    /// <returns></returns>
            private static string GetTableName<T>(T dto)
            {
                string tablename = string.Empty;
                foreach (object obj in dto.GetType().GetCustomAttributes(typeof(EnitityMappingAttribute), true))
                {
                    if (obj.GetType() == typeof(EnitityMappingAttribute))
                    {
                        EnitityMappingAttribute attr = obj as EnitityMappingAttribute;
                        tablename = attr.TableName;
                        break;
                    }
                }
                return tablename;
            }
        }
    }
    View Code
    //********************************************************************************//
    //创建日期:<创建日期,2012-05-27>
    //创建作者:<张易,zhangyi@shanghai3h.com>
    //功能说明:自定义特性 属性或者类可用  支持继承
    //********************************************************************************//
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace CSMS2.Entity
    {
        /// <summary>
        
    /// 自定义特性 属性或者类可用  支持继承
        
    /// </summary>
        [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = true)]
        public class EnitityMappingAttribute : Attribute
        {

            /// <summary>
            
    /// 实体实际对应的表名
            
    /// </summary>
            public string TableName
            {
                get;
                set;
            }

            /// <summary>
            
    /// 中文列名
            
    /// </summary>
            public string ColumnName
            {
                get;
                set;
            }

            public Operater Operater
            {
                get;
                set;
            }


        }

        /// <summary>
        
    /// 操作类
        
    /// </summary>
        public enum Operater
        {
            Equal,
            Greater,
            Less,
            GreaterEqual,
            LessEqual,
            Like,
            In,
            Is,
            NotEqual,
            NotIn
        }
    }
  • 相关阅读:
    并行数据的并行转串行
    色彩空间转换仿真与模型搭建
    布隆过滤器介绍和在java中应用举例
    java9初探
    个人博客开通啦!
    MyBatis多租户隔离插件开发
    手动解析Excel获取文件元数据
    解决Shiro+SpringBoot自定义Filter不生效问题
    基于Redis的分布式锁实现
    解决tomcat同时部署两个SpringBoot应用提示InstanceAlreadyExistsException
  • 原文地址:https://www.cnblogs.com/zyizyizyi/p/2521456.html
Copyright © 2011-2022 走看看