使用JDBC建立數據庫連接的兩種方式:
1.在代碼中使用DriverManager獲得數據庫連接。這種方式效率低,并且其性能、可靠性和穩定性隨著用戶訪問量得增加逐漸下降。
2.使用配置數據源的方式連接數據庫,該方式其實質就是在上述方法的基礎上增加了數據庫連接池,這種方式效率高。
數據源連接池的方式連接數據庫與在代碼中使用DriverManager獲得數據庫連接存在如下差別:
1)數據源連接池的方式連接數據庫是在程序中,通過向一個JNDI(Java Naming and Directory Interface)服務器查詢,即調用Context接口的lookup()方法,來得到DataSource對象,然后調用DataSource對象的getConnection()方法建立連接
2)為了能重復利用數據庫連接對象,提高對請求的響應時間和服務器的性能,采用連接池技術.連接池技術預先建立多個數據庫連接對象,然后將連接對象保存到連接池中,當客戶請求到來時,從池中取出一個連接對象為客戶服務,當請求完成時,客戶程序調用close()方法,將連接對象放回池中.
3)在代碼中使用DriverManager獲得數據庫連接的方式中,客戶程序得到的連接對象是物理連接,調用連接對象的close()方法將關閉連接,而采用連接池技術,客戶程序得到的連接對象是連接池中物理連接的一個句柄,調用連接對象的close()方法,物理連接并沒有關閉,數據源的實現只是刪除了客戶程序中的連接對象和池中的連接對象之間的聯系.
為了測試方便可以在數據庫(這里以mysql 5為例)中建立一個USER表:
CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL, `password` varchar(50) DEFAULT NULL, `email` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`), );
導入數據庫的驅動的jar包到tomcat的lib目錄下(這里以mysql5為例,所用到的jar包為:mysql-connector-java-5.0.8-bin.jar)。
1.在代碼中使用DriverManager獲得數據庫連接。這種方式效率低,并且其性能、可靠性和穩定性隨著用戶訪問量得增加逐漸下降。
oracle數據庫連接的Java代碼如下:
import java.sql.Connection; import java.sql.DriverManager; /** * 獲取數據庫連接 */ public class DBConnection { /** Oracle數據庫連接URL*/ private final static String DB_URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; /** Oracle數據庫連接驅動*/ private final static String DB_DRIVER = "oracle.jdbc.driver.OracleDriver"; /** 數據庫用戶名*/ private final static String DB_USERNAME = "root"; /** 數據庫密碼*/ private final static String DB_PASSWORD = "admin"; /** * 獲取數據庫連接 * @return */ public Connection getConnection(){ /** 聲明Connection連接對象*/ Connection conn = null; try{ /** 使用Class.forName()方法自動創建這個驅動程序的實例且自動調用DriverManager來注冊它*/ Class.forName(DB_DRIVER); /** 通過DriverManager的getConnection()方法獲取數據庫連接*/ conn = DriverManager.getConnection(DB_URL,DB_USERNAME,DB_PASSWORD); }catch(Exception ex){ ex.printStackTrace(); } return conn; } /** * 關閉數據庫連接 * * @param connect */ public void closeConnection(Connection conn){ try{ if(conn!=null){ /** 判斷當前連接連接對象如果沒有被關閉就調用關閉方法*/ if(!conn.isClosed()){ conn.close(); } } }catch(Exception ex){ ex.printStackTrace(); } } }mysql數據庫連接的JSP代碼如下:
<%@page import="java.sql.*, com.mysql.jdbc.Driver"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <body> <% //com.mysql.jdbc.Driver Class.forName(Driver.class.getName()).newInstance(); String url = "jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF8"; String user = "root"; String password = "123"; Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "select * from user"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { out.print("<br />" + "====================" + "<br />"); out.print(rs.getLong("id") + " "); out.print(rs.getString("username") + " "); out.print(rs.getString("password") + " "); out.print(rs.getString("email") + " "); } %> </body> </html> 2.使用配置數據源的方式連接數據庫,該方式其實質就是在上述方法的基礎上增加了數據庫連接池,這種方式效率高。
1)mysql數據庫數據源連接池的JSP代碼如下:
<%@page import="java.sql.*, javax.naming.*, javax.sql.DataSource"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <body> <% Context initCtx = new InitialContext(); DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/demoDB"); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); String sql = "select * from user"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { out.print("<br />" + "====================" + "<br />"); out.print(rs.getLong("id") + " "); out.print(rs.getString("username") + " "); out.print(rs.getString("password") + " "); out.print(rs.getString("email") + " "); } %> </body> </html> 2) 添加如下代碼到tomcat的conf目錄下的server.xml中:
<Context> <Resource name="jdbc/demoDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/demo" username="root" password="123" maxActive="50" maxIdle="30" maxWait="10000" /> </Context>
3)在web工程目錄下的web.xml的根節點下配置如下內容:
<resource-ref> <description>mysqlDB Connection</description> <res-ref-name>jdbc/demoDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
完成上述步驟數據源的連接池配置已經完成,但是為了提高項目的可移植性,最好將上述第二步的內容放入到工程的META-INF目錄的context.xml中(這個文件需要自行建立):
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="jdbc/demoDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/demo" username="root" password="123" maxActive="50" maxIdle="30" maxWait="10000" /> </Context>
3.使用配置數據源的數據庫連接池時的數據庫操作工具類
代碼如下:
package db.utils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.naming.InitialContext; import javax.sql.DataSource; //import org.apache.log4j.Logger; /** * 數據庫操作輔助類 */ public class DbUtils { //private static Logger logger = Logger.getLogger("DbUtils"); /** * 該語句必須是一個 SQL INSERT、UPDATE 或 DELETE 語句 * @param sql * @param paramList:參數,與SQL語句中的占位符一一對應 * @return * @throws Exception */ public int execute(String sql, List<Object> paramList) throws Exception { if(sql == null || sql.trim().equals("")) { //logger.info("parameter is valid!"); } Connection conn = null; PreparedStatement pstmt = null; int result = 0; try { conn = getConnection(); pstmt = DbUtils.getPreparedStatement(conn, sql); setPreparedStatementParam(pstmt, paramList); if(pstmt == null) { return -1; } result = pstmt.executeUpdate(); } catch (Exception e) { //logger.info(e.getMessage()); throw new Exception(e); } finally { closeStatement(pstmt); closeConn(conn); } return result; } /** * 將查詢數據庫獲得的結果集轉換為Map對象 * @param sql:查詢語句 * @param paramList:參數 * @return */ public List<Map<String, Object>> getQueryList(String sql, List<Object> paramList) throws Exception { if(sql == null || sql.trim().equals("")) { //logger.info("parameter is valid!"); return null; } Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List<Map<String, Object>> queryList = null; try { conn = getConnection(); pstmt = DbUtils.getPreparedStatement(conn, sql); setPreparedStatementParam(pstmt, paramList); if(pstmt == null) { return null; } rs = getResultSet(pstmt); queryList = getQueryList(rs); } catch (RuntimeException e) { //logger.info(e.getMessage()); System.out.println("parameter is valid!"); throw new Exception(e); } finally { closeResultSet(rs); closeStatement(pstmt); closeConn(conn); } return queryList; } private void setPreparedStatementParam(PreparedStatement pstmt, List<Object> paramList) throws Exception { if(pstmt == null || paramList == null || paramList.isEmpty()) { return; } DateFormat df = DateFormat.getDateTimeInstance(); for (int i = 0; i < paramList.size(); i++) { if(paramList.get(i) instanceof Integer) { int paramValue = ((Integer)paramList.get(i)).intValue(); pstmt.setInt(i+1, paramValue); } else if(paramList.get(i) instanceof Float) { float paramValue = ((Float)paramList.get(i)).floatValue(); pstmt.setFloat(i+1, paramValue); } else if(paramList.get(i) instanceof Double) { double paramValue = ((Double)paramList.get(i)).doubleValue(); pstmt.setDouble(i+1, paramValue); } else if(paramList.get(i) instanceof Date) { pstmt.setString(i+1, df.format((Date)paramList.get(i))); } else if(paramList.get(i) instanceof Long) { long paramValue = ((Long)paramList.get(i)).longValue(); pstmt.setLong(i+1, paramValue); } else if(paramList.get(i) instanceof String) { pstmt.setString(i+1, (String)paramList.get(i)); } } return; } /** * 獲得數據庫連接 * @return * @throws Exception */ private Connection getConnection() throws Exception { InitialContext cxt = new InitialContext(); DataSource ds = (DataSource) cxt.lookup(jndiName); if ( ds == null ) { throw new Exception("Data source not found!"); } return ds.getConnection(); } private static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception { if(conn == null || sql == null || sql.trim().equals("")) { return null; } PreparedStatement pstmt = conn.prepareStatement(sql.trim()); return pstmt; } /** * 獲得數據庫查詢結果集 * @param pstmt * @return * @throws Exception */ private ResultSet getResultSet(PreparedStatement pstmt) throws Exception { if(pstmt == null) { return null; } ResultSet rs = pstmt.executeQuery(); return rs; } /** * @param rs * @return * @throws Exception */ private List<Map<String, Object>> getQueryList(ResultSet rs) throws Exception { if(rs == null) { return null; } ResultSetMetaData rsMetaData = rs.getMetaData(); int columnCount = rsMetaData.getColumnCount(); List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(); while (rs.next()) { Map<String, Object> dataMap = new HashMap<String, Object>(); for (int i = 0; i < columnCount; i++) { dataMap.put(rsMetaData.getColumnName(i+1), rs.getObject(i+1)); } dataList.add(dataMap); } return dataList; } /** * 關閉數據庫連接 * @param conn */ private void closeConn(Connection conn) { if(conn == null) { return; } try { conn.close(); } catch (SQLException e) { //logger.info(e.getMessage()); } } /** * 關閉 * @param stmt */ private void closeStatement(Statement stmt) { if(stmt == null) { return; } try { stmt.close(); } catch (SQLException e) { //logger.info(e.getMessage()); } } /** * 關閉 * @param rs */ private void closeResultSet(ResultSet rs) { if(rs == null) { return; } try { rs.close(); } catch (SQLException e) { //logger.info(e.getMessage()); } } private String jndiName = "java:/comp/env/jdbc/demoDB"; public void setJndiName(String jndiName) { this.jndiName = jndiName; } }總結:使用配置數據源的方式連接數據庫,這種方式效率高且性能穩定,推薦使用。
查看更多Java的語法,大家可以關注:《Thinking in Java 中文手冊》、《JDK 1.7 參考手冊官方英文版》、《JDK 1.6 API java 中文參考手冊》、《JDK 1.5 API java 中文參考手冊》,也希望大家多多支持武林網。
新聞熱點
疑難解答