使用操作符過載,生成ORM實體類的SQL條件語句

2021-09-06 05:05:31 字數 4137 閱讀 6945

orm框架的乙個不可或缺的功能就是根據實體類,生成運算元據庫的sql語句,這其中,最難處理的就是那些複雜的sql條件比較語句。比如,有下面這樣乙個sql語句:

select[id

], [

bankcode

], [

citycode

], [

fundcode

], [

fundname

], [

fundreviews

], [

enddagte

], [

adddate

]from

[fundreviews

]where  ( ([

citycode]=

@cp1or[

bankcode]=

@cp2)  

and  (

[fundcode]=

@cp3or[

bankcode]=

@cp4) 

)

這個複雜的查詢條件由兩個or子條件最後組合成乙個and 條件的,因此它有3組條件:

1:[citycode]=

@cp1or[

bankcode]=

@cp2;

2:[fundcode]=

@cp3or[

bankcode]=

@cp4;

3:1 and 2 ;

而條件1其實就是 condition1 or condition2,這又是乙個條件組合。

我們發現,儘管sql的條件語句可能很複雜,但這些條件卻是由一些子條件組合成的,或者說由一組條件組合成乙個新的條件,大家想想,這是不是典型的「組合模式」阿?

在pdf.net框架的orm元件中,有乙個專門處理條件的物件oqlcompare ,它就是根據「組合模式」設計的,我們來看看怎麼由它來構造這個查詢條件:

1,採用and,or過載:

fundreviews p = 

new fundreviews();

//例項化乙個實體類

oql q = 

new oql(p);               

//例項化乙個oql物件

console.writeline(

"oqlcompare 複雜比較條件表示式測試---------

");

oqlcompare cmp = 

new oqlcompare(p);

oqlcompare cmpresult = (cmp.comparer(p.citycode, oqlcompare.comparetype.equal, 

"021")

| cmp.comparer(p.bankcode, oqlcompare.comparetype.equal, 

"008"))

& (cmp.comparer(p.fundcode, oqlcompare.comparetype.equal, 

"kf008

")

| cmp.comparer(p.bankcode, oqlcompare.comparetype.equal, 

"008"));

q.select().where(cmpresult);

console.writeline(

"sql=

" + q.tostring());

在oql中,採用了類似sql的語法,也是

select(

[屬性列表

]). where(

[條件表示式

]).orderby(

[排序字段

]).groupby(

[分組字段

]) 

其中[條件表示式]就可以使用oqlcompare物件來構造。由於oqlcompare物件comparer函式返回的仍然是乙個oqlcompare物件,所以可以利用這個特點,採用組合模式,構造出非常複雜的sql條件語句。

我們看到oql採用了類似函式式的語法風格,但在[條件表示式]的構造過程中,還是顯得很冗長,我們可以繼續對oqlcompare物件進行重構:

//////

設定等於某個實體屬性的比較條件

///

///當前實體比較物件

///要比較的值

///構造的實體比較物件

public

static oqlcompare 

operator ==(oqlcompare compare, 

object value)

//////

設定不等於某個實體屬性的比較條件

///

///當前實體比較物件

///要比較的值

///構造的實體比較物件

public

static oqlcompare 

operator !=(oqlcompare compare, 

object value)

//////

根據實體物件的屬性,獲取新的條件比較物件

///

///

///

public oqlcompare property(

object field)

private

static oqlcompare buildoperator(oqlcompare compare, 

object value,

string operatorstring)

我們可以採用類似的方式,繼續實現 >=,>,<=,< 等sql條件比較符號的過載,這裡就不一一舉例了,我們來看新的使用方式:

2,採用sql比較符號的過載:

//物件 p 為實體類

oqlcompare cmp2 = 

new oqlcompare(p);

oqlcompare cmpresult2 = 

( cmp2.property(p.citycode) == 

"021"  | cmp2.property(p.bankcode) == 

"008")

&  ( cmp2.property(p.fundcode) == 

"kf008

"| cmp2.property(p.bankcode) == 

"008");

q.reset();

//重新初始化oql

q.select().where(cmpresult2);

console.writeline(

"操作符過載 sql=

" + q.tostring());

現在這個sql條件的構造過程是不是清晰多了?這就是操作符過載的魅力:)

3,使用equal方法,簡化相等比較

直接看下面的**,功能跟上面的例子一樣:

//物件 p 為實體類

oqlcompare cmp2 = 

new oqlcompare(p);

oqlcompare cmpresult2 = 

( cmp2.equal(p.citycode,

"021")    | cmp2.equal(p.bankcode,

"008")  )

&  ( cmp2.equal(p.fundcode,

"kf008

")  | cmp2.equal(p.bankcode,

"008")  );

q.reset();

//重新初始化oql

q.select().where(cmpresult2);

console.writeline(

"操作符過載 sql=

" + q.tostring());

從效能上來說,這種方式效率稍高,因為它是函式式的處理方式,更直接。

注:本文介紹的這個oql特性僅在pdf.net ver 4.3版本受支援,但之前的版本參照本文說的方法加以改進,也可以使用。有關pdf.net的版本資訊,請看官網介紹:

有關pdf.net的開源資訊,請參看我的部落格文章:

節前送禮:pdf.net(pwmis資料開發框架)v3.0版開源

實現ORM模型一鍵生成實體類

使用方法 配置resources generactor.properties檔案 在com.dgy.main中執行main方法 主要的方法 取得mysql資料庫的表的字段資訊 查詢乙個表的所有列資訊 param tablename return public static mapgetcloumin...

使用OQL「語言」構造ORM實體類的複雜查詢條件

oql 語言 是pdf.net資料開發框架的實體物件查詢語言,一直以來,orm的複雜查詢條件都是困擾orm的問題,所以很多時候不得不捨棄orm,直接手工拼接sql。我們來看看oql是怎麼解決這些問題的,現在舉乙個今天同事遇到的問題 有這樣乙個實體類 myentity,實體類的具體定義在此忽略,有興趣...

C 類操作符過載筆記

不能改變操作符優先順序 不能改變操作符的結合性 不能改變操作符所需要的運算元 不能建立新的操作符 對於二元操作符過載,如果操作符左邊是類 那麼就在該類內部成員函式過載操作符即可 如果操作符左邊不是類,而是乙個常量,那麼就必須在類的外部定義乙個操作符過載函式 有乙個最基本條件 一定有乙個一元是乙個自定...