2010年5月7日
#
http://www.iteye.com/topic/930648
RBAC(Role-Based Access Control,基于角色的訪問(wèn)控制),就是用戶通過(guò)角色與權(quán)限進(jìn)行關(guān)聯(lián)。簡(jiǎn)單地說(shuō),一個(gè)用戶擁有若干角色,每一個(gè)角色擁有若干權(quán)限。這樣,就構(gòu)造成“用戶-角色-權(quán)限”的授權(quán)模型。在這種模型中,用戶與角色之間,角色與權(quán)限之間,一般者是多對(duì)多的關(guān)系。(如下圖)

角色是什么?可以理解為一定數(shù)量的權(quán)限的集合,權(quán)限的載體。例如:一個(gè)論壇系統(tǒng),“超級(jí)管理員”、“版主”都是角色。版主可管理版內(nèi)的帖子、可管理版內(nèi)的用戶等,這些是權(quán)限。要給某個(gè)用戶授予這些權(quán)限,不需要直接將權(quán)限授予用戶,可將“版主”這個(gè)角色賦予該用戶。
當(dāng)用戶的數(shù)量非常大時(shí),要給系統(tǒng)每個(gè)用戶逐一授權(quán)(授角色),是件非常煩瑣的事情。這時(shí),就需要給用戶分組,每個(gè)用戶組內(nèi)有多個(gè)用戶。除了可給用戶授權(quán)外,還可以給用戶組授權(quán)。這樣一來(lái),用戶擁有的所有權(quán)限,就是用戶個(gè)人擁有的權(quán)限與該用戶所在用戶組擁有的權(quán)限之和。(下圖為用戶組、用戶與角色三者的關(guān)聯(lián)關(guān)系)

在應(yīng)用系統(tǒng)中,權(quán)限表現(xiàn)成什么?對(duì)功能模塊的操作,對(duì)上傳文件的刪改,菜單的訪問(wèn),甚至頁(yè)面上某個(gè)按鈕、某個(gè)圖片的可見(jiàn)性控制,都可屬于權(quán)限的范疇。有些權(quán)限設(shè)計(jì),會(huì)把功能操作作為一類,而把文件、菜單、頁(yè)面元素等作為另一類,這樣構(gòu)成“用戶-角色-權(quán)限-資源”的授權(quán)模型。而在做數(shù)據(jù)表建模時(shí),可把功能操作和資源統(tǒng)一管理,也就是都直接與權(quán)限表進(jìn)行關(guān)聯(lián),這樣可能更具便捷性和易擴(kuò)展性。(見(jiàn)下圖)

請(qǐng)留意權(quán)限表中有一列“權(quán)限類型”,我們根據(jù)它的取值來(lái)區(qū)分是哪一類權(quán)限,如“MENU”表示菜單的訪問(wèn)權(quán)限、“OPERATION”表示功能模塊的操作權(quán)限、“FILE”表示文件的修改權(quán)限、“ELEMENT”表示頁(yè)面元素的可見(jiàn)性控制等。
這樣設(shè)計(jì)的好處有二。其一,不需要區(qū)分哪些是權(quán)限操作,哪些是資源,(實(shí)際上,有時(shí)候也不好區(qū)分,如菜單,把它理解為資源呢還是功能模塊權(quán)限呢?)。其二,方便擴(kuò)展,當(dāng)系統(tǒng)要對(duì)新的東西進(jìn)行權(quán)限控制時(shí),我只需要建立一個(gè)新的關(guān)聯(lián)表“權(quán)限XX關(guān)聯(lián)表”,并確定這類權(quán)限的權(quán)限類型字符串。
這里要注意的是,權(quán)限表與權(quán)限菜單關(guān)聯(lián)表、權(quán)限菜單關(guān)聯(lián)表與菜單表都是一對(duì)一的關(guān)系。(文件、頁(yè)面權(quán)限點(diǎn)、功能操作等同理)。也就是每添加一個(gè)菜單,就得同時(shí)往這三個(gè)表中各插入一條記錄。這樣,可以不需要權(quán)限菜單關(guān)聯(lián)表,讓權(quán)限表與菜單表直接關(guān)聯(lián),此時(shí),須在權(quán)限表中新增一列用來(lái)保存菜單的ID,權(quán)限表通過(guò)“權(quán)限類型”和這個(gè)ID來(lái)區(qū)分是種類型下的哪條記錄。
到這里,RBAC權(quán)限模型的擴(kuò)展模型的完整設(shè)計(jì)圖如下:

隨著系統(tǒng)的日益龐大,為了方便管理,可引入角色組對(duì)角色進(jìn)行分類管理,跟用戶組不同,角色組不參與授權(quán)。例如:某電網(wǎng)系統(tǒng)的權(quán)限管理模塊中,角色就是掛在區(qū)局下,而區(qū)局在這里可當(dāng)作角色組,它不參于權(quán)限分配。另外,為方便上面各主表自身的管理與查找,可采用樹(shù)型結(jié)構(gòu),如菜單樹(shù)、功能樹(shù)等,當(dāng)然這些可不需要參于權(quán)限分配。
http://developer.51cto.com/art/200907/136668.htmspring 中已經(jīng)提供了很好的實(shí)現(xiàn),所以這又省去了很多的功夫,接下來(lái)看看
iBATIS是如何支持
Clob和blob的。
iBATIS提供了TypeHandler接口,用于處理數(shù)據(jù)類型,基本的實(shí)現(xiàn)類為BaseTypeHandler
在spring 中,提供了AbstractLobTypeHandler作為基礎(chǔ)類,并且提供了相應(yīng)的模版方法,所有的工作由LobHandler處理。
BlobByteArrayTypeHandler 主要用于處理blob類型數(shù)據(jù),使用byte[]來(lái)映射相應(yīng)的Blob
ClobStringTypeHandler 用于處理Clob類型數(shù)據(jù),使用字符串來(lái)映射Clob
有一點(diǎn)需要注意的是,AbstractLobTypeHandler中實(shí)現(xiàn)了事務(wù)支持,需要用來(lái)釋放相應(yīng)的資源,所以一定需要在事務(wù)環(huán)境中進(jìn)行。
下面是一個(gè)簡(jiǎn)單的例子:
- public class Food {
- private String content;
-
- private String id;
-
- private byte[] image;
-
- private String name;
- ...
- }
xml如下:說(shuō)明一下,在resultMap中可以通過(guò)typeHandler來(lái)指定具體的handler.在inline變量中,可以通過(guò)handler來(lái)定義相應(yīng)的typeHandler
- ﹤sqlMap namespace="Food"﹥
-
- ﹤typeAlias alias="Food" type="org.esoft.hdb.bo.Food"/﹥
- ﹤resultMap id="foodResult" class="Food"﹥
- ﹤result property="id" column="C_ID"/﹥
- ﹤result property="name" column="C_NAME"/﹥
- ﹤result property="content" column="C_content"
- typeHandler="org.springframework.orm.ibatis.support.ClobStringTypeHandler"/﹥
- ﹤result property="image" column="C_image"
- typeHandler="org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler"/﹥
- ﹤/resultMap﹥
- ﹤sql id="foodFragment"﹥select C_ID,C_NAME,C_CONTENT,C_IMAGE from T_FOOD﹤/sql﹥
- ﹤select id="getAll" resultMap="foodResult"﹥
- ﹤include refid="foodFragment"/﹥
- ﹤/select﹥
- ﹤select id="selectById" parameterClass="string" resultMap="foodResult"﹥
- ﹤include refid="foodFragment"/﹥ where C_ID=#id#﹤/select﹥
-
- ﹤insert id="insert" parameterClass="Food"﹥ insert into T_FOOD ( C_ID,
- C_NAME,C_CONTENT, C_IMAGE) values ( #id#,
- #name#,#content,handler=org.springframework.orm.ibatis.support.ClobStringTypeHandler#,
- #image,handler=org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler#)
- ﹤/insert﹥
-
- ﹤update id="update" parameterClass="Food"﹥ update T_FOOD set C_NAME = #name#,
- C_CONTENT =
- #content,handler=org.springframework.orm.ibatis.support.ClobStringTypeHandler#,
- C_IMAGE =
- #image,handler=org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler#
- where C_ID = #id# ﹤/update﹥
-
- ﹤delete id="deleteById" parameterClass="string"﹥ delete from T_FOOD where C_ID = #id#
- ﹤/delete﹥
-
- ﹤/sqlMap﹥
-
-
- public interface FoodService {
-
-
- void save(Food food);
- Food get(String id);
- /**
- * @param food
- */
- void update(Food food);
- }
-
- public class FoodServiceImpl implements FoodService {
- private FoodDAO foodDAO;
-
- private DaoCreator creator;
-
- public void setCreator(DaoCreator creator) {
- this.creator = creator;
- }
-
- protected FoodDAO getFoodDAO() {
- if (foodDAO == null) {
- foodDAO = (FoodDAO) creator.createDao(FoodDAO.class, Food.class);
- }
- return foodDAO;
- }
-
- public Food get(String id) {
- return getFoodDAO().get(id);
- }
- public void save(Food food) {
- getFoodDAO().save(food);
- }
- public void update(Food food) {
- getFoodDAO().update(food);
- }
-
- }
-
- spring xml 配置:
-
- 。。。
- ﹤bean id="lobHandler"
- class="org.springframework.jdbc.support.lob.DefaultLobHandler"/﹥
-
- ﹤bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager"﹥
- ﹤property name="dataSource" ref="dataSource"/﹥
- ﹤/bean﹥
-
- ﹤bean id="sqlMapClient"
- class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"﹥
- ﹤property name="dataSource" ref="dataSource"/﹥
- ﹤property name="configLocation"﹥
- ﹤value﹥SqlMapConfig.xml﹤/value﹥
- ﹤/property﹥
- ﹤property name="lobHandler" ref="lobHandler"/﹥
- ﹤/bean﹥
-
- ﹤bean id="daoCreate" class="org.esoft.hdb.ibatis.IbatisDaoCreator"﹥
- ﹤property name="sqlMapClient" ref="sqlMapClient"/﹥
- ﹤/bean﹥
-
- ﹤bean id="foodService" class="org.esoft.hdb.service.FoodServiceImpl"﹥
- ﹤property name="creator" ref="daoCreate"/﹥
- ﹤/bean﹥
-
-
- ﹤aop:config﹥
- ﹤aop:pointcut id="foodServiceMethods"
- expression="execution(* org.esoft.hdb.service.FoodService.*(..))"/﹥
- ﹤aop:advisor advice-ref="txAdvice" pointcut-ref="foodServiceMethods"/﹥
- ﹤/aop:config﹥
- ﹤tx:advice id="txAdvice" transaction-manager="transactionManager"﹥
- ﹤tx:attributes﹥
- ﹤tx:method name="*" propagation="REQUIRED"/﹥
- ﹤/tx:attributes﹥
- ﹤/tx:advice﹥
簡(jiǎn)單的測(cè)試:
- save :
- Food food = new Food();
- food.setPk("1");
- food.setName("food1");
- BufferedInputStream in = new BufferedInputStream(getClass()
- .getResourceAsStream("/1.gif"));
- byte[] b = FileCopyUtils.copyToByteArray(in);
- food.setImage(b);
- in = new BufferedInputStream(getClass().getResourceAsStream(
- "/hibernate.cfg.xml"));
- b = FileCopyUtils.copyToByteArray(in);
- food.setContent(new String(b));
- foodService.save(food);
- update:
- Food food = foodService.get("1");
- BufferedInputStream in = new BufferedInputStream(getClass()
- .getResourceAsStream("/jdbc.properties"));
- byte[] b = FileCopyUtils.copyToByteArray(in);
- food.setContent(new String(b));
- foodService.update(food);
- food = foodService.get("1");
- assertNotNull(food.getImage());
select sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
lo.locked_mode
from v$locked_object lo,
dba_objects ao,
v$session sess
where ao.object_id = lo.object_id and lo.session_id = sess.SID;獲得未提交的事物的列表和基礎(chǔ)信息
然后根據(jù) sessionID和serial#號(hào)強(qiáng)制關(guān)閉事物:
ALTER SYSTEM KILL SESSION '9,108';
--'9,108'為sessionID和serial#號(hào),逗號(hào)分開(kāi)
http://www.javaeye.com/topic/37302
類與類之間的關(guān)系對(duì)于理解面向?qū)ο缶哂泻苤匾淖饔茫郧霸诿嬖嚨臅r(shí)候也經(jīng)常被問(wèn)到這個(gè)問(wèn)題,在這里我就介紹一下。
類與類之間存在以下關(guān)系:
(1)泛化(Generalization)
(2)關(guān)聯(lián)(Association)
(3)依賴(Dependency)
(4)聚合(Aggregation)
UML圖與應(yīng)用代碼例子:
1.泛化(Generalization)
[泛化]
表示類與類之間的繼承關(guān)系,接口與接口之間的繼承關(guān)系,或類對(duì)接口的實(shí)現(xiàn)關(guān)系。一般化的關(guān)系是從子類指向父類的,與繼承或?qū)崿F(xiàn)的方法相反。
[具體表現(xiàn)]
父類 父類實(shí)例=new 子類()
[UML圖](圖1.1)


圖1.1 Animal類與Tiger類,Dog類的泛化關(guān)系
[代碼表現(xiàn)]
- class Animal{}
- class Tiger extends Animal{}
- public class Test
- {
- public void test()
- {
- Animal a=new Tiger();
- }
- }
2.依賴(Dependency)
[依賴]
對(duì)于兩個(gè)相對(duì)獨(dú)立的對(duì)象,當(dāng)一個(gè)對(duì)象負(fù)責(zé)構(gòu)造另一個(gè)對(duì)象的實(shí)例,或者依賴另一個(gè)對(duì)象的服務(wù)時(shí),這兩個(gè)對(duì)象之間主要體現(xiàn)為依賴關(guān)系。
[具體表現(xiàn)]
依賴關(guān)系表現(xiàn)在局部變量,方法的參數(shù),以及對(duì)靜態(tài)方法的調(diào)用
[現(xiàn)實(shí)例子]
比如說(shuō)你要去擰螺絲,你是不是要借助(也就是依賴)螺絲刀(Screwdriver)來(lái)幫助你完成擰螺絲(screw)的工作
[UML表現(xiàn)](圖1.2)

圖1.2 Person類與Screwdriver類的依賴關(guān)系
[代碼表現(xiàn)]
- public class Person{
-
- public void screw(Screwdriver screwdriver){
- screwdriver.screw();
- }
- }
3.關(guān)聯(lián)(Association)
[關(guān)聯(lián)]
對(duì)于兩個(gè)相對(duì)獨(dú)立的對(duì)象,當(dāng)一個(gè)對(duì)象的實(shí)例與另一個(gè)對(duì)象的一些特定實(shí)例存在固定的對(duì)應(yīng)關(guān)系時(shí),這兩個(gè)對(duì)象之間為關(guān)聯(lián)關(guān)系。
[具體表現(xiàn)]
關(guān)聯(lián)關(guān)系是使用實(shí)例變量來(lái)實(shí)現(xiàn)
[現(xiàn)實(shí)例子]
比如客戶和訂單,每個(gè)訂單對(duì)應(yīng)特定的客戶,每個(gè)客戶對(duì)應(yīng)一些特定的訂單;再例如公司和員工,每個(gè)公司對(duì)應(yīng)一些特定的員工,每個(gè)員工對(duì)應(yīng)一特定的公司
[UML圖] (圖1.3)

圖1.3 公司和員工的關(guān)聯(lián)關(guān)系
[代碼表現(xiàn)]
- public class Company{
- private Employee employee;
- public Employee getEmployee(){
- return employee;
- }
- public void setEmployee(Employee employee){
- this.employee=employee;
- }
-
- public void run(){
- employee.startWorking();
- }
- }
(4)聚合(Aggregation)
[聚合]
當(dāng)對(duì)象A被加入到對(duì)象B中,成為對(duì)象B的組成部分時(shí),對(duì)象B和對(duì)象A之間為聚集關(guān)系。聚合是關(guān)聯(lián)關(guān)系的一種,是較強(qiáng)的關(guān)聯(lián)關(guān)系,強(qiáng)調(diào)的是整體與部分之間的關(guān)系。
[具體表現(xiàn)]
與關(guān)聯(lián)關(guān)系一樣,聚合關(guān)系也是通過(guò)實(shí)例變量來(lái)實(shí)現(xiàn)這樣關(guān)系的。關(guān)聯(lián)關(guān)系和聚合關(guān)系來(lái)語(yǔ)法上是沒(méi)辦法區(qū)分的,從語(yǔ)義上才能更好的區(qū)分兩者的區(qū)別。
[關(guān)聯(lián)與聚合的區(qū)別]
(1)關(guān)聯(lián)關(guān)系所涉及的兩個(gè)對(duì)象是處在同一個(gè)層次上的。比如人和自行車就是一種關(guān)聯(lián)關(guān)系,而不是聚合關(guān)系,因?yàn)槿瞬皇怯勺孕熊嚱M成的。
聚合關(guān)系涉及的兩個(gè)對(duì)象處于不平等的層次上,一個(gè)代表整體,一個(gè)代表部分。比如電腦和它的顯示器、鍵盤、主板以及內(nèi)存就是聚集關(guān)系,因?yàn)橹靼迨请娔X的組成部分。
(2)對(duì)于具有聚集關(guān)系(尤其是強(qiáng)聚集關(guān)系)的兩個(gè)對(duì)象,整體對(duì)象會(huì)制約它的組成對(duì)象的生命周期。部分類的對(duì)象不能單獨(dú)存在,它的生命周期依賴于整體類的對(duì)象的生命周期,當(dāng)整體消失,部分也就隨之消失。比如張三的電腦被偷了,那么電腦的所有組件也不存在了,除非張三事先把一些電腦的組件(比如硬盤和內(nèi)存)拆了下來(lái)。
[UML圖](圖1.4)

圖1.3 電腦和組件的聚合關(guān)系
[代碼表現(xiàn)]
- public class Computer{
- private CPU cpu;
- public CPU getCPU(){
- return cpu;
- }
- public void setCPU(CPU cpu){
- this.cpu=cpu;
- }
-
- public void start(){
-
- cpu.run();
- }
- }