爱的心痛 發表於 2025-5-20 12:04:00

delphi 注解+反射

<p>delphi 通过注解+反射,可以实现数据的ORM编程,不再需要DATASET。</p>
<p>注解:是一种RTTI。</p>
<p>始创于java,go/c#/java/delphi。。。目前都支持注解。</p>
<p>RTTI对程序性能的影响:https://www.cnblogs.com/hnxxcxg/p/19660714</p>
<p>go语言的注解:</p>
<div class="cnblogs_code">
<pre>type Person <span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> {
Name    </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span> xml:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Email   </span><span style="color: rgba(0, 0, 255, 1)">string</span> `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">email</span><span style="color: rgba(128, 0, 0, 1)">"</span> xml:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">email</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
Age   </span><span style="color: rgba(0, 0, 255, 1)">int</span>    `json:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age,omitempty</span><span style="color: rgba(128, 0, 0, 1)">"</span> xml:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age,omitempty</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">`
}</span></pre>
</div>
<p>delphi的注解:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用json做注解</span>
json = <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(TCustomAttribute)
    txt: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
    constructor Create(AJson: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
end;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">数据模型(data-model)</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表的注解</span>
TGoods =<span style="color: rgba(0, 0, 0, 1)"> record
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">字段的注解</span>
    goodsid: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">字段的注解</span>
    goodsname: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
end;</span></pre>
</div>
<p>&nbsp;注解的常见用途:</p>
<p>1)序列化和反序列化:</p>
<p>注解常被用于控制结构体的序列化和反序列化。例如,在 Go 的 encoding/json 和 encoding/xml 包中,你可以使用注解来指定字段在 JSON 或 XML 中的名称,或者在编码时是否忽略某个字段。这可以让你有更大的灵活性来定义和控制序列化和反序列化的过程。</p>
<p>2)数据验证:</p>
<p>一些库允许你使用注解来为结构体的字段添加验证规则。例如,你可以使用 valid 注解来指定一个字段必须是邮件地址格式,或者使用 range 注解来指定一个整数字段的值必须在某个范围内。这些库通常提供了一套简洁的 DSL(领域特定语言)让你可以在注解中定义复杂的验证规则。</p>
<p>3)数据库 ORM 映射:</p>
<p>有些数据库 ORM(对象关系映射)库允许你使用注解来定义数据库表和结构体之间的映射关系。例如,你可以使用 sql 注解来指定字段对应的数据库列的名称,或者一个字段是否可以为 null。</p>
<p>4)HTTP 路由和处理:</p>
<p>在某些 Web 框架中,标签可以被用来定义 HTTP 路由规则或者请求处理逻辑。例如,你可以使用 route 注解来指定一个方法处理哪个 URL 路径的请求,或者使用 method 注解来指定一个方法处理哪种 HTTP 方法的请求。</p>
<p>delphi 注解+反射的样例:</p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">unit Unit1;

</span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)">

uses Rtti, core.json,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用json做注解</span>
json = <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(TCustomAttribute)
    txt: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
    constructor Create(AJson: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
end;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">数据模型(data-model)</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表的注解</span>
TGoods =<span style="color: rgba(0, 0, 0, 1)"> record
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">字段的注解</span>
    goodsid: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">字段的注解</span>
    goodsname: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
end;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注解+反射 自动生成记录的CRUD</span>
TCrud&lt;T&gt; =<span style="color: rgba(0, 0, 0, 1)"> record
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">var</span> aRecord: T;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">a record</span>
    <span style="color: rgba(0, 0, 255, 1)">class</span> function <span style="color: rgba(0, 0, 255, 1)">select</span>: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> function insert: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> function delete: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> function update: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">处理record.field.value</span>
    <span style="color: rgba(0, 0, 255, 1)">class</span> function ProcessFieldValue(<span style="color: rgba(0, 0, 255, 1)">const</span> ARttiField: TRttiField): <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
end;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">远程 服务方法</span>
TService1 = <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">函数的注解</span>
<span style="color: rgba(0, 0, 0, 1)">    procedure proc1;
end;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">路由服务方法</span>
TRouter&lt;T&gt; =<span style="color: rgba(0, 0, 0, 1)"> record
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> service: TObject;
    </span><span style="color: rgba(0, 0, 255, 1)">class</span> procedure route(<span style="color: rgba(0, 0, 255, 1)">const</span> FUrl: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">const</span> FMethod: <span style="color: rgba(0, 0, 255, 1)">string</span>); <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">;
end;

TForm1 </span>= <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    Button4: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    { Private declarations }
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
    { Public declarations }
end;

</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
Form1: TForm1;

implementation

{$R </span>*<span style="color: rgba(0, 0, 0, 1)">.dfm}

constructor json.Create(AJson: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
begin
txt :</span>=<span style="color: rgba(0, 0, 0, 1)"> AJson;
end;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> function TCrud&lt;T&gt;.Update: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
LRttiContext: TRttiContext;
LRttiType: TRttiType;
LRttiField: TRttiField;
LTableAttribute, LFieldAttribute: TCustomAttribute;
LTableName, LWhere, LFieldName, LValue, LKeyFields, LSet: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
LJsonO: JO;
begin
LRttiContext :</span>=<span style="color: rgba(0, 0, 0, 1)"> TRttiContext.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiType :</span>=<span style="color: rgba(0, 0, 0, 1)"> LRttiContext.GetType(TypeInfo(T));
    LTableAttribute :</span>= LRttiType.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
    LJsonO :</span>=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LTableAttribute).txt);
    LTableName :</span>= LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tablename</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表名</span>
    LKeyFields := LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">keyfields</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 主键</span>
<span style="color: rgba(0, 0, 0, 1)">    FreeAndNil(LJsonO);
    LValue :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    LWhere :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    LSet :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> LRttiField <span style="color: rgba(0, 0, 255, 1)">in</span> LRttiType.GetFields <span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
    begin
      LFieldAttribute :</span>= LRttiField.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
      LJsonO :</span>=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LFieldAttribute).txt);
      LFieldName :</span>= LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">fieldname</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 字段名</span>
<span style="color: rgba(0, 0, 0, 1)">      FreeAndNil(LJsonO);
      LValue :</span>=<span style="color: rgba(0, 0, 0, 1)"> ProcessFieldValue(LRttiField);
      LSet :</span>= LSet + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">,</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LFieldName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">=</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> LValue;
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> Pos(LFieldName, LKeyFields) = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> then
      Continue; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 非主键不做where条件</span>
      LWhere := LWhere + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)"> and </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LFieldName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">=</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LValue; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 拼where条件</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LWhere = <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)"> then
      begin
      Result :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
      ShowMessage(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">没有where条件</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
      Exit;
      end;
    end;
    System.Delete(LWhere, </span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
    System.Delete(LSet, </span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
    Result :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">update </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LTableName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)"> set </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LSet + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)"> where </span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> LWhere;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiContext.Free;
end;
end;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> function TCrud&lt;T&gt;.Delete: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
begin
</span><span style="color: rgba(0, 0, 255, 1)">var</span> LRttiContext: TRttiContext :=<span style="color: rgba(0, 0, 0, 1)"> TRttiContext.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">var</span> LRttiType: TRttiType :=<span style="color: rgba(0, 0, 0, 1)"> LRttiContext.GetType(TypeInfo(T));
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LTableAttribute: TCustomAttribute := LRttiType.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LJsonO: JO :=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LTableAttribute).txt);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LTableName: <span style="color: rgba(0, 0, 255, 1)">string</span> := LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tablename</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表名</span>
    <span style="color: rgba(0, 0, 255, 1)">var</span> LKeyFields: <span style="color: rgba(0, 0, 255, 1)">string</span> := LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">keyfields</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 主键</span>
<span style="color: rgba(0, 0, 0, 1)">    FreeAndNil(LJsonO);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LValue: <span style="color: rgba(0, 0, 255, 1)">string</span> := <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LWhere: <span style="color: rgba(0, 0, 255, 1)">string</span> := <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> <span style="color: rgba(0, 0, 255, 1)">var</span> LRttiField: TRttiField <span style="color: rgba(0, 0, 255, 1)">in</span> LRttiType.GetFields <span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
    begin
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> LFieldAttribute: TCustomAttribute := LRttiField.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
      LJsonO :</span>=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LFieldAttribute).txt);
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> LFieldName: <span style="color: rgba(0, 0, 255, 1)">string</span> := LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">fieldname</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 字段名</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> Pos(LFieldName, LKeyFields) = <span style="color: rgba(128, 0, 128, 1)">0</span> then <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 非主键不做where条件</span>
<span style="color: rgba(0, 0, 0, 1)">      begin
      FreeAndNil(LJsonO);
      Continue;
      end;
      FreeAndNil(LJsonO);
      LValue :</span>=<span style="color: rgba(0, 0, 0, 1)"> ProcessFieldValue(LRttiField);
      LWhere :</span>= LWhere + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)"> and </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LFieldName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">=</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LValue; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 拼where条件</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> LWhere = <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)"> then
      begin
      Result :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
      ShowMessage(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">没有where条件</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
      Exit;
      end;
    end;
    System.Delete(LWhere, </span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
    Result :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">delete from </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LTableName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)"> where </span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> LWhere;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiContext.Free;
end;
end;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> function TCrud&lt;T&gt;.Insert: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
LRttiContext: TRttiContext;
LRttiType: TRttiType;
LRttiField: TRttiField;
LTableAttribute, LFieldAttribute: TCustomAttribute;
LTableName: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
LJsonO: JO;
LFields, LValues, LValue: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
begin
LRttiContext :</span>=<span style="color: rgba(0, 0, 0, 1)"> TRttiContext.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiType :</span>=<span style="color: rgba(0, 0, 0, 1)"> LRttiContext.GetType(TypeInfo(T));
    LTableAttribute :</span>= LRttiType.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
    LJsonO :</span>=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LTableAttribute).txt);
    LTableName :</span>= LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tablename</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 表名</span>
<span style="color: rgba(0, 0, 0, 1)">    FreeAndNil(LJsonO);
    LFields :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    LValues :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    LValue :</span>= <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> LRttiField <span style="color: rgba(0, 0, 255, 1)">in</span> LRttiType.GetFields <span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
    begin
      LFieldAttribute :</span>= LRttiField.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
      LJsonO :</span>=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LFieldAttribute).txt);
      LFields :</span>= LFields + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">,</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LJsonO.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">fieldname</span><span style="color: rgba(128, 0, 0, 1)">'</span>]; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 拼字段</span>
<span style="color: rgba(0, 0, 0, 1)">      FreeAndNil(LJsonO);
      LValue :</span>=<span style="color: rgba(0, 0, 0, 1)"> ProcessFieldValue(LRttiField);
      LValues :</span>= LValues + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">,</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LValue; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 拼值</span>
<span style="color: rgba(0, 0, 0, 1)">    end;
    System.Delete(LFields, </span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
    System.Delete(LValues, </span><span style="color: rgba(128, 0, 128, 1)">1</span>, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
    Result :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">insert into </span><span style="color: rgba(128, 0, 0, 1)">'</span> + LTableName + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">(</span><span style="color: rgba(128, 0, 0, 1)">'</span> + LFields + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">) values (</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)">
      LValues </span>+ <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">)</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiContext.Free;
end;
end;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> function TCrud&lt;T&gt;.ProcessFieldValue(<span style="color: rgba(0, 0, 255, 1)">const</span> ARttiField: TRttiField): <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
begin
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (@aRecord = nil) or (ARttiField =<span style="color: rgba(0, 0, 0, 1)"> nil) then
    Exit;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> ARttiField.FieldType.ToString = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TDateTime</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> then
    Result :</span>= FormatDateTime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yyyy-mm-dd hh:nn:ss</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
      ARttiField.GetValue(@aRecord).AsType</span>&lt;TDateTime&gt;<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ARttiField.FieldType.ToString = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TDate</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> then
    Result :</span>= FormatDateTime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yyyy-mm-dd</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, ARttiField.GetValue(@aRecord)
      .AsType</span>&lt;TDate&gt;<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ARttiField.FieldType.ToString = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TTime</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> then
    Result :</span>= FormatDateTime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">hh:nn:ss</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, ARttiField.GetValue(@aRecord)
      .AsType</span>&lt;TTime&gt;<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> ARttiField.GetValue(@aRecord).ToString;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ARttiField.FieldType.ToString = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">string</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) or
    (ARttiField.FieldType.ToString </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TDateTime</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) or
    (ARttiField.FieldType.ToString </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TDate</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) or
    (ARttiField.FieldType.ToString </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TTime</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) then
    Result :</span>=<span style="color: rgba(0, 0, 0, 1)"> QuotedStr(Result);
end;

</span><span style="color: rgba(0, 0, 255, 1)">class</span> function TCrud&lt;T&gt;.<span style="color: rgba(0, 0, 255, 1)">select</span>: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
begin
</span><span style="color: rgba(0, 0, 255, 1)">var</span> LRttiContext: TRttiContext :=<span style="color: rgba(0, 0, 0, 1)"> TRttiContext.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">var</span> LRttiType: TRttiType :=<span style="color: rgba(0, 0, 0, 1)"> LRttiContext.GetType(TypeInfo(T));
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LTableAttribute: TCustomAttribute := LRttiType.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LJsonObj: JO :=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LTableAttribute).txt);
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> LTableName: <span style="color: rgba(0, 0, 255, 1)">string</span> := LJsonObj.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tablename</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
    LJsonObj.Free;
    Result :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">select * from </span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> LTableName;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    LRttiContext.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TCrud</span>&lt;TGoods&gt;.aRecord.goodsid := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">666</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Memo1.Text :</span>= TCrud&lt;TGoods&gt;<span style="color: rgba(0, 0, 0, 1)">.delete;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
TCrud</span>&lt;TGoods&gt;.aRecord.goodsid := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">666</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
TCrud</span>&lt;TGoods&gt;.aRecord.goodsname := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">商品一</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Memo1.Text :</span>= TCrud&lt;TGoods&gt;<span style="color: rgba(0, 0, 0, 1)">.Insert;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
TCrud</span>&lt;TGoods&gt;.aRecord.goodsid := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">666</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
TCrud</span>&lt;TGoods&gt;.aRecord.goodsname := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">修改</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Memo1.Text :</span>= TCrud&lt;TGoods&gt;<span style="color: rgba(0, 0, 0, 1)">.Update;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
TRouter</span>&lt;TService1&gt;.service :=<span style="color: rgba(0, 0, 0, 1)"> TService1.Create;
TRouter</span>&lt;TService1&gt;.route(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">v1/test</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">get</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
TRouter</span>&lt;TService1&gt;<span style="color: rgba(0, 0, 0, 1)">.service.Free;
end;

procedure TService1.proc1;
begin
ShowMessage(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">hi</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
end;

{ TRouter</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> }

</span><span style="color: rgba(0, 0, 255, 1)">class</span> procedure TRouter&lt;T&gt;.route(<span style="color: rgba(0, 0, 255, 1)">const</span> FUrl: <span style="color: rgba(0, 0, 255, 1)">string</span>; <span style="color: rgba(0, 0, 255, 1)">const</span> FMethod: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
begin
</span><span style="color: rgba(0, 0, 255, 1)">var</span> LContext: TRttiContext :=<span style="color: rgba(0, 0, 0, 1)"> TRttiContext.Create;
</span><span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">var</span> LRttiType: TRttiType :=<span style="color: rgba(0, 0, 0, 1)"> LContext.GetType(TypeInfo(T));
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> <span style="color: rgba(0, 0, 255, 1)">var</span> LRttiMethod: TRttiMethod <span style="color: rgba(0, 0, 255, 1)">in</span> LRttiType.GetMethods <span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
    begin
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> LAttribute: TCustomAttribute := LRttiMethod.GetAttribute&lt;json&gt;<span style="color: rgba(0, 0, 0, 1)">;
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> LJsonObject: JO :=<span style="color: rgba(0, 0, 0, 1)"> SO(json(LAttribute).txt);
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (FUrl = LJsonObject.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">url</span><span style="color: rgba(128, 0, 0, 1)">'</span>]) and (FMethod = LJsonObject.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">method</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]) then
      begin
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> Assigned(LRttiMethod) then
          LRttiMethod.Invoke(service, []); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">call rpc</span>
<span style="color: rgba(0, 0, 0, 1)">      Exit;
      end;
      LJsonObject.Free;
    end;
</span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
    LContext.Free;
end;
end;

end.</span></pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/18886555</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/18886555
頁: [1]
查看完整版本: delphi 注解+反射