『壹』 Java.sql包中的Connection介面的「自定義類型映射」。
Oracle 官方網頁上有這段解釋,就是說我們如何把一個 SQL 東西翻譯成一個 Java 類型的。比如,一個 Date 列翻譯成 java.sql.Date,一個 number(1) 翻譯成 boolean 而不是 integer。
至於如何使用這個類型映射,你先在調試模式下看一下它原來返回的 getTypeMap() 是什麼樣的,裡面應該已經有默認的翻譯,只是不支持自定義的 SQL Type,比如 Java 類型或其它資料庫特有的類型。
Parameters:
columnIndex-thefirstcolumnis1,thesecondis2,...
map-ajava.util.amminglanguage
Returns:
另外一段:說connection.getTypeMap();演示我們把一個自定義的類型mySchemaName.ATHLETES的欄位翻譯成Athletes的java欄位。
Ausermaycreateanewtypemap,whichisajava.util.Mapobject,makeanentryinit,andpassittothejava..Inthiscase,ion.
Forexample,.,insertstheentryintoit,'stypemap.
java.util.Mapmap=con.getTypeMap();
map.put("mySchemaName.ATHLETES",Class.forName("Athletes"));
con.setTypeMap(map);
再說說寫一個自己的自定義類型:
http://docs.oracle.com/javase/tutorial/jdbc/basics/sqlcustommapping.html
http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getObject(int,%20java.util.Map)
『貳』 關於sql 包中的 statement 介面
你只知道什麼是介面,卻不知道為什麼要使用介面。
聽說介面回調這個說法嗎。你必須關心statement是怎麼來的。
Statement statement=connection.creStatement();
問題就在這句話裡面。 connection.creStatement();返回的到底是什麼?
請你仔細想好再回答。
其實connection.creStatement();返回的是一個實現了statement介面的類。
當然你不知道到底是哪個類,你只要知道它實現了statement介面就行,然後用介面的引用去指向那個類就叫介面回調。 你想想,你要開燈只要按一下那個開關,相當於那個介面引用,至於那個開關具體是怎麼實現開關燈功能的你不知道,你也不需要知道,對使用者來說,這就是介面的一大好處。因為具體返回哪個類由Connection類來決定,而且恰恰那個類也不用你寫。
那麼現在你應該知道 了,statement.execute();實現了沒有。 也就是人家幫你實現了那個介面,你只管用,不用關具體怎麼實現的,因為,那個方法需要什麼參數,有什麼功能在介面里已經寫的很清楚了。
再給你一個介面回調的例子。迭代器的實現
HashSet set=new HashSet();
Iterator it=set.iterator();
由hashset來決定怎麼去實現iterator介面,你只管定義介面引用,然後就去使用介面里有的方法就行。
『叄』 到底什麼是sql server資料庫的訪問介面
1(你這個不管是通過什麼方式接收數據,總之獲取數據,寫入數據的一個過程,資料庫中記錄了你的數據信息)
2(對方要數據,就是要訪問你的資料庫,說白了就是要看你上一步存進去的數據,對方要的介面,說白了就是你寫個功能,他傳遞進來參數,你從資料庫中查詢數據,返回給對方,至於這個介面怎麼實現,就看你的了,具體說就是你寫個方法實現資料庫訪問,讓人家調用)
『肆』 如何為sql server資料庫寫一個編程介面,需要注意什麼問題
編程寫一個連接池
用的時候從池中拿出connection,不用了就還回去
每次取的時候判斷是否為null,是就給個新的,不是就繼續讓他用
『伍』 java自定義一個類型,實現SQLXML介面
info欄位設置為xml類型...
資料庫 你插入varchar不就好了 提取出來你要的東西 加入xml為毛
用dom4j這個包可以很容易解析xml
『陸』 sql server 2000 有哪些編程介面
一
1、不同之:組織方式.文件系統的文件通常是由操作系統規定的,但是功能方面比較簡單,方便查找定位之用,文件與文件之間不能調用數據;而資料庫中的文件是由資料庫軟體組織的,其程度很高,能方便查找,更重要是它們之間聯系緊密!能相互傳遞據.
2、(1)物理數據層。它是資料庫的最內層,是物理存貯設備上實際存儲的數據的集合。這些數據是原始數據,是用戶加工的對象,由內部模式描述的指令操作處理的位串、字元和字組成。
(2)概念數據層。它是資料庫的中間一層,是資料庫的整體邏輯表示。指出了每個數據的邏輯定義及數據間的邏輯聯系,是存貯記錄的集合。它所涉及的是資料庫所有對象的邏輯關系,而不是它們的物理情況,是資料庫管理員概念下的資料庫。
(3)邏輯數據層。它是用戶所看到和使用的資料庫,表示了一個或一些特定用戶使用的數據集合,即邏輯記錄的集合。
3、程序和數據的獨立性是資料庫的主要特徵之一.作為工程資料庫管理系統,也必須保持這個特徵.為此,介紹了具體的工程資料庫管理系統EDRMS程序與數據的獨立性實現,並用實例予以說明.
二
1、a關系:關系是一個二維表,表的每行對應一個元組,表的列對應屬性。
b屬性:指關系中的列;
域:值的集,每個屬性的取值的范圍;
元組(Tuple):給出一組域產生笛卡兒乘積D1,D2…Dn,產生笛卡兒乘積D1*D2*….Dn=其中(d1,d2..dn)為元組。
c
關系的表:是一個簡單的表,不準許出現組合的屬性。
d用二維表的形式來表示實體集屬性間的關系,以及實體之間聯系的形式。
三
1、等值連接:在連接條件中使用等於號(=)運算符比較被連接列的列值,其查詢結果中列出被連接表中的所有列,包括其中的重復列。
自然連接:在連接條件中使用等於(=)運算符比較被連接列的列值,但它使用選擇列表指出查詢結果集合中所包括的列,並刪除連接表中的重復列。
四
1、在SQL Server 2000 中,資料庫由存儲特定結構化數據集的表集合組成。表中包含行(有時稱作記錄或元組)和列(有時稱作特性)的集合。表中的每一列都設計為存儲某種類型的信息(例如,日期、名稱、美元金額或數字)。表上有幾種控制(約束、規則、觸發器、默認值和自定義用戶數據類型)用於確保數據的有效性。表上可以有索引,利用索引可以快速地找到行。可將聲明引用完整性 (DRI) 約束添加到表上,以確保不同表中相互關聯的數據保持一致。資料庫還可以存儲過程,這些過程使用 Transact-SQL 編程代碼對資料庫中的數據進行操作,如存儲對表數據提供自定義訪問的視圖。
2、SQL Server 2000 使用一組文件映射資料庫。資料庫中的所有數據和對象(如表、存儲過程、觸發器和視圖)都存儲在文件組中。
3、主要數據文件,次要數據文件,事務日誌文件
4、因為利用事務日誌備份可以將資料庫恢復到特定的即時點(如輸入不想要的數據之前的那一點)或故障發生點。在媒體恢復策略中應考慮利用事務日誌備份。
五
1、表是包含資料庫中所有數據的資料庫對象。表定義為列的集合。
2、每行代表惟一的一條記錄,而每列代表記錄中的一個域。
3、一對多關系,多對多關系,一對一關系
六
1、Transact-Sql語言的分類如下:
數據類型
變數說明
用來說明變數的命令
流程式控制制語句
2、null表示空值;與其他的比較既非空於空值的區別;null在表中即為空擋數據。
5、通常與LIKE關鍵字一起來使用
可以用在檢查約束中使用LIKE
在後面的查詢語句中還會經常使用到
6、ORDER BY是一個可選的子句,它允許你根據指定要order by的列來以上升或者下降的順序來顯示查詢的
9、.SQL;文本文檔
八
資料庫中的索引與書籍中的目錄類似。在一本書中,利用目錄可以快速查找所需信息,無須閱讀整本書。在資料庫中,索引使資料庫程序無須對整個表進行掃描,就可以在其中找到所需數據。資料庫中的索引是一個表中所包含的值的列表,其中註明了表中包含各個值的行所在的存儲位置。可以為表中的單個列建立索引,也可以為一組列建立索引;索引採用B樹結構。索引包含一個條目,該條目有來自表中每一行的一個或多個列(搜索關鍵字)。B樹按搜索關鍵字排序,可以在搜索關鍵字的任何子詞條集合上進行高效搜索。例如,對於一個A、B、C列上的索引,可以在A,A、B,A、B、C上對其進行高效搜索。
在隨SQL Server 2000 提供的pubs示例資料庫中,employee表在emp_id列上有一個索引。當SQL Server執行一個語句,在employee 中根據指定的emp_id值查找數據時,它能夠識別emp_id列的索引,並使用該索引查找所需數據。如果該索引不存在,它會從表的第一行開始,逐行搜索指定的emp_id值。
SQL Server 2000為某些類型的約束(如PRIMARY KEY和UNIQUE約束)自動創建索引。可以通過創建不依賴於約束的索引,進一步對表定義進行自定義。
不過,索引為性能所帶來的好處卻是有代價的。帶索引的表在資料庫中會占據更多的空間。另外,為了維護索引,對數據進行插入、更新、刪除操作所花費的時間會更長。在設計和創建索引時,應確保對性能的提高程度大於在存儲空間和處理資源方面的代價。
在考慮是否為一個列創建索引時,應考慮被索引的列是否以及如何用於查詢中。索引對下列查詢很有幫助:
l 搜索符合特定搜索關鍵字值的行(精確匹配查詢)。精確匹配比較是指查詢使用 WHERE 語句指定具有給定值的列條目。例如WHERE emp_id = 'VPA30890F'。
l 搜索其搜索關鍵字值為范圍值的行(范圍查詢)。范圍查詢是指查詢指定其值介於兩個值之間的任何條目。例如WHERE job_lvl BETWEEN 9 and 12。
l 在表 T1 中搜索根據聯接謂詞與表 T2 中的某個行匹配的行(索引嵌套循環聯接)。
l 在不進行顯式排序操作的情況下產生經排序的查詢輸出,尤其是經過排序的動態游標。
l 在不進行顯式排序操作的情況下,按一種有序的順序對行進行掃描,以允許基於順序的操作,如合並聯接和流聚合。
l 以優於表掃描的性能對表中所有的行進行掃描,性能提高是由於減少了要掃描的列集和數據總量(該查詢有覆蓋索引可供使用)。
l 搜索插入和更新操作中重復的新搜索關鍵字值,以實施PRIMARY KEY和 UNIQUE 約束。
l 搜索已定義了FOREIGN KEY約束的兩個表之間匹配的行。
在很多查詢中,索引可以帶來多方面的好處。例如,索引除了可以覆蓋查詢外,還使得可以進行范圍查詢。SQL Server 2000可以在同一個查詢中為一個表使用多個索引,並可以合並多個索引,以便搜索關鍵字共同覆蓋一個查詢。另外,SQL Server會自動確定利用哪些索引進行查詢,並且能夠在表被改動時確保該表的所有索引都得到維護。
一個表如果建有大量索引會影響 INSERT、UPDATE 和 DELETE 語句的性能,因為在表中的數據更改時,所有索引都須進行適當的調整。另一方面,對於不需要修改數據的查詢(SELECT 語句),大量索引有助於提高性能,因為SQL Server 2000有更多的索引可供選擇,以便確定以最快速度訪問數據的最佳方法。對小型表進行索引可能不會產生優化效果,因為 SQL Server 2000在遍歷索引以搜索數據時,花費的時間可能會比簡單的表掃描還長。
九
視圖是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含一系列帶有名稱的列和行數據。但是,視圖並不在資料庫中以存儲的數據值集形式存在。行和列數據來自由定義視圖的查詢所引用的表,並且在引用視圖時動態生成。
對其中所引用的基礎表來說,視圖的作用類似於篩選。定義視圖的篩選可以來自當前或其他資料庫的一個或多個表,或者其他視圖。分布式查詢也可用於定義使用多個異類源數據的視圖。如果有幾台不同的伺服器分別存儲組織中不同地區的數據,而用戶需要將這些伺服器上相似結構的數據組合起來,這種方式就很有用。通過視圖進行查詢沒有任何限制,通過它們進行數據修改時的限制也很少。
視圖通常用來集中、簡化和自定義每個用戶對資料庫的不同認識。視圖可用作安全機制,方法是允許用戶通過視圖訪問數據,而不授予用戶直接訪問視圖基礎表的許可權。從SQL Server 2000 復制數據時也可使用視圖來提高性能並分區數據。
視圖可以簡化用戶操作數據的方式。可將經常使用的聯接、投影、聯合查詢和選擇查詢定義為視圖,這樣,用戶每次對特定的數據執行進一步操作時,不必指定所有條件和限定。例如,一個用於報表目的,並執行子查詢、外聯接及聚合以從一組表中檢索數據的復合查詢,就可以創建為一個視圖。視圖簡化了對數據的訪問,因為每次生成報表時無需寫或提交基礎查詢,而是查詢視圖。
視圖允許用戶以不同的方式查看數據,即使他們同時使用相同的數據時也如此。這在具有不同目的和技術水平的用戶共享同一個資料庫時尤為有利。例如,可定義一個視圖以僅檢索由客戶經理處理的客戶數據。視圖可以根據使用該視圖的客戶經理的登錄 ID 決定檢索哪些數據。
可使用視圖將數據導出至其他應用程序。例如,可能希望使用pubs資料庫中的stores和sales表在Excel中分析銷售數據。為此,可創建一個基於stores和sales表的視圖。然後使用數據導入導出工具導出由視圖定義的數據。
Transact-SQL UNION 集合運算符可在視圖內使用,以將來自不同表的兩個或多個查詢結果組合成單一的結果集。這在用戶看來是一個單獨的表,稱為分區視圖。例如,如果一個表含有華盛頓的銷售數據,另一個表含有加利福尼亞的銷售數據,即可從 UNION 創建這兩個表的視圖。該視圖代表了這兩個區域的銷售數據。使用分區視圖時,首先創建幾個相同的表,指定一個約束以決定可在各個表中添加的數據范圍。視圖即使用這些基表創建。當查詢該視圖時,SQL Server 自動決定查詢所影響的表,並僅引用這些表。例如,如果一個查詢指定只需要華盛頓特區的銷售數據,則 SQL Server 只讀取含有華盛頓特區銷售數據的表,而並不訪問其餘的表。分區試圖可基於來自多個異類源(如遠程伺服器)的數據,而不僅僅局限於同一資料庫中的表。例如,要將分別存儲組織中不同區域數據的幾台遠程伺服器上的數據組合起來,可以創建分布式查詢,從每個數據源中檢索數據,然後基於這些分布式查詢創建視圖。所有查詢都只從包含查詢所請求數據的遠程伺服器上讀取表中的數據,其他在視圖中由分布式查詢引用的伺服器均不被訪問。
十
在使用SQL Server 2000 創建應用程序時,Transact-SQL編程語言是應用程序和SQL Server資料庫之間的主要編程介面。使用Transact-SQL程序時,可用兩種方法存儲和執行程序。可以在本地存儲程序,並創建向SQL Server發送命令並處理結果的應用程序;也可以將程序在SQL Server中存儲為存儲過程,同時創建執行存儲過程並處理結果的應用程序。
SQL Server 2000中的存儲過程與其他編程語言中的過程類似,利用存儲過程可以完成以下任務。
l 接受輸入參數並以輸出參數的形式將多個值返回至調用過程或批處理。
l 包含執行資料庫操作(包括調用其他過程)的編程語句。
l 向調用過程或批處理返回狀態值,以表明成功或失敗(以及失敗原因)。
l 可使用 Transact-SQL EXECUTE 語句運行存儲過程。存儲過程與函數不同,因為存儲過程不返回取代其名稱的值,也不能直接用在表達式中。
使用SQL Server 2000中的存儲過程代替存儲在客戶計算機本地的Transact-SQL程序有很多的好處。
l 允許模塊化程序設計。只需創建過程一次並將其存儲在資料庫中,以後即可在程序中調用該過程任意次。存儲過程可由在資料庫編程方面有專長的人員創建,並可獨立於程序源代碼而單獨修改。
l 允許更快執行。如果某操作需要大量Transact-SQL代碼或需重復執行,存儲過程將比Transact-SQL批代碼的執行要快。將在創建存儲過程時對其進行分析和優化,並可在首次執行該過程後使用該過程的內存中版本。每次運行Transact-SQL語句時,都要從客戶端重復發送,並且在SQL Server 2000每次執行這些語句時,都要對其進行編譯和優化。
l 減少網路流量。一個需要數百行Transact-SQL代碼的操作由一條執行過程代碼的單獨語句就可實現,而不需要在網路中發送數百行代碼。
l 可作為安全機制使用。即使對於沒有直接執行存儲過程中語句的許可權的用戶,也可授予他們執行該存儲過程的許可權。
十一
SQL Server 2000 提供了兩種主要機制來強制業務規則和數據完整性:約束和觸發器。觸發器是一種特殊類型的存儲過程,它在指定的表中的數據發生變化時自動生效。喚醒調用觸發器以響應INSERT、UPDATE或DELETE語句。觸發器可以查詢其他表,並可以包含復雜的Transact-SQL語句。觸發器和觸發它的語句要作為可在觸發器內回滾的單個事務對待。如果檢測到嚴重錯誤(例如磁碟空間不足),則整個事務即自動回滾。
觸發器可通過資料庫中的相關表實現級聯更改。觸發器可以強制CHECK約束定義的約束更為復雜的約束。與CHECK約束不同,觸發器可以引用其他表中的列。例如,觸發器可以使用另一個表中的SELECT比較插入或更新的數據,以及執行其他操作,如修改數據或顯示用戶定義錯誤信息。觸發器也可以評估數據修改前後的表狀態,並根據其差異採取對策。一個表中的多個同類觸發器(INSERT、UPDATE或DELETE)允許採取多個不同的對策以響應同一個修改語句。
約束和觸發器在特殊情況下各有優勢。觸發器的主要好處在於它們可以包含使用Transact-SQL代碼的復雜處理邏輯。因此,觸發器可以支持約束的所有功能;但它在所給出的功能上並不總是最好的方法。
實體完整性總應在最低級別上通過索引進行強制,這些索引或是PRIMARY KEY和UNIQUE約束的一部分,或是在約束之外獨立創建的。假設功能可以滿足應用程序的功能需求,域完整性應通過CHECK約束進行強制,而引用完整性則應通過FOREIGN KEY約束進行強制。
十二
先創建登錄名,可以是windows登錄名也可以sql登錄名
windows登錄名是windows操作系統已經存在的用戶名
sql登錄名要在sql中創建而得的
要創建windows登錄名:
例如:已經在windows中存在一個pkxz用戶,域名是xxiang
create login [xxiang\pkxz] from windows with default_database = css
alter login pkxz with name=ppp
drop login pkxz
注意:只有administrators組的用戶可以訪問所有實例,並可獲所有訪問權,
其餘本地用戶組里的組,只能相對應的訪問實例。
例如:chenshanshan是users用戶組里的,是[xxinag2006\pkxz]實例的域用戶帳戶,
chenshanshan只能訪問這個實例,並可獲所有訪問權。
例如:joan是users用戶組里的,是[xxinag2006\pkxz]實例的登錄名,joan只能訪問這個實例。
要創建sql登錄名:
sql用戶名是pkxz
create login pkxz with password ='xx121314' , default_database = css
alter login pkxz with password = 'pp'
drop login pkxz
注意:sql用戶名只能相對應的訪問實例
例如:pc是[xxiang\pkxz]的登錄名,只能訪問這個實例,不可訪問別的實例。
兩者都創建了登錄名,且都是css為默認資料庫
然後創建完後把登錄名授予角色
sp_addsrvrolemember 'pkxz','sysadmin'
sp_dropsrvrolemember 'pkxz','sysadmin'
伺服器角色只能訪問相對應的實例操作!不能訪問別的實例!
創建用戶
Ceate user pkxz_user from login pkxz with default_schema = pkxz_schema
如果沒有創建架構的話,默認是dbo架構,這里是pkxz_schema
創建架構
創建架構的同時還可以創建該架構所擁有的表,視圖,羨慕且可以對這些對象設軒許可權。
create schema pkxz_schema authorization pkxz_user
Create Table pp (pp int)
Grant Select To pkxz_user_1
資料庫角色
可以自己添加,還有內置固定資料庫角色
自己添加角色
create role CreateTable authorization pkxz_user // CreateTable是角色名
分配許可權
Grant Insert To CreateTable
添加成員
sp_addrolemember 'CreateTable','pkxz_user_1'
public角色的兩個特點,1、初始狀態沒有許可權 2、所有的資料庫的成員都是他的成員
當修改了public角色,其實更改了所有資料庫成員的許可權
許可權的管理
Grant 授予 Revoke 收回許可權 Deny 否認許可權
例如:將一個表pt的插入許可權授予pkxz_user_1
Grant Insert On pt To pkxz_user_1
『柒』 mybatis自定義插件要實現什麼介面
竟然Mybatis是對四大介面進行攔截的,那我們葯先要知道Mybatis的四大介面對象 Executor, StatementHandler, ResultSetHandler, ParameterHandler。
上圖Mybatis框架的整個執行過程。Mybatis插件能夠對則四大對象進行攔截,可以包含到了Mybatis一次會議的所有操作。可見Mybatis的的插件很強大。
Executor是 Mybatis的內部執行器,它負責調用StatementHandler操作資料庫,並把結果集通過 ResultSetHandler進行自動映射,另外,他還處理了二級緩存的操作。從這里可以看出,我們也是可以通過插件來實現自定義的二級緩存的。
StatementHandler是Mybatis直接和資料庫執行sql腳本的對象。另外它也實現了Mybatis的一級緩存。這里,我們可以使用插件來實現對一級緩存的操作(禁用等等)。
ParameterHandler是Mybatis實現Sql入參設置的對象。插件可以改變我們Sql的參數默認設置。
ResultSetHandler是Mybatis把ResultSet集合映射成POJO的介面對象。我們可以定義插件對Mybatis的結果集自動映射進行修改。
插件Interceptor
Mybatis的插件實現要實現Interceptor介面,我們看下這個介面定義的方法。
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
這個介面只聲明了三個方法。
setProperties方法是在Mybatis進行配置插件的時候可以配置自定義相關屬性,即:介面實現對象的參數配置
plugin方法是插件用於封裝目標對象的,通過該方法我們可以返回目標對象本身,也可以返回一個它的代理,可以決定是否要進行攔截進而決定要返回一個什麼樣的目標對象,官方提供了示例:return Plugin.wrap(target, this);
intercept方法就是要進行攔截的時候要執行的方法
理解這個介面的定義,先要知道java動態代理機制。plugin介面即返回參數target對象(Executor/ParameterHandler/ResultSetHander/StatementHandler)的代理對象。在調用對應對象的介面的時候,可以進行攔截並處理。
Mybatis四大介面對象創建方法
Mybatis的插件是採用對四大介面的對象生成動態代理對象的方法來實現的。那麼現在我們看下Mybatis是怎麼創建這四大介面對象的。
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//確保ExecutorType不為空(defaultExecutorType有可能為空)
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor; if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
} if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
return resultSetHandler;
}
查看源碼可以發現, Mybatis框架在創建好這四大介面對象的實例後,都會調用InterceptorChain.pluginAll()方法。InterceptorChain對象是插件執行鏈對象,看源碼就知道裡面維護了Mybatis配置的所有插件(Interceptor)對象。
// target --> Executor/ParameterHandler/ResultSetHander/StatementHandler
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
其實就是安順序執行我們插件的plugin方法,一層一層返回我們原對象(Executor/ParameterHandler/ResultSetHander/StatementHandler)的代理對象。當我們調用四大介面對象的方法時候,實際上是調用代理對象的響應方法,代理對象又會調用十大介面對象的實例。
Plugin對象
我們知道,官方推薦插件實現plugin方法為:Plugin.wrap(target, this);
public static Object wrap(Object target, Interceptor interceptor) {
// 獲取插件的Intercepts註解
Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
Class<?> type = target.getClass();
Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap));
}
return target;
}
這個方法其實是Mybatis簡化我們插件實現的工具方法。其實就是根據當前攔截的對象創建了一個動態代理對象。代理對象的InvocationHandler處理器為新建的Plugin對象。
插件配置註解@Intercepts
Mybatis的插件都要有Intercepts註解來指定要攔截哪個對象的哪個方法。我們知道,Plugin.warp方法會返回四大介面對象的代理對象(通過new Plugin()創建的IvocationHandler處理器),會攔截所有的執行方法。在代理對象執行對應方法的時候,會調用InvocationHandler處理器的invoke方法。Mybatis中利用了註解的方式配置指定攔截哪些方法。具體如下:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set<Method> methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
} catch (Exception e) {
throw ExceptionUtil.unwrapThrowable(e);
}
}
可以看到,只有通過Intercepts註解指定的方法才會執行我們自定義插件的intercept方法。未通過Intercepts註解指定的將不會執行我們的intercept方法。
官方插件開發方式
@Intercepts({@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理對象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法參數
// do something ...... 方法攔截前執行代碼塊
Object result = invocation.proceed();
// do something .......方法攔截後執行代碼塊
return result;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
}
以上就是Mybatis官方推薦的插件實現的方法,通過Plugin對象創建被代理對象的動態代理對象。可以發現,Mybatis的插件開發還是很簡單的。
自定義開發方式
Mybatis的插件開發通過內部提供的Plugin對象可以很簡單的開發。只有理解了插件實現原理,對應不採用Plugin對象我們一樣可以自己實現插件的開發。下面是我個人理解之後的自己實現的一種方式。
public class TestInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理對象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法參數
// do something ...... 方法攔截前執行代碼塊
Object result = invocation.proceed();
// do something .......方法攔截後執行代碼塊
return result;
}
public Object plugin(final Object target) {
return Proxy.newProxyInstance(Interceptor.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return intercept(new Invocation(target, method, args));
}
});
}
public void setProperties(Properties properties) {
}
}
當然,Mybatis插件的那這個時候Intercepts的註解起不到作用了。
作者:曹金桂
鏈接:http://www.jianshu.com/p/7c7b8c2c985d
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
『捌』 怎樣設計一個SQL和ACCESS資料庫通用的介面
把SQL和ACCESS兩個連接都寫出來,簡單點用IF就行了,如果連接SQL不成功就去連接ACCESS
『玖』 如何使用sql server 資料庫介面
要實現跟資料庫連接操作,第一:寫一個資料庫連接類,第二:配置訪問資料庫基本元素,可以採用*.XML形式(配置IP,埠,用戶名,密碼等),第三:門診收費系統會提供一個介面調用資料庫連接類的。一般像在醫院或門診這地方,一般都是採用配置形式做資料庫連接的,直接拿配置文件修改一下連接IP地址就可以了,但確保資料庫伺服器上有資料庫表,有連接配置上還要提供一下伺服器IP,埠,和資料庫用戶名和密碼就可以了。在SQL SERVER2008資料庫上只做授權操作即可,授權操作可以有用戶管理裡面進行。允許該用戶查詢和修改等操作就OK了。
『拾』 SQL如何做介面
好像不行吧。
SQL是面向過程的,沒有面向對象的功能。