通过TCustomAttribute和反射实现动态查询(一)
通过TCustomAttribute和反射实现基本信息的动态模糊查询,规范查询的实现方式,提高查询的效率(根据指定的条件动态组装SQL语句,只判断需要的条件和返回需要的字段)。
首先定义一组TCustomAttribute类,包括:
/// <summary> /// 基本信息模糊查询主表自定义描述类。 /// </summary> TBaseInfoQueryMainTable = class sealed(TCustomAttribute) private FTableName: string; FMatchType: TBISelectMatchType; procedure SetMatchType(const Value: TBISelectMatchType); procedure SetTableName(const Value: string); public constructor Create(ATableName : string; AMatchType : TBISelectMatchType); /// <summary> /// 表名 /// </summary> property TableName : string read FTableName write SetTableName; /// <summary> /// 匹配方式 /// </summary> property MatchType : TBISelectMatchType read FMatchType write SetMatchType; end;
/// <summary> /// 基本信息动态模糊查询从表自定义描述类。 /// </summary> TBaseInfoQuerySubTable = class sealed(TCustomAttribute) private FTableName: string; FJoinCondition: string; FJoinMode: string; procedure SetJoinCondition(const Value: string); procedure SetJoinMode(const Value: string); procedure SetTableName(const Value: string); public constructor Create(ATableName : string; AJoinMode : string; AJoingCondition : string); /// <summary> /// 表名 /// </summary> property TableName : string read FTableName write SetTableName; /// <summary> /// <para> /// 连接模式。 /// </para> /// <para> /// 如:left join、inner join、left outer join等。 /// </para> /// </summary> property JoinMode : string read FJoinMode write SetJoinMode; /// <summary> /// <para> /// 连接条件。 /// </para> /// <para> /// 如:主表.ID=TableName.xxx and 主表.ID2=Table.yyy等。 /// </para> /// </summary> property JoinCondition : string read FJoinCondition write SetJoinCondition; end;
/// <summary> /// 基本信息动态模糊查询Where条件自定义描述类。 /// </summary> TBaseInfoQueryWhereFieldsAttribute = class sealed(TCustomAttribute) private FFieldAlias: string; FTableName: string; FFieldName: string; FFieldCaption: string; FChecked: Boolean; procedure SetFieldAlias(const Value: string); procedure SetFieldName(const Value: string); procedure SetTableName(const Value: string); procedure SetFieldCaption(const Value: string); procedure SetChecked(const Value: Boolean); public constructor Create(ATableName : string; AFieldName : string; AFieldCaption : string; AFieldAlias : string=''; AChecked : Boolean = False); /// <summary> /// 表名 /// </summary> property TableName : string read FTableName write SetTableName; /// <summary> /// 字段名 /// </summary> property FieldName : string read FFieldName write SetFieldName; /// <summary> /// <para> /// 字段别名。 /// </para> /// <para> /// 如:select s_values as xxx from systeminfo中的xxx。 /// </para> /// </summary> property FieldAlias : string read FFieldAlias write SetFieldAlias; /// <summary> /// 字段标题,用于表格列的展示。 /// </summary> property FieldCaption : string read FFieldCaption write SetFieldCaption; /// <summary> /// 字段是否被勾选。 /// </summary> property Checked : Boolean read FChecked write SetChecked; end;
/// <summary> /// 基本信息动态模糊查询Select字段自定义描述类。 /// </summary> TBaseInfoQuerySelectFieldsAttribute = class sealed(TCustomAttribute) private FFieldAlias: string; FTableName: string; FFieldName: string; FFixed: Boolean; FFieldCaption: string; FVisible: Boolean; procedure SetFieldAlias(const Value: string); procedure SetFieldCaption(const Value: string); procedure SetFieldName(const Value: string); procedure SetFixed(const Value: Boolean); procedure SetTableName(const Value: string); procedure SetVisible(const Value: Boolean); public constructor Create(ATableName : string; AFieldName : string; AFieldCaption : string; AFieldAlias : string=''; AVisible : Boolean = True; AFixed : Boolean = False); /// <summary> /// 表名 /// </summary> property TableName : string read FTableName write SetTableName; /// <summary> /// 字段名 /// </summary> property FieldName : string read FFieldName write SetFieldName; /// <summary> /// <para> /// 字段别名。 /// </para> /// <para> /// 如:select s_values as xxx from systeminfo中的xxx。 /// </para> /// </summary> property FieldAlias : string read FFieldAlias write SetFieldAlias; /// <summary> /// 字段标题,用于表格列的展示。 /// </summary> property FieldCaption : string read FFieldCaption write SetFieldCaption; /// <summary> /// 字段是否被勾选。 /// </summary> property Visible : Boolean read FVisible write SetVisible; /// <summary> /// 是否为必须select的字段,比如ID字段。默认False。 /// </summary> property Fixed : Boolean read FFixed write SetFixed; end;
为了书写方便,对以上几个类定义了各自的简写。
/// <summary> /// TBaseInfoQueryMainTable的简写。 /// </summary> TBIQueryMain = TBaseInfoQueryMainTable; TBIQuerySub = TBaseInfoQuerySubTable; /// <summary> /// TBaseInfoQueryWhereFieldsAttribute的简写。 /// </summary> TBIQueryWhere = TBaseInfoQueryWhereFieldsAttribute; /// <summary> /// TBaseInfoQuerySelectFieldsAttribute的简写。 /// </summary> TBIQuerySelect = TBaseInfoQuerySelectFieldsAttribute;
此外,定义了一个描述匹配方式的数据类型。
/// <summary> /// 查询匹配方式 /// </summary> /// <remarks> /// 右匹配(%X)、左匹配(x%)、全匹配(%x%)。 /// </remarks> TBISelectMatchType = (smtRight, smtLeft, smtAll);