數(shù)據(jù)連接學習(一):JNDI入門及數(shù)據(jù)源配置


0.學習原因

因為學習Spring時涉及到了很多關于JNDI的知識,臥槽肋乍,壓根沒聽說過呀,所以特地來學習一下煌往。
參考博客:
JNDI學習總結(一)——JNDI數(shù)據(jù)源的配置


1.JNDI的誕生及簡介簡介

1)服務器數(shù)據(jù)源配置的誕生

  1. JDBC階段:
    一開始是使用JDBC來連接操作數(shù)據(jù)庫的:
    在Java開發(fā)中,使用JDBC操作數(shù)據(jù)庫的四個步驟如下:

    ①加載數(shù)據(jù)庫驅動程序(Class.forName("數(shù)據(jù)庫驅動類");)
    ②連接數(shù)據(jù)庫(Connection con = DriverManager.getConnection();)
    ③操作數(shù)據(jù)庫(PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();)
    ④關閉數(shù)據(jù)庫力穗,釋放連接(con.close();)

  2. 所有的用戶都需要經(jīng)過此四步進行操作电爹,但是這四步之中有三步(①加載數(shù)據(jù)庫驅動程序须鼎、②連接數(shù)據(jù)庫诞外、④關閉數(shù)據(jù)庫澜沟,釋放連接)對所有人都是一樣的,而所有人只有在操作數(shù)據(jù)庫上是不一樣峡谊,那么這就造成了性能的損耗茫虽。
    那么最好的做法是,準備出一個空間既们,此空間里專門保存著全部的數(shù)據(jù)庫連接濒析,以后用戶用數(shù)據(jù)庫操作的時候不用再重新加載驅動、連接數(shù)據(jù)庫之類的啥纸,而直接從此空間中取走連接号杏,關閉的時候直接把連接放回到此空間之中。
    而這個空間就是連接池斯棒。

  3. 但是連接池的是有會有以下疑慮:

    1盾致、 如果沒有任何一個用戶使用連接莹妒,那么那么應該維持一定數(shù)量的連接,等待用戶使用绰上。
    2、 如果連接已經(jīng)滿了渠驼,則必須打開新的連接蜈块,供更多用戶使用。
    3迷扇、 如果一個服務器就只能有100個連接百揭,那么如果有第101個人過來呢?應該等待其他用戶釋放連接
    4蜓席、 如果一個用戶等待時間太長了器一,則應該告訴用戶,操作是失敗的厨内。

  4. 如果直接用程序實現(xiàn)以上功能祈秕,則會比較麻煩。
    所以在Tomcat 4.1.27之后雏胃,在服務器上就直接增加了數(shù)據(jù)源的配置選項请毛,直接在服務器上配置好數(shù)據(jù)源連接池即可。在J2EE服務器上保存著一個數(shù)據(jù)庫的多個連接瞭亮。每一個連接通過DataSource可以找到方仿。DataSource被綁定在了JNDI樹上(為每一個DataSource提供一個名字)客戶端通過名稱找到在JNDI樹上綁定的DataSource,再由DataSource找到一個連接统翩。

  5. 示意圖如下:


    00042JNDI學習1-01.jpg
  6. 網(wǎng)上流傳的圖:


    00042JNDI學習1-02.jpg
  7. 那么在以后的操作中仙蚜,除了數(shù)據(jù)庫的連接方式不一樣之外,其他的所有操作都一樣厂汗,只是關閉的時候不是徹底地關閉數(shù)據(jù)庫委粉,而是把數(shù)據(jù)庫的連接放回到連接池中去。

2)JNDI的簡介及優(yōu)點:

  1. JNDI的定義:
    上面知道了JNDI的作用面徽,JNDI的定義也就很容易理解了:
    JNDI是Java命名與文件夾接口(Java Naming and Directory Interface)艳丛,在J2EE規(guī)范中是重要的規(guī)范之中的一個。
    簡單的理解趟紊,區(qū)別于JDBC,就是:
    jdbc是java去找數(shù)據(jù)庫驅動氮双,jndi是通過你的服務器配置(如Tomcat)的配置文件context來找數(shù)據(jù)庫驅動~
  2. 現(xiàn)在JNDI已經(jīng)成為J2EE的標準之一,所有的J2EE容器都必須提供一個JNDI的服務霎匈。(web容器就是Tomcat等服務器充當?shù)?
  3. 為什么使用了連接池還要用JNDI:

    為了數(shù)據(jù)庫資源的管理戴差,在容器中配置一個數(shù)據(jù)庫連接池,使用JNDI 來管理
    這樣容器中運行多個服務的時候铛嘱,每個服務只需添加一個jndi的名稱就可以連接到數(shù)據(jù)庫了
    如果不使用jndi的方式暖释,直接在項目中配置數(shù)據(jù)庫連接池袭厂,那么每個項目需要配置一次,如果更改數(shù)據(jù)庫地址時球匕,
    每個項目的數(shù)據(jù)庫連接方式都要更改纹磺,比較麻煩,使用jndi的話亮曹,直接更改一下jndi里面的數(shù)據(jù)庫連接池的配置就可以了橄杨,方便一些。

  4. 一般來說如果目標客戶有專業(yè)的應用服務器照卦,比如 WebSphere式矫,WebLogic,我們就不需要在代碼中配置使用特定的 dbcp 或其它的連接池了役耕。只使用JNDI就可以了采转。

2.JNDI+Tomcat配置數(shù)據(jù)源(全局配置)

1)Tomcat全局配置:

  1. 需要在tomcat中的server.xml中配置數(shù)據(jù)源:


    00042JNDI學習1-03.jpg
  2. 在Tomcat的lib目錄下添加驅動包:


    00042JNDI學習1-04.jpg
  3. 打開server.xml,一般都有一個默認的全局配置(Resource)標簽:


    00042JNDI學習1-05.jpg

代碼如下:

    <GlobalNamingResources>
        <Resource auth="Container" description="User databasethat can be updated and saved" 
        factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 
        name="UserDatabase" 
        pathname="conf/tomcat-users.xml" 
        type="org.apache.catalina.UserDatabase"/>
    </GlobalNamingResources>
  1. 在默認的Resource下添加配置如下:

     <Resource 
         name="jdbc/mysql"
         auth="Container" 
         type="javax.sql.DataSource"
         maxActive="100" 
         maxIdle="30" 
         maxWait="10000"
         username="root" 
         password="root"
         driverClassName="com.mysql.jdbc.Driver"
         url="jdbc:mysql://127.0.0.1:3306/springtest?useUnicode=true&amp;characterEncoding=utf-8"/>
    

各項配置的含義后面介紹瞬痘。

  1. 以上兩步(導包+配置server.xml)全局配置就已經(jīng)配置好了故慈。
    這一步并非必須的,可以不寫框全,親測沒有失敗
    在需要使用的JNDI的項目中的web.xml中引用該配置:

     <resource-ref>
         <res-ref-name>jdbc/mysql</res-ref-name>
         <res-type>javax.sql.DataSource</res-type>
         <res-auth>Container</res-auth>
     </resource-ref>
    

屬于可選配置惯悠,如果在web.xml中加入了上面的配置,則需要在Tomcat中一定要配置對應的Resource竣况,否則會報錯克婶。

  1. 查看Service的最下面,可以看到有當前工程的上下文:


    00042JNDI學習1-06.jpg

在該上下文中增加對全局配置的引用:

    <Context docBase="JNDITest" path="/JNDITest" reloadable="true" source="org.eclipse.jst.jee.server:JNDITest">
            <ResourceLink global="mysqlData" name="jdbc/mysql" type="javax.sql.DataSource" />
    </Context>

配置模板:

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
    jndi配置方法(tomcat):
     -->
    <!--映射JNDITest項目的虛擬目錄-->
    <Context docBase="D:/MyEclipse8.5/workspace/JNDITest/WebRoot" debug="0" reloadable="false">
        <!--global指的是全局配置的name,
            name指的是這個DataSourse的名字-->
        <!--引用全局配置-->
        <ResourceLink name="mysqlData" global="jdbc/mysql" type="javax.sql.DataSource"/>
    </Context>
  1. 這一步可以替換第6步(寫了這個則不用配置第六步):
    在項目的META-INF下面建立context.xml文件丹泉,在里面寫上:

     <?xml version="1.0" encoding="UTF-8"?> 
     <Context> 
         <ResourceLink name="mysqlData" global="jdbc/mysql type="javax.sql.DataSource"/> 
     </Context>
    
  2. 第6步替換策略二(自認為最簡單的方式):
    找到Tomcat下的conf/context.xml文件:


    00042JNDI學習1-08.jpg

配置上:

    <Context>
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
        <ResourceLink name="mysqlData" global="jdbc/mysql" type="javax.sql.DataSource"/>
    </Context>

這句話就可以了情萤。
所以第六步可以有三種策略(我只測試了一種)。

2)創(chuàng)建測試類代碼:

  1. 創(chuàng)建測試類:(最簡單的jsp測試)

     <%@page import="javax.naming.InitialContext"%>  
     <%@page import="javax.naming.Context"%>  
     <%@page import="javax.sql.DataSource"%>  
     <%@ page language="java" contentType="text/html; charset=utf-8"  
         pageEncoding="utf-8"%>  
     <%  
         Context initContext = new InitialContext();     //上轉型摹恨,也可以不用上轉型 
         DataSource ds = (DataSource)initContext.lookup("java:/comp/env/mysqlData");  
         out.print(ds); 
     %> 
    
  2. 測試結果:


    00042JNDI學習1-07.jpg

成功獲取到數(shù)據(jù)源(javax.sql.datasource對象)筋岛。

  1. 注意事項:
    java:/comp/env/,這是j2ee的命名空間晒哄,其他地方可能會變
    context.lookup(“XXX”)睁宰,在任何時候都是有效的,只要XXX確實是一個存在的JNDI名寝凌。
    Tomcat的全局JNDI資源不能直接訪問柒傻,必須有java:comp/env/前綴。
    這樣子配置好的工程默認使用的是Tomcat自帶的dbcp連接池较木。

3)JNDI的配置模板:

<GlobalNamingResources>
    <!--默認的這個配置不要刪除-->
    <Resource name="UserDatabase" auth="Container"
            type="org.apache.catalina.UserDatabase"
            description="User database that can be updated and saved"
            factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
            pathname="conf/tomcat-users.xml" />
    
    <!--
    |- name:表示以后要查找的名稱红符。通過此名稱可以找到DataSource,此名稱任意更換,但是程序中最終要查找的就是此名稱预侯,
    為了不與其他的名稱混淆致开,所以使用jdbc/oracle,現(xiàn)在配置的是一個jdbc的關于oracle的命名服務萎馅。
    |- auth:由容器進行授權及管理双戳,指的用戶名和密碼是否可以在容器上生效
    |- type:此名稱所代表的類型,現(xiàn)在為javax.sql.DataSource
    |- maxActive:表示一個數(shù)據(jù)庫在此服務器上所能打開的最大連接數(shù)
    |- maxIdle:表示一個數(shù)據(jù)庫在此服務器上維持的最小連接數(shù)
    |- maxWait:最大等待時間糜芳。10000毫秒
    |- username:數(shù)據(jù)庫連接的用戶名
    |- password:數(shù)據(jù)庫連接的密碼
    |- driverClassName:數(shù)據(jù)庫連接的驅動程序
    |- url:數(shù)據(jù)庫連接的地址
    -->
    
    <!--配置Oracle數(shù)據(jù)庫的JNDI數(shù)據(jù)源-->
    <Resource 
            name="jdbc/oracle"
            auth="Container" 
            type="javax.sql.DataSource"
            maxActive="100" 
            maxIdle="30" 
            maxWait="10000"
            username="lead_oams" 
            password="p"
            driverClassName="oracle.jdbc.driver.OracleDriver"
            url="jdbc:oracle:thin:@127.0.0.1:1521:lead"/>
    
    <!--配置MySQL數(shù)據(jù)庫的JNDI數(shù)據(jù)源-->
    <Resource 
            name="jdbc/mysql"
            auth="Container" 
            type="javax.sql.DataSource"
            maxActive="100" 
            maxIdle="30" 
            maxWait="10000"
            username="root" 
            password="root"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://127.0.0.1:3306/leadtest?useUnicode=true&amp;characterEncoding=utf-8"/>
    
    <!--配置SQLServer數(shù)據(jù)庫的JNDI數(shù)據(jù)源-->
    <Resource 
            name="jdbc/sqlserver"
            auth="Container" 
            type="javax.sql.DataSource"
            maxActive="100" 
            maxIdle="30" 
            maxWait="10000"
            username="sa" 
            password="p@ssw0rd"
            driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
            url="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=demo"/>
    
</GlobalNamingResources>

3.JNDI+Tomcat配置數(shù)據(jù)源(局部配置)

1)簡單思路

  1. 非全局JNDI數(shù)據(jù)源是針對某一個Web項目配置的數(shù)據(jù)源拣技,具體的配置步驟如下:
    1、在tomcat服務器的lib目錄下加入數(shù)據(jù)庫連接的驅動jar包
    2耍目、針對具體的web項目映射虛擬目錄,然后在虛擬目錄映射的配置文件中配置JNDI數(shù)據(jù)源
  2. 還有一個更簡單的思路:
    就是將上述引用全局配置的地方改為和全局配置相同的那樣的配置,并將全局配置刪除徐绑。
    所以共有三種方法(conf/context.xml中配置的可能是全局的)
  3. 正常使用的話還是用全局配置吧邪驮。

2)配置過程及幾種方法:
配置模板和全局配置的相同。

  1. 方法一:修改server.xml中的context(對應全局配置步驟6)

     <Context docBase="JNDITest" path="/JNDITest" reloadable="true" source="org.eclipse.jst.jee.server:JNDITest">
         <Resource name="jdbc/test" 
                 auth="Container" 
                 type="javax.sql.DataSource" 
                 driverClassName="com.mysql.jdbc.Driver" 
                 url="jdbc:mysql://127.0.0.1/test" 
                 username="root" 
                 password="root" 
                 maxActive="20" 
                 maxIdle="10" 
                 maxWait="-1"/> 
     </Context>
    
  2. 方法二:在項目的META-INF下面建立context.xml文件(對應全局配置步驟7)傲茄,在里面配置上:

     <?xml version="1.0" encoding="UTF-8"?> 
     <Context> 
         <Resource name="jdbc/test" 
                 auth="Container" 
                 type="javax.sql.DataSource" 
                 driverClassName="com.mysql.jdbc.Driver" 
                 url="jdbc:mysql://127.0.0.1/test" 
                 username="root" 
                 password="root" 
                 maxActive="20" 
                 maxIdle="10" 
                 maxWait="-1"/> 
     </Context> 
    
  3. 方法三:配置conf/context.xml(對應步驟8)
    (這步極有可能是全局的配置):

     <Context>
         <WatchedResource>WEB-INF/web.xml</WatchedResource>
         <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
         <Resource name="jdbc/test" 
                 auth="Container" 
                 type="javax.sql.DataSource" 
                 driverClassName="com.mysql.jdbc.Driver" 
                 url="jdbc:mysql://127.0.0.1/test" 
                 username="root" 
                 password="root" 
                 maxActive="20" 
                 maxIdle="10" 
                 maxWait="-1"/> 
     <\Context>
    

將上述WatchedResource標簽中的路徑改為項目路徑就是局部配置了毅访。

  1. 測試類和全局配置的相同,我也不測試了盘榨。

4.關于配置JNDI的總結

  1. 全局配置的思路圖(虛線為非必須):


    00042JNDI學習1-09.jpg
  2. 局部配置就不畫了喻粹,差不多。

  3. 以上步驟就能配置數(shù)據(jù)源了草巡,至于獲取了DataSource怎么操作數(shù)據(jù)守呜,那就是javax.sql.DataSource的事情了,以后再學。


最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末山憨,一起剝皮案震驚了整個濱河市查乒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郁竟,老刑警劉巖玛迄,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棚亩,居然都是意外死亡蓖议,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門讥蟆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勒虾,“玉大人,你說我怎么就攤上這事瘸彤〈雍常” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長低零。 經(jīng)常有香客問我婆翔,道長,這世上最難降的妖魔是什么掏婶? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任啃奴,我火速辦了婚禮,結果婚禮上雄妥,老公的妹妹穿的比我還像新娘最蕾。我一直安慰自己,他們只是感情好老厌,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布瘟则。 她就那樣靜靜地躺著,像睡著了一般枝秤。 火紅的嫁衣襯著肌膚如雪醋拧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天淀弹,我揣著相機與錄音丹壕,去河邊找鬼。 笑死薇溃,一個胖子當著我的面吹牛菌赖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沐序,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼琉用,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了策幼?” 一聲冷哼從身側響起辕羽,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垄惧,沒想到半個月后刁愿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡到逊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年铣口,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片觉壶。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡脑题,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铜靶,到底是詐尸還是另有隱情叔遂,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站已艰,受9級特大地震影響痊末,放射性物質發(fā)生泄漏。R本人自食惡果不足惜哩掺,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一凿叠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嚼吞,春花似錦盒件、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至誊稚,卻和暖如春翔始,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背片吊。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留协屡,地道東北人俏脊。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像肤晓,于是被迫代替她去往敵國和親爷贫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容