java - 復(fù)雜的字段條件判斷解析
問(wèn)題描述
應(yīng)用場(chǎng)景簡(jiǎn)化描述現(xiàn)在有個(gè)用戶Person,包含int age, BigDecimal money,java.util.Date accessTime等字段,對(duì)應(yīng)于用戶表person:
年齡(age : int)資產(chǎn) (money : number)入網(wǎng)日期 (accessTime : date)20100.002017-03-2420150.002016-05-0721300.002015-04-0321240.002015-07-1522300.002014-12-2121300.002014-12-21另外,有一張條件表,condition:
字段名(fieldName : varchar)運(yùn)算符(oper : varchar)閾值 (threshold : varchar )age=21money>280.05accessTime>2015-05-31條件表condition用來(lái)配置過(guò)濾用戶person的條件,表示要過(guò)濾出
年齡等于21歲
資產(chǎn)大于280.05
入網(wǎng)日期在 2015-06-01之后
的所有用戶。
其中,oper可取的值有 = , < , > , >= , <= , in , between
如果oper為in或between, 則閾值為多個(gè),用逗號(hào)隔開(kāi)。
問(wèn)題現(xiàn)在,對(duì)于不同的字段,在條件表condition里都是varchar類型,而在person表中,卻有不同的類型。
而且,條件表里的條件是從web系統(tǒng)頁(yè)面上,由用戶配置的;也就是說(shuō),條件的個(gè)數(shù)不確定,配置的字段,運(yùn)算符,閾值也都是不確定的。
問(wèn): 如何才能使用java代碼,先將所有用戶以及條件查出來(lái),然后遍歷每個(gè)用戶,對(duì)于每個(gè)用戶,遍歷每個(gè)條件,怎樣才能正確的判斷該用戶通過(guò)所有的條件檢查,得出通過(guò)條件篩選的用戶列表?(上邊的場(chǎng)景是實(shí)際場(chǎng)景簡(jiǎn)化后的,請(qǐng)不要給出拼接sql,通過(guò)sql過(guò)濾的答案)
是不是可以把person的記錄生成xml文件,條件生成xsd文件,用xsd去校驗(yàn)xml ??
問(wèn)題解答
回答1:如果不用sql的話,可以考慮使用責(zé)任鏈模式,將所有數(shù)據(jù)獲取出來(lái)放到linkedlist里面,然后寫(xiě)個(gè)過(guò)濾器來(lái)過(guò)濾集合里面的內(nèi)容,每一個(gè)條件可以相當(dāng)于一個(gè)過(guò)濾器
回答2:你用戶表有多大,還全部查出來(lái)。
正規(guī)做法都是拼sql查吧。。。
更高級(jí)的做法應(yīng)該是自定義領(lǐng)域特定語(yǔ)言,然后轉(zhuǎn)sql吧,反正不可能是用xml過(guò)濾。
回答3:感覺(jué)你這個(gè)condition表沒(méi)什么用啊??jī)H僅是存儲(chǔ)數(shù)據(jù)?如果臨時(shí)的直接用json傳過(guò)來(lái)就好了,如果你要持久存儲(chǔ)的話,起碼要個(gè)admin_id什么的,來(lái)標(biāo)記下是誰(shuí)的篩選條件。感覺(jué)效率不如直接扔到redis好點(diǎn)。
看你用的是Java,不過(guò)我習(xí)慣用PHP,就用PHP簡(jiǎn)單描述下我的思路吧...
寫(xiě)一個(gè)Filter類處理condition轉(zhuǎn)換為sql。
class Filter { public function doFilter() {//1. 獲取登錄的admin_id//2. 獲取篩選條件/** * 數(shù)據(jù)格式例子為: [ * ’field’ => ’age’;, * ’type’ => ’compare’, * ’ext’ => ’>’, * ’value’ => ’2’ * ] */foreach($conditions as $condition) { // 根據(jù)type獲取對(duì)應(yīng)的$conditionHandle $conditionHandle::parse($condition);} }}// Condition接口interface Condition { // 解析數(shù)據(jù),返回sql片段和需要填充的數(shù)據(jù)(此處使用PDO預(yù)處理,減少SQL注入) static function parse($data);}// ConditionHandlenamespace Condition;class Compare implements Condition { // 執(zhí)行流程 public static function parse($data) {...return [ ’sql’ => ’age > ?’, ’params’ => [ 2 ]]; }}
手寫(xiě)的,語(yǔ)法錯(cuò)誤請(qǐng)忽略...
相關(guān)文章:
1. 怎樣使留言的數(shù)據(jù)與登錄的用戶名,密碼保持一致(在數(shù)據(jù)庫(kù)上是一行的)。2. java - 輸出4個(gè)不相等整數(shù)之間所有任意三個(gè)整數(shù)的乘積3. javascript - 一排三個(gè)框,各個(gè)框的間距是15px,距離外面的白框間距也是15px,這個(gè)css怎么寫(xiě)?4. javascript - jqery 適應(yīng)輪播,哪位前輩可以幫助小弟按照下面圖片寫(xiě)一個(gè)大概例子,小弟在此跪謝!5. css3 - rem布局下,用戶瀏覽器的最小字號(hào)是12px怎么辦?6. css如何實(shí)現(xiàn)兩欄布局,左邊固定寬度,右邊寬度自適應(yīng),且高度和瀏覽器當(dāng)前高度一致?7. css3 - CSSComb for Sublime Text 在 Windows 下無(wú)法使用。8. javascript - nodejs中使用request庫(kù)怎么抓取網(wǎng)頁(yè)中的圖片9. mysql money 插入數(shù)據(jù)為什么報(bào)錯(cuò)?10. angular.js - 百度爬蟲(chóng)如何處理“#”符號(hào)?
