@caos
2014-09-02T05:58:10.000000Z
字数 6152
阅读 2419
编程
DataSource是JDBC规范的一部分, 它被视为一个通用的数据库连接工厂。通过使用DataSource, Container或Framework可以将连接池以及事务管理的细节从应用代码中分离出来。 作为一个开发人员,在开发和测试产品的过程中,你可能需要知道连接数据库的细节。 但在产品实施时,你不需要知道这些细节。通常数据库管理员会帮你设置好数据源。
也就是说,DataSource接口能够将应用程序和数据库解耦,从而使应用程序能够方便的从多种不同的数据库中切换,当然,这也离不开各数据库提供商对JDBC结构标准实现的努力。
JDBC DataSource 接口由 javax.sql包中,而且接口中声明了两个需要实现的方法:
| 数据库 | Oracle | MySQL |
|---|---|---|
| 接口 | oracle.jdbc.pool.OracleDataSource | com.mysql.jdbc.jdbc2.optional.MysqlDataSource |
创建一个简单的JDBC项目引入Jar包
在Oracle和MySQL中创建表并初始化数据
MySQLSetup.sql
--Create Employee tableCREATE TABLE `Employee` (`empId` int(10) unsigned NOT NULL,`name` varchar(10) DEFAULT NULL,PRIMARY KEY (`empId`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- insert some sample dataINSERT INTO `Employee` (`empId`, `name`)VALUES(1, 'Pankaj'),(2, 'David');commit;
OracleSetup.sql
CREATE TABLE "EMPLOYEE"("EMPID" NUMBER NOT NULL ENABLE,"NAME" VARCHAR2(10 BYTE) DEFAULT NULL,PRIMARY KEY ("EMPID"));Insert into EMPLOYEE (EMPID,NAME) values (10,'Pankaj');Insert into EMPLOYEE (EMPID,NAME) values (5,'Kumar');Insert into EMPLOYEE (EMPID,NAME) values (1,'Pankaj');commit;
db.properties
#mysql DB propertiesMYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.DriverMYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDBMYSQL_DB_USERNAME=pankajMYSQL_DB_PASSWORD=pankaj123#Oracle DB PropertiesORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriverORACLE_DB_URL=jdbc:oracle:thin:@localhost:1521:orclORACLE_DB_USERNAME=hrORACLE_DB_PASSWORD=oracle
MyDataSourceFactory.java
package com.journaldev.jdbc.datasource;import java.io.FileInputStream;import java.io.IOException;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;import oracle.jdbc.pool.OracleDataSource;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;public class MyDataSourceFactory {public static DataSource getMySQLDataSource() {Properties props = new Properties();FileInputStream fis = null;MysqlDataSource mysqlDS = null;try {fis = new FileInputStream("db.properties");props.load(fis);mysqlDS = new MysqlDataSource();mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));} catch (IOException e) {e.printStackTrace();}return mysqlDS;}public static DataSource getOracleDataSource(){Properties props = new Properties();FileInputStream fis = null;OracleDataSource oracleDS = null;try {fis = new FileInputStream("db.properties");props.load(fis);oracleDS = new OracleDataSource();oracleDS.setURL(props.getProperty("ORACLE_DB_URL"));oracleDS.setUser(props.getProperty("ORACLE_DB_USERNAME"));oracleDS.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));} catch (IOException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return oracleDS;}}
测试代码
DataSourceTest.java
package com.journaldev.jdbc.datasource;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;public class DataSourceTest {public static void main(String[] args) {testDataSource("mysql");System.out.println("**********");testDataSource("oracle");}private static void testDataSource(String dbType) {DataSource ds = null;if("mysql".equals(dbType)){ds = MyDataSourceFactory.getMySQLDataSource();}else if("oracle".equals(dbType)){ds = MyDataSourceFactory.getOracleDataSource();}else{System.out.println("invalid db type");return;}Connection con = null;Statement stmt = null;ResultSet rs = null;try {con = ds.getConnection();stmt = con.createStatement();rs = stmt.executeQuery("select empid, name from Employee");while(rs.next()){System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));}} catch (SQLException e) {e.printStackTrace();}finally{try {if(rs != null) rs.close();if(stmt != null) stmt.close();if(con != null) con.close();} catch (SQLException e) {e.printStackTrace();}}}}
测试结果
Employee ID=1, Name=Pankaj
Employee ID=2, Name=David
**********
Employee ID=10, Name=Pankaj
Employee ID=5, Name=Kumar
Employee ID=1, Name=Pankaj
上图中项目结构中我们看到了DBCP的Jar包,使用DBCP能够更好的解耦应用程序与数据库的关联,下面给出使用DBCP的做法:
示例代码
DBCPDataSourceFactory.java
package com.journaldev.jdbc.datasource;import java.io.FileInputStream;import java.io.IOException;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSource;public class DBCPDataSourceFactory {public static DataSource getDataSource(String dbType){Properties props = new Properties();FileInputStream fis = null;BasicDataSource ds = new BasicDataSource();try {fis = new FileInputStream("db.properties");props.load(fis);}catch(IOException e){e.printStackTrace();return null;}if("mysql".equals(dbType)){ds.setDriverClassName(props.getProperty("MYSQL_DB_DRIVER_CLASS"));ds.setUrl(props.getProperty("MYSQL_DB_URL"));ds.setUsername(props.getProperty("MYSQL_DB_USERNAME"));ds.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));}else if("oracle".equals(dbType)){ds.setDriverClassName(props.getProperty("ORACLE_DB_DRIVER_CLASS"));ds.setUrl(props.getProperty("ORACLE_DB_URL"));ds.setUsername(props.getProperty("ORACLE_DB_USERNAME"));ds.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));}else{return null;}return ds;}}
测试代码
ApacheCommonsDBCPTest.java
package com.journaldev.jdbc.datasource;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;public class ApacheCommonsDBCPTest {public static void main(String[] args) {testDBCPDataSource("mysql");System.out.println("**********");testDBCPDataSource("oracle");}private static void testDBCPDataSource(String dbType) {DataSource ds = DBCPDataSourceFactory.getDataSource(dbType);Connection con = null;Statement stmt = null;ResultSet rs = null;try {con = ds.getConnection();stmt = con.createStatement();rs = stmt.executeQuery("select empid, name from Employee");while(rs.next()){System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));}} catch (SQLException e) {e.printStackTrace();}finally{try {if(rs != null) rs.close();if(stmt != null) stmt.close();if(con != null) con.close();} catch (SQLException e) {e.printStackTrace();}}}}
测试结果与第一次相同
DataSource的获取方式,也可以使用主流容器(Tomcat/JBoss)中提供的JNDI(Java Naming and Directory Interface,Java命名和目录接口),这些都是为了满足应用程序能够更灵活的使用数据库连接而产生的,本文大部分内容摘录自JDBC DataSource Example – Oracle, MySQL and Apache DBCP Tutorial英文好的童鞋可以阅读原版。