[关闭]
@caos 2014-09-02T05:58:10.000000Z 字数 6152 阅读 2057

JDBC DataSource

编程



简介

DataSource是JDBC规范的一部分, 它被视为一个通用的数据库连接工厂。通过使用DataSource, Container或Framework可以将连接池以及事务管理的细节从应用代码中分离出来。 作为一个开发人员,在开发和测试产品的过程中,你可能需要知道连接数据库的细节。 但在产品实施时,你不需要知道这些细节。通常数据库管理员会帮你设置好数据源。

也就是说,DataSource接口能够将应用程序和数据库解耦,从而使应用程序能够方便的从多种不同的数据库中切换,当然,这也离不开各数据库提供商对JDBC结构标准实现的努力。
JDBC
JDBC DataSource 接口由 javax.sql包中,而且接口中声明了两个需要实现的方法:

使用指南

数据库 Oracle MySQL
接口 oracle.jdbc.pool.OracleDataSource com.mysql.jdbc.jdbc2.optional.MysqlDataSource

创建一个简单的JDBC项目引入Jar包
此处输入图片的描述

创建数据库表结构

在Oracle和MySQL中创建表并初始化数据

MySQLSetup.sql

  1. --Create Employee table
  2. CREATE TABLE `Employee` (
  3. `empId` int(10) unsigned NOT NULL,
  4. `name` varchar(10) DEFAULT NULL,
  5. PRIMARY KEY (`empId`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  7. -- insert some sample data
  8. INSERT INTO `Employee` (`empId`, `name`)
  9. VALUES
  10. (1, 'Pankaj'),
  11. (2, 'David');
  12. commit;

OracleSetup.sql

  1. CREATE TABLE "EMPLOYEE"
  2. (
  3. "EMPID" NUMBER NOT NULL ENABLE,
  4. "NAME" VARCHAR2(10 BYTE) DEFAULT NULL,
  5. PRIMARY KEY ("EMPID")
  6. );
  7. Insert into EMPLOYEE (EMPID,NAME) values (10,'Pankaj');
  8. Insert into EMPLOYEE (EMPID,NAME) values (5,'Kumar');
  9. Insert into EMPLOYEE (EMPID,NAME) values (1,'Pankaj');
  10. commit;

数据库连接配置

db.properties

  1. #mysql DB properties
  2. MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver
  3. MYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDB
  4. MYSQL_DB_USERNAME=pankaj
  5. MYSQL_DB_PASSWORD=pankaj123
  6. #Oracle DB Properties
  7. ORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
  8. ORACLE_DB_URL=jdbc:oracle:thin:@localhost:1521:orcl
  9. ORACLE_DB_USERNAME=hr
  10. ORACLE_DB_PASSWORD=oracle

示例代码

MyDataSourceFactory.java

  1. package com.journaldev.jdbc.datasource;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.sql.SQLException;
  5. import java.util.Properties;
  6. import javax.sql.DataSource;
  7. import oracle.jdbc.pool.OracleDataSource;
  8. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  9. public class MyDataSourceFactory {
  10. public static DataSource getMySQLDataSource() {
  11. Properties props = new Properties();
  12. FileInputStream fis = null;
  13. MysqlDataSource mysqlDS = null;
  14. try {
  15. fis = new FileInputStream("db.properties");
  16. props.load(fis);
  17. mysqlDS = new MysqlDataSource();
  18. mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));
  19. mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));
  20. mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
  21. } catch (IOException e) {
  22. e.printStackTrace();
  23. }
  24. return mysqlDS;
  25. }
  26. public static DataSource getOracleDataSource(){
  27. Properties props = new Properties();
  28. FileInputStream fis = null;
  29. OracleDataSource oracleDS = null;
  30. try {
  31. fis = new FileInputStream("db.properties");
  32. props.load(fis);
  33. oracleDS = new OracleDataSource();
  34. oracleDS.setURL(props.getProperty("ORACLE_DB_URL"));
  35. oracleDS.setUser(props.getProperty("ORACLE_DB_USERNAME"));
  36. oracleDS.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));
  37. } catch (IOException e) {
  38. e.printStackTrace();
  39. } catch (SQLException e) {
  40. e.printStackTrace();
  41. }
  42. return oracleDS;
  43. }
  44. }

测试代码
DataSourceTest.java

  1. package com.journaldev.jdbc.datasource;
  2. import java.sql.Connection;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.sql.Statement;
  6. import javax.sql.DataSource;
  7. public class DataSourceTest {
  8. public static void main(String[] args) {
  9. testDataSource("mysql");
  10. System.out.println("**********");
  11. testDataSource("oracle");
  12. }
  13. private static void testDataSource(String dbType) {
  14. DataSource ds = null;
  15. if("mysql".equals(dbType)){
  16. ds = MyDataSourceFactory.getMySQLDataSource();
  17. }else if("oracle".equals(dbType)){
  18. ds = MyDataSourceFactory.getOracleDataSource();
  19. }else{
  20. System.out.println("invalid db type");
  21. return;
  22. }
  23. Connection con = null;
  24. Statement stmt = null;
  25. ResultSet rs = null;
  26. try {
  27. con = ds.getConnection();
  28. stmt = con.createStatement();
  29. rs = stmt.executeQuery("select empid, name from Employee");
  30. while(rs.next()){
  31. System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));
  32. }
  33. } catch (SQLException e) {
  34. e.printStackTrace();
  35. }finally{
  36. try {
  37. if(rs != null) rs.close();
  38. if(stmt != null) stmt.close();
  39. if(con != null) con.close();
  40. } catch (SQLException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }
  45. }

测试结果

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

Apache Commons DBCP 示例

上图中项目结构中我们看到了DBCP的Jar包,使用DBCP能够更好的解耦应用程序与数据库的关联,下面给出使用DBCP的做法:

示例代码
DBCPDataSourceFactory.java

  1. package com.journaldev.jdbc.datasource;
  2. import java.io.FileInputStream;
  3. import java.io.IOException;
  4. import java.util.Properties;
  5. import javax.sql.DataSource;
  6. import org.apache.commons.dbcp.BasicDataSource;
  7. public class DBCPDataSourceFactory {
  8. public static DataSource getDataSource(String dbType){
  9. Properties props = new Properties();
  10. FileInputStream fis = null;
  11. BasicDataSource ds = new BasicDataSource();
  12. try {
  13. fis = new FileInputStream("db.properties");
  14. props.load(fis);
  15. }catch(IOException e){
  16. e.printStackTrace();
  17. return null;
  18. }
  19. if("mysql".equals(dbType)){
  20. ds.setDriverClassName(props.getProperty("MYSQL_DB_DRIVER_CLASS"));
  21. ds.setUrl(props.getProperty("MYSQL_DB_URL"));
  22. ds.setUsername(props.getProperty("MYSQL_DB_USERNAME"));
  23. ds.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
  24. }else if("oracle".equals(dbType)){
  25. ds.setDriverClassName(props.getProperty("ORACLE_DB_DRIVER_CLASS"));
  26. ds.setUrl(props.getProperty("ORACLE_DB_URL"));
  27. ds.setUsername(props.getProperty("ORACLE_DB_USERNAME"));
  28. ds.setPassword(props.getProperty("ORACLE_DB_PASSWORD"));
  29. }else{
  30. return null;
  31. }
  32. return ds;
  33. }
  34. }

测试代码
ApacheCommonsDBCPTest.java

  1. package com.journaldev.jdbc.datasource;
  2. import java.sql.Connection;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.sql.Statement;
  6. import javax.sql.DataSource;
  7. public class ApacheCommonsDBCPTest {
  8. public static void main(String[] args) {
  9. testDBCPDataSource("mysql");
  10. System.out.println("**********");
  11. testDBCPDataSource("oracle");
  12. }
  13. private static void testDBCPDataSource(String dbType) {
  14. DataSource ds = DBCPDataSourceFactory.getDataSource(dbType);
  15. Connection con = null;
  16. Statement stmt = null;
  17. ResultSet rs = null;
  18. try {
  19. con = ds.getConnection();
  20. stmt = con.createStatement();
  21. rs = stmt.executeQuery("select empid, name from Employee");
  22. while(rs.next()){
  23. System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name"));
  24. }
  25. } catch (SQLException e) {
  26. e.printStackTrace();
  27. }finally{
  28. try {
  29. if(rs != null) rs.close();
  30. if(stmt != null) stmt.close();
  31. if(con != null) con.close();
  32. } catch (SQLException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  37. }

测试结果与第一次相同

总结

DataSource的获取方式,也可以使用主流容器(Tomcat/JBoss)中提供的JNDI(Java Naming and Directory Interface,Java命名和目录接口),这些都是为了满足应用程序能够更灵活的使用数据库连接而产生的,本文大部分内容摘录自JDBC DataSource Example – Oracle, MySQL and Apache DBCP Tutorial英文好的童鞋可以阅读原版。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注