JNDI學習總結(二):tomcat配置全域性和私有JNDI資料來源的幾種方式
下面介紹幾種常用的JNDI資料來源配置方式
環境:IDEA+tomcat7
全域性:
1. 修改tomcat的context.xml的<context>標籤
在<context>標籤內加入如下內容(以配置mysql資料來源為例):
<Resource name="jdbc/mysql" //名稱可以自定義 auth="Container" type="javax.sql.DataSource" username="" //改成自己的資料庫使用者名稱和密碼 password="" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/資料庫名" />
配置好後重啟tomcat。 可以選擇在專案中引入mysql驅動,或者直接將驅動jar包扔進tomcat安裝目錄中的lib資料夾下。
最後在專案的web.xml中配置這段程式碼(其實可有可無,但最好加上,後文會解釋原因):
<resource-ref> <res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同 <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref>
使用下面這段程式碼測試(注意,不能在main中測試,否則會報錯。在jsp頁面中或者servlet中可以,需要web環境):
Context initial = new InitialContext(); //得到上下文引用
DataSource datasource = (DataSource) initial.lookup("java:comp/env/jdbc/mysql");
2. 修改tomcat的server.xml的<GlobalNamingResources>
在<GlobalNamingResources>標籤中加入下面程式碼:
<Resource name="globalResourceTest" auth="Container" type="javax.sql.DataSource" username="" password="" maxIdle="30" maxWait="10000" maxActive="100" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/資料庫名" />
開啟$tomcat_home\conf\context.xml, 在<context>標籤中加入下面程式碼:
<ResourceLink name="jdbc/mysql" global="globalResource" type="javax.sql.DataSource"/>
注意:<Resource>中的name屬性要和<ResourceLink>中的global屬性對應才能引用到,<ResourceLink>中的name才是資料來源的名字,要通過這個名字找到資料來源。
同樣在web.xml中加入下面程式碼:
<resource-ref>
<res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
私有:
1. 修改tomcat的server.xml的<Host>
找到<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"></Host>,在其中加入以下內容:
<Context path="/xxxx" docBase="專案的絕對路徑" reloadable="true">
<Resource name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource"
username=""
password=""
maxIdle="30"
maxWait="10000"
maxActive="100"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/資料庫名"/>
</Context>
注意:<context>的path屬性必須和專案訪問路徑一致且開頭必須加“/”。 什麼叫專案訪問路徑?如果你用eclipse+tomcat啟動專案,那path屬性為“/你的專案名”。 若你使用IDEA+tomcat啟動專案,這裡的path必須等於下圖圈起來的地方:
, 不然獲取不到資料來源。
若在IDE中啟動tomcat,其實docBase這個屬性設不設定都可以,設定了亂填也不影響。但為什麼我還是寫上了,因為當你使用cmd啟動tomcat時,若不設定該屬性啟動時會丟擲“NamingException: No naming context bound to this class loader”。所以必須將docBase設定為專案的絕對路徑。
然後在web.xml中加入:
<resource-ref>
<res-ref-name>jdbc/mysql</res-ref-name> //和上面的name屬性值相同
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
2. 在專案的META-INF資料夾下建立context.xml
內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
<Resource name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource"
username=""
password=""
maxIdle="30"
maxWait="10000"
maxActive="100"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/專案名"/>
</Context>
同時存在多種配置方式且同名,會獲取哪一個:
首先,全域性配置大於私有配置,也就是說若全域性和私有同時存在,優先獲取全域性配置的資料來源
全域性:
在context.xml中,<Resource>和<ResourceLink>(引用server.xml中<GlobalNamingResources> )同時存在,哪個標籤在前獲取到哪一個,即按順序獲取。
私有:
1. 若只存在<Host>標籤中的配置,不存在META-INF中的context.xml,則優先獲取<Host>中配置的第一個資料來源。
2. 若兩種私有配置方式都存在,會獲取META-INF中context.xml配置的資料來源。
為什麼web.xml中的配置可有可無,卻要加上呢?
詳情見tomcat的docs:jndi-resources-howto.html
其中有這麼一句話:
If a resource has been defined in a <Context> element it is not necessary for that resource to be defined in /WEB-INF/web.xml. However, it is recommended to keep the entry in /WEB-INF/web.xml to document the resource requirements for the web application.
也就是說,在web.xml加入的那段程式碼僅起到說明作用,說明這個Web應用引用了哪些資源!詳情請翻閱文件