对数据权限控制的实验

一开始我把控制数据权限写在业务里,以订单管理为例,先讨论一个最简单的情况。管理员可以看所有的订单,而用户只能看自己的订单。这里的管理员是一个角色。我会这么写(一些次要代码都省略了):
java 代码
 
  1. List getOrders(String userId){  
  2.           String sql;  
  3.           Role role=orgService.getRoleForUser(userId);  
  4.           if(("admin").equals(role.getName()))  
  5.                 sql="select * from order";  
  6.           else  
  7.                 sql="select * from order where author="+userId;  
  8.           Object o=excuteSql(sql);  
  9.           return excute(o);  
  10.      }  
恩,不错,很好的完成了权限控制。过了没多久,公司发展了,老板增加了人手,老板发话了,我要设置区域管理员分管不同区域的订单。管理员分为北京地区管理员,上海地区管理员,其他地区管理员和总管理员。怎么办?修改代码吧
java 代码
 
  1. List getOrders(String userId){  
  2.             String sql;  
  3.             Role role=orgService.getRoleForUser(userId);  
  4.             if(("admin").equals(role.getName()))  
  5.                  sql="select * from order";  
  6.             else if("bjadmin").equals(role.getName()))  
  7.                         sql="select * from order where area='beijing'";  
  8.             else if("shadmin").equals(role.getName()))  
  9.                         sql="select * from order where area='shanghai'";  
  10.             else if("qtadmin").equals(role.getName()))  
  11.                         sql="select * from order where area='qita'";  
  12.             else  
  13.                   sql="select * from order where author="+userId;  
  14.             Object o=excuteSql(sql);  
  15.             return excute(o);  
  16.        }  
恩恩,这就搞定了,可怎么也感觉不爽,也许该做点什么。一堆if/else权限判断让人心烦,再写个类把这些sql管理起来好了,
那就动手吧
java 代码
 
  1. public class SqlManager{  
  2.         String getSql(String userId){  
  3.                 String sql;  
  4.         Role role=orgService.getRoleForUser(userId);  
  5.         if(("admin").equals(role.getName()))  
  6.             sql="select * from order";  
  7.         else if("bjadmin").equals(role.getName()))  
  8.                 sql="select * from order where area='beijing'";  
  9.         else if("shadmin").equals(role.getName()))  
  10.                 sql="select * from order where area='shanghai'";  
  11.         else if("qtadmin").equals(role.getName()))  
  12.                 sql="select * from order where area='qita'";  
  13.         else  
  14.           sql="select * from order where author="+userId;  
  15.         return sql;  
  16.         }  
  17. }  
这样把权限判断移到SqlManager里,业务代码就清爽了很多,再增加管理员就修改SqlManager好了
java 代码
 
  1. List getOrders(String userId){  
  2.             String sql=sqlManager.getSql(userId);  
  3.             Object o=excuteSql(sql);  
  4.             return excute(o);  
  5.        }  
呵呵,看起来还不错。但是等等,我们的业务方法为什么需要userId这个参数呢,是啊是啊,权限判断用到了它,但是那和我业务又有什么关系呢,不爽。现在AOP不是很流行吗,你不用AOP怎么能说明你技术高呢?快用吧快用吧,用不着也要想着方法用。
业务方法简化为
java 代码
 
  1. List getOrders(){  
  2.             String sql="";  
  3.             Object o=excuteSql(sql);  
  4.             return excute(o);  
  5.        }  
对excuteSql方法我们来AOP一下,注入权限判断过的sql.嘿嘿,技术水平又一次得到了显现。业务方法是幸福了,可我的SqlManager倒是很不幸福。咋办?用个配置文件吧,hibernate不是老鼓励我们把sql写在配置文件里吗?
xml 代码
 
  1. <xml>  
  2.     <sql role="admin">select * from order</sql>  
  3.     <sql role="bjadmin">select * from order where area='beijing'</sql>  
  4.     <sql role="shadmin">select * from order where area='shanghai'</sql>  
  5.     <sql role="qtadmin">select * from order where area='qita'</sql>  
  6.     <sql role="none">select * from order where author=?</sql>  
  7. </xml>  
这样SqlManager就可以把行数缩小了,就可以敏捷一点了。
java 代码
 
  1. public class SqlManager{  
  2.         String getSql(String userId){  
  3.                 String sql;  
  4.          Role role=orgService.getRoleForUser(userId);  
  5.          sql=getSqlfromXml(role.getName());  
  6.          return sql;  
  7.         }  
  8.           
  9.         String getSqlfromXml(String rolename){  
  10.                 ....  
  11.         }  
  12.  }  
以后再增加权限连类都不用修改了,改xml好了。等等,你是不是把问题太简单化了。现在不仅仅是订单,货物也要这么分区域管理。不错,我们应该想着通用一下了。这样,把SqlManager抽象一下
java 代码
 
  1. String abstract getSqlfromXml(String rolename);  
然后做几个子类好了 OrderSqlManager, GoodsSqlManager .
可是,哥们,书上说,要面向接口编程,你这样不太好吧。没事,再接口一下:
java 代码
 
  1. public interface SqlManagerInterface{  
  2.         String getSql(String userId);  
  3. }  
还是没法用啊。也许现在可以看看acegi的provider机制了,把这一大堆SqlManager全部作为provider,根据不同的模块选择不同的provider,统一拦截excuteSql方法,生成不同的sql到数据库执行。xml不爽?db也可以。然后,再然后呢?改你的类名,重构,和acegi整合一下。
呵呵,完全是个人的一些想法,希望多批评提提意见。我想表达的意思是:也许把数据权限再抽象一些,以组件的形式来减少侵入是可以做到的。

你可能感兴趣的:(AOP,sql,xml,配置管理,Acegi)