???List?getOrders(String?userId){
?????????????String?sql;
?????????????Role?role=orgService.getRoleForUser(userId);
?????????????if(("admin").equals(role.getName()))
???????????????????sql="select?*?from?order";
?????????????else
???????????????????sql="select?*?from?order?where?author="+userId;
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
?????????????String?sql;
?????????????Role?role=orgService.getRoleForUser(userId);
?????????????if(("admin").equals(role.getName()))
???????????????????sql="select?*?from?order";
?????????????else
???????????????????sql="select?*?from?order?where?author="+userId;
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
恩,不錯,很好的完成了權限控制。過了沒多久,公司發展了,老板增加了人手,老板發話了,我要設置區域管理員分管不同區域的訂單。管理員分為北京地區管理員,上海地區管理員,其他地區管理員和總管理員。怎么辦?修改代碼吧
????List?getOrders(String?userId){
?????????????String?sql;
?????????????Role?role=orgService.getRoleForUser(userId);
?????????????if(("admin").equals(role.getName()))
??????????????????sql="select?*?from?order";
?????????????else?if("bjadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='beijing'";
?????????????else?if("shadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='shanghai'";
?????????????else?if("qtadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='qita'";
?????????????else
???????????????????sql="select?*?from?order?where?author="+userId;
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
?????????????String?sql;
?????????????Role?role=orgService.getRoleForUser(userId);
?????????????if(("admin").equals(role.getName()))
??????????????????sql="select?*?from?order";
?????????????else?if("bjadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='beijing'";
?????????????else?if("shadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='shanghai'";
?????????????else?if("qtadmin").equals(role.getName()))
?????????????????????????sql="select?*?from?order?where?area='qita'";
?????????????else
???????????????????sql="select?*?from?order?where?author="+userId;
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
恩恩,這就搞定了,可怎么也感覺不爽,也許該做點什么。一堆if/else權限判斷讓人心煩,再寫個類把這些sql管理起來好了,那就動手吧
??public?class?SqlManager{
??????????String?getSql(String?userId){
??????????????????String?sql;
??????????Role?role=orgService.getRoleForUser(userId);
??????????if(("admin").equals(role.getName()))
??????????????sql="select?*?from?order";
??????????else?if("bjadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='beijing'";
??????????else?if("shadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='shanghai'";
??????????else?if("qtadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='qita'";
??????????else
????????????sql="select?*?from?order?where?author="+userId;
??????????return?sql;
??????????}
??}
??????????String?getSql(String?userId){
??????????????????String?sql;
??????????Role?role=orgService.getRoleForUser(userId);
??????????if(("admin").equals(role.getName()))
??????????????sql="select?*?from?order";
??????????else?if("bjadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='beijing'";
??????????else?if("shadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='shanghai'";
??????????else?if("qtadmin").equals(role.getName()))
???????????????????sql="select?*?from?order?where?area='qita'";
??????????else
????????????sql="select?*?from?order?where?author="+userId;
??????????return?sql;
??????????}
??}
這樣把權限判斷移到SqlManager里,業務代碼就清爽了很多,再增加管理員就修改SqlManager好了
????List?getOrders(String?userId){
?????????????String?sql=sqlManager.getSql(userId);
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
?????????????String?sql=sqlManager.getSql(userId);
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
呵呵,看起來還不錯。但是等等,我們的業務方法為什么需要userId這個參數呢,是啊是啊,權限判斷用到了它,但是那和我業務又有什么關系呢,不爽。現在AOP不是很流行嗎,你不用AOP怎么能說明你技術高呢?快用吧快用吧,用不著也要想著方法用。
業務方法簡化為
????List?getOrders(){
?????????????String?sql="";
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
?????????????String?sql="";
?????????????Object?o=excuteSql(sql);
?????????????return?excute(o);
????????}
對excuteSql方法我們來AOP一下,注入權限判斷過的sql.嘿嘿,技術水平又一次得到了顯現。業務方法是簡單了,可我的SqlManager倒是復雜了,還是很不幸福。咋辦?用個配置文件吧,hibernate不是老鼓勵我們把sql寫在配置文件里嗎?
????<xml>
????????<sql?role="admin">select?*?from?order</sql>
????????<sql?role="bjadmin">select?*?from?order?where?area='beijing'</sql>
????????<sql?role="shadmin">select?*?from?order?where?area='shanghai'</sql>
????????<sql?role="qtadmin">select?*?from?order?where?area='qita'</sql>
????????<sql?role="none">select?*?from?order?where?author=?</sql>
????</xml>
????????<sql?role="admin">select?*?from?order</sql>
????????<sql?role="bjadmin">select?*?from?order?where?area='beijing'</sql>
????????<sql?role="shadmin">select?*?from?order?where?area='shanghai'</sql>
????????<sql?role="qtadmin">select?*?from?order?where?area='qita'</sql>
????????<sql?role="none">select?*?from?order?where?author=?</sql>
????</xml>
這樣SqlManager就可以把行數縮小了,就可以敏捷一點了。
????public?class?SqlManager{
??????????String?getSql(String?userId){
??????????????????String?sql;
??????????Role?role=orgService.getRoleForUser(userId);
??????????sql=getSqlfromXml(role.getName());
??????????return?sql;
??????????}
??????????
??????????String?getSqlfromXml(String?rolename){
??????????????????
.
??????????}
??}
??????????String?getSql(String?userId){
??????????????????String?sql;
??????????Role?role=orgService.getRoleForUser(userId);
??????????sql=getSqlfromXml(role.getName());
??????????return?sql;
??????????}
??????????
??????????String?getSqlfromXml(String?rolename){
??????????????????

??????????}
??}
以后再增加權限連類都不用修改了,改xml好了。等等,你是不是把問題太簡單化了。現在不僅僅是訂單,貨物也要這么分區域管理。
不錯,我們應該想著通用一下了。這樣,把SqlManager抽象一下
????????String?abstract?getSqlfromXml(String?rolename);
然后做幾個子類好了 OrderSqlManager, GoodsSqlManager .
可是,哥們,書上說,要面向接口編程,你這樣不太好吧。沒事,再接口一下:
???public?interface?SqlManagerInterface{
???????????String?getSql(String?userId);
???}
???????????String?getSql(String?userId);
???}
還是沒法用啊。也許現在可以看看acegi的provider機制了,把這一大堆SqlManager全部作為provider,根據不同的模塊選擇不同的provider,統一攔截excuteSql方法,生成不同的sql到數據庫執行。xml不爽?db也可以。然后,再然后呢?改你的類名,重構,和acegi整合一下。
呵呵,完全是個人的一些想法,希望多批評提提意見。我想表達的意思是:也許把數據權限再抽象一些,以組件的形式來減少侵入是可以做到的。
http://www.tkk7.com/ronghao 榮浩原創,轉載請注明出處:)