JDBC(Java DataBase Connectivity)時用於運行SQL的解決方案,開發人員使用JDBC的標准接口,數據庫廠商則對接口進行實現,這樣開發人員就可以無需接觸底層數據庫驅動程序的差異性。
廠商在實現JDBC驅動程序時,依方式可將驅動程序分為四種類型:
JDBC-ODBC Bridge Driver以下編寫一個簡單的JavaBean來測試可否連接數據庫:
package club.chuxing;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DbBean {
private String url;
private String username;
private String password;
public DbBean(){
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
Logger.getLogger(DbBean.class.getName()).log(Level.SEVERE, null, e);
}
}
public boolean isConnectedOk() {
boolean ok = false;
Connection conn = null;
try {
conn = DriverManager.getConnection(url, username, password);
if (!conn.isClosed()) {
ok = true;
}
} catch (SQLException e) {
Logger.getLogger(DbBean.class.getName()).log(Level.SEVERE, null, e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
Logger.getLogger(DbBean.class.getName())
.log(Level.SEVERE, null, e);
}
}
}
return ok;
}
public void setPassword(String password) {
this.password = password;
}
public void setUrl(String url) {
this.url = url;
}
public void setName(String username) {
this.username = username;
}
}
之後就可以通過調用isConnectedOK()方法來看看是否可以連接成功。例如,可以寫個簡單的JSP網頁,代碼如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
連接成功
<%-- 連接成功 --%>
連接失敗
在Java EE中的環境中,將取得連接等與數據庫來源相關的行為規范在javax.sql.DataSource
接口,實際如何取得Connection則由實現接口的對象來負責。
為了讓應用程序在需要取得某些與系統相關的資源對象時,能與實際的系統配置、實體機器位置、環境架構等無關,在Java應用程序中可以通過JNDI(Java Naming Directory Interface)來取得所需的資源對象。可用如下方式取得DataSource實例:
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/test");
} catch(NamingException ex) {
//other process
}
在創建Context對象的過程中會收集環境的相關數據,之後根據JNDI名稱jdbc/demo向JNDI服務器查找DataSource實例並返回。在這個程序片段中,不會知道實際的資源配置、實體機器位置、環境架構等信息,應用程序不會與這些相依。
之前的DbBean類可以改為如下編寫方式:
package club.chuxing;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DatabaseBean {
private DataSource dataSource;
public DatabaseBean(){
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/test");
} catch(NamingException ex) {
Logger.getLogger(DatabaseBean.class.getName())
.log(Level.SEVERE, null, ex);
}
}
public boolean isConnectedOK(){
boolean ok = false;
Connection conn = null;
try {
conn = dataSource.getConnection();
if (!conn.isClosed()) {
ok = true;
}
} catch(SQLException ex) {
Logger.getLogger(DatabaseBean.class.getName())
.log(Level.SEVERE, null, ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch(SQLException ex) {
Logger.getLogger(DatabaseBean.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
return ok;
}
}
以上代碼並不含有驅動程序、數據庫用戶名、密碼等信息,這些都由數據庫管理人員或服務器管理人員負責設置,我們唯一需要知道的就是jdbc/test這個JNDI名稱,並且告訴web容器,也就是要在web.xml中設置。
web.xml:
jdbc/demo
javax.sql.DataSource
Container
Shareable
在web.xml中設置的目的,就是讓web容器提供JNDI查找時所需的相關環境信息,這樣創建Context對象時就不用設置一大堆參數了。接著可以編寫一個簡單的JSP來使用DatabaseBean。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
連接成功
<%-- 連接成功 --%>
連接失敗
對於Java開發人員來說,它的工作已經完成了。現在假設你是服務器管理員,職責就是設置JNDI相關資源,但設置的方式並非標准的一部分,而是依應用程序服務器而有所不同。假設應用程序將部署在Tomcat6上,則可以要求web應用程序在封裝為war文件時,必須在META-INF文件夾中包括一個context.xml文件。例如:
name屬性用來設置JNDI名稱,username與password用來設置數據庫用戶名和密碼,driverClassName用來設置驅動程序類名稱,url用來設置JDBC URL。其他屬性則是與DBCP(Database Connection Pool)有關的,這是內置在Tomcat中的連接池機制。
當應用程序部署後,Tomcat會根據META-INF中context.xml的設置,尋找指定的驅動程序,所以必須將驅動程序的JAR文件放置在Tomcat的lib目錄中,接著Tomcat就會為JNDI名稱jdbc/demo設置相關的資源。
使用root來操作數據庫是不安全的,root賬號用於操作數據庫的完整權限,應用設置具有適當權限的用戶來操作數據庫。