傳統(tǒng)的jdbc連接數(shù)據(jù)庫方式如下:
我們需要幾個步驟:注冊 JDBC 驅(qū)動程序注冊( Class.forName(DRIVER_NAME) ),通過DriverManager獲取物理連接拦宣。
一次數(shù)據(jù)庫訪問對應(yīng)一個物理連接,每次操作數(shù)據(jù)庫都要打開蜘欲、關(guān)閉該物理連接忆嗜。
添加mysql驅(qū)動包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
jdbc操作類如下:
public class DBUtil {
private static Logger logger = LoggerFactory.getLogger(DBUtil.class);
private static String DRIVER_NAME = null;
private static String URL = null;
private static String USER_NAME = null;
private static String PWD = null;
private static Properties properties = new Properties();
static {
try {
properties.load(DBUtil.class.getResourceAsStream("/jdbc.properties"));
} catch (IOException e) {
logger.error("系統(tǒng)加載jdbc.properties配置異常");
}
DRIVER_NAME = properties.getProperty("jdbc.driver");
URL = properties.getProperty("jdbc.url");
USER_NAME = properties.getProperty("jdbc.username");
PWD = properties.getProperty("jdbc.password");
try {
Class.forName(DRIVER_NAME);
} catch (ClassNotFoundException e) {
logger.error("加載數(shù)據(jù)庫驅(qū)動異常");
}
}
public static Connection getConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(URL, USER_NAME, PWD);
} catch (SQLException e) {
logger.error("創(chuàng)建數(shù)據(jù)庫鏈接異常", e);
}
return connection;
}
public static void close(Connection connection) {
if (connection != null) {
try {
if (!connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
logger.error("連接關(guān)閉異常", e);
}
}
}
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
if (resultSet != null) {
try {
if (!resultSet.isClosed()) {
resultSet.close();
}
} catch (SQLException e) {
logger.error("結(jié)果集關(guān)閉異常", e);
}
}
if (statement != null) {
try {
if (!statement.isClosed()) {
statement.close();
}
} catch (SQLException e) {
logger.error("語句關(guān)閉異常", e);
}
}
close(connection);
}
}
我們采用DBCP(DataBase connection pool),數(shù)據(jù)庫連接池。DBCP是 apache 上的一個 java 連接池項目,也是 tomcat 使用的連接池組件。
添加dbcp依賴豪筝,對應(yīng)commons-pool和commons-dbcp兩個包
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
使用連接池,代碼如下:
public class DBCPUtil {
private static Logger logger = LoggerFactory.getLogger(DBUtil.class);
private static Properties properties = new Properties();
private static DataSource dataSource;
static {
try {
properties.load(DBCPUtil.class.getResourceAsStream("/jdbc.properties"));
} catch (IOException e) {
logger.error("系統(tǒng)加載jdbc.properties配置異常");
}
try {
dataSource= BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
logger.error("加載數(shù)據(jù)庫驅(qū)動異常");
}
// dataSource=new BasicDataSource();
// dataSource.setUsername("root");
// dataSource.setPassword("root");
// dataSource.setUrl("jdbc:mysql://localhost:3306/web");
// dataSource.setDriverClassName("com.mysql.jdbc.Driver");
}
public static Connection getConnection() {
Connection connection = null;
try {
connection=dataSource.getConnection();
connection.setAutoCommit(true);
} catch (SQLException e) {
logger.error("創(chuàng)建數(shù)據(jù)庫鏈接異常", e);
}
return connection;
}
public static void close(Connection connection) {
if (connection != null) {
try {
if (!connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
logger.error("連接關(guān)閉異常", e);
}
}
}
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
if (resultSet != null) {
try {
if (!resultSet.isClosed()) {
resultSet.close();
}
} catch (SQLException e) {
logger.error("結(jié)果集關(guān)閉異常", e);
}
}
if (statement != null) {
try {
if (!statement.isClosed()) {
statement.close();
}
} catch (SQLException e) {
logger.error("語句關(guān)閉異常", e);
}
}
close(connection);
}
}
注意properties的配置 和jdbc是不同的摘能。 我因為還用原來的配置壤蚜,報錯空指針,Cannot create JDBC driver of class '' for connect URL 'null' 徊哑,找了半天Bug
#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/web?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
#jdbc.username=root
#jdbc.password=root
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root
JDBC的數(shù)據(jù)庫連接池使用javax.sql.DataSource來表示袜刷,DataSource只是一個接口,該接口通常由商用服務(wù)器等提供實現(xiàn)莺丑,也有一些開源組織提供實現(xiàn)(DBCP著蟹、C3P0)。
DataSource通常被稱為數(shù)據(jù)源梢莽,它包含連接池和連接池管理兩個部分萧豆,但習(xí)慣上也經(jīng)常把DataSource稱為連接池。
數(shù)據(jù)源連接池的方式連接數(shù)據(jù)庫是在程序中,通過向一個JNDI(Java Naming and Directory Interface)服務(wù)器查詢,即調(diào)用Context接口的lookup()方法,來得到DataSource對象,然后調(diào)用DataSource對象的getConnection()方法建立連接
在代碼中使用DriverManager獲得數(shù)據(jù)庫連接的方式中,客戶程序得到的連接對象是物理連接,調(diào)用連接對象的close()方法將關(guān)閉連接,而采用連接池技術(shù),客戶程序得到的連接對象是連接池中物理連接的一個句柄,調(diào)用連接對象的close()方法,物理連接并沒有關(guān)閉,數(shù)據(jù)源的實現(xiàn)只是刪除了客戶程序中的連接對象和池中的連接對象之間的聯(lián)系.
關(guān)于jndi昏名,可以參考:http://benweizhu.github.io/blog/2014/07/07/learning-jdbc-with-jndi/