一、關於
JNDI(Java Naming and Directory Interface,Java命名和目錄接口),J2EE的標準之一,J2EE容器都必須要提供的一個服務
JNDI的出現,讓數據庫連接代碼交給容器管理,比如Tomcat、JBOSS等容器,使開發者不用關心數據庫的配置和驅動等是什麼
二、配置
- 1、配置參數的說明
<Resource
|- name:名稱,可任意,但程序中最終要查找的就是此名稱
|- auth:由容器進行授權及管理,指用戶名和密碼是否可以在容器上生效
|- type:此名稱所代表的類型,現在爲javax.sql.DataSource
|- maxActive:表示一個數據庫在此服務器上所能打開的最大連接數
|- maxIdle:表示一個數據庫在此服務器上維持的最小連接數
|- maxWait:最大等待時間
|- username:數據庫連接的用戶名
|- password:數據庫連接的密碼
|- driverClassName:數據庫連接的驅動
|- url:數據庫連接的地址
/>
- 2、全局配置
在tomcat的conf/context.xml配置文件中加入
<Context>
<Resource name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb"
username="root" password="root"
maxActive="20" maxIdle="10"
maxWait="10000"/>
</Context>
3、局部配置
在項目的 META-INF 下面新建context.xml並加入
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb"
username="root"
password="root"
maxActive="20"
maxIdle="10"
maxWait="10000" />
</Context>
- 4、常見數據庫配置
<!--oracle數據庫的jndi數據源,這裏的lead爲service名。-->
<Resource
name="jndiOracle"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="lead_oams"
password="pwd123"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@192.168.2.220:1521:leadtest" />
<!--配置MySQL數據庫的JNDI數據源-->
<Resource
name="jndiMysql"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.2.221:3306/leadtest?useUnicode=true&characterEncoding=utf-8" />
<!--配置SQLServer數據庫的JNDI數據源-->
<Resource
name="jndiSqlserver"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="sa"
password="pwd123"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://192.168.2.223:1433;DatabaseName=leadtest" />
5、測試
在 jsp/servlet 中調用加載 jndi 方式
注意:不可以直接用main方法測試,必須通過啓動容器調用
Connection conn = null;
try {
// 初始化查找命名空間
Context ctx = new InitialContext();
// InitialContext ctx = new InitialContext();亦可
// 找到DataSource,對名稱進行定位java:comp/env是必須加的,後面跟你的DataSource名
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jndiMySQL");
// 取出連接
conn = ds.getConnection();
String sql = "select *from test";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println("id:" + rs.getInt("id") + ",name:" + rs.getString("name") + "");
}
out.println(conn);
out.println(conn.isClosed());
out.println("</br>");
System.out.println("connection pool connected !!");
} catch (NamingException e) {
System.out.println(e.getMessage());
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 注意不是關閉,是放回連接池.
conn.close();
}
三、Spring和SpringBoot
- 1、Spring配置
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/mysql" />
</bean>
- 2、SpringBoot配置
- 1)、外置Tomcat
在Tomcat已經配置context.xml後,在項目的application.properties中配置如下即可
spring.datasource.jndi-name=java:comp/env/jndiMySQL
- 2)、內嵌Tomcat
添加application.properties中的spring.datasource.jndi-name屬性,值與下一步中指定的name相同
添加ServletWebServerFactory的配置(舊一些的版本可能是TomcatEmbeddedServletContainerFactory)
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatWebServer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName("jndiMySQL");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
resource.setProperty("url", "jdbc:mysql://localhost:3306/testdb");
resource.setProperty("username", "root");
resource.setProperty("password","root");
context.getNamingResources().addResource(resource);
super.postProcessContext(context);
}
};
return tomcat;
}