分享好友 数据库首页 频道列表

JDBC DataSource Example – Oracle, MySQL and Apache DBCP Tutorial

数据库其他  2023-02-09 22:460

We have already seen that JDBC DriverManager can be used to get relational database connections. But when it comes to actual programming, we want more than just connections.

Most of the times we are looking for loose coupling for connectivity so that we can switch databases easily, connection pooling for transaction management and distributed systems support. JDBC DataSource is the preferred approach if you are looking for any of these features in your application. JDBC DataSource interface is present in javax.sql package and it only declare two overloaded methods getConnection() andgetConnection(String str1,String str2).

It is the responsibility of different Database vendors to provide different kinds of implementation of DataSource interface. For example MySQL JDBC Driver provides basic implementation of DataSource interface with com.mysql.jdbc.jdbc2.optional.MysqlDataSource class and Oracle database driver implements it with oracle.jdbc.pool.OracleDataSource class.

These implementation classes provide methods through which we can provide database server details with user credentials. Some of the other common features provided by these DataSource implementation classes are;

 
  • Caching of PreparedStatement for faster processing
  • Connection timeout settings
  • Logging features
  • ResultSet maximum size threshold

Let’s create a simple JDBC project and learn how to use MySQL and Oracle DataSource basic implementation classes to get the database connection. Our final project will look like below image.

JDBC DataSource Example – Oracle, MySQL and Apache DBCP Tutorial

Database Setup

Before we get into our example programs, we need some database setup with table and sample data. Installation of MySQL or Oracle database is out of scope of this tutorial, so I will just go ahead and setup table with sample data.

MySQLSetup.sql

--Create Employee table
CREATE TABLE `Employee` (
  `empId` int(10) unsigned NOT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`empId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- insert some sample data
INSERT 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;

  

Now let’s move on to our java programs. For having database configuration loosely coupled, I will read them from property file.

db.properties

#mysql DB properties
MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver
MYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDB
MYSQL_DB_USERNAME=pankaj
MYSQL_DB_PASSWORD=pankaj123
 
#Oracle DB Properties
ORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
ORACLE_DB_URL=jdbc:oracle:thin:@localhost:1521:orcl
ORACLE_DB_USERNAME=hr
ORACLE_DB_PASSWORD=oracle

  

Make sure that above configurations match with your local setup. Also make sure you have MySQL and Oracle DB JDBC jars included in the build path of the project.

JDBC MySQL and Oracle DataSource Example

Let’s write a factory class that we can use to get MySQL or Oracle DataSource.

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;
    }
         
}

  

Notice that both Oracle and MySQL DataSource implementation classes are very similar, let’s write a simple test program to use these methods and run some test.

 
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();
                }
        }
    }
 
}

  

Notice that the client class is totally independent of any Database specific classes. This helps us in hiding the underlying implementation details from client program and achieve loose coupling and abstraction benefits.

When we run above test program, we will get below output.

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 Example

If you look at above DataSource factory class, there are two major issues with it.

  1. The factory class methods to create the MySQL and Oracle DataSource are tightly coupled with respective driver API. If we want to remove support for Oracle database in future or want to add some other database support, it will require code change.
  2. Most of the code to get the MySQL and Oracle DataSource is similar, the only different is the implementation class that we are using.

Apache Commons DBCP API helps us in getting rid of these issues by providing DataSource implementation that works as an abstraction layer between our program and different JDBC drivers.

Apache DBCP library depends on Commons Pool library, so make sure they both are in the build path as shown in the image.

Here is the DataSource factory class using BasicDataSource that is the simple implementation of DataSource.

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;
    }
}

  

As you can see that depending on user input, either MySQL or Oracle datasource is created. If you are supporting only one database in the application then you don’t even need these logic. Just change the properties and you can switch from one database server to another. The key point through which Apache DBCP provide abstraction is setDriverClassName() method.

Here is the client program using above factory method to get different types of connection.

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();
                }
        }
    }
 
}

  

When you run above program, the output will be same as earlier program.

If you look at the DataSource and above usage, it can be done with normal DriverManager too. The major benefit of DataSource is when it’s used within a Context and with JNDI.

With simple configurations we can create a Database Connection Pool that is maintained by the Container itself. Most of the servlet containers such as Tomcat and JBoss provide it’s own DataSource implementation and all we need is to configure it through simple XML based configurations and then use JNDI context lookup to get the DataSource and work with it. This helps us by taking care of connection pooling and management from our application side to server side and thus giving us more time to write business logic for the application.

In next tutorial, we will learn how we can configure DataSource in Tomcat Container and use it in Web Application.

查看更多关于【数据库其他】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
去重复的sql(Oracle) 去重复的英文
1.利用group by 去重复2.可以利用下面的sql去重复,如下  1) select id,name,sex from (select a.*,row_number() over(partition by a.id,a.set order by name) su from test a ) where su=1  2)select id,name,sex from (select a.*,row_number() over(p

0评论2023-02-10893

Oracle SQL七次提速技巧
以下SQL执行时间按序号递减。1,动态SQL,没有绑定变量,每次执行都做硬解析操作,占用较大的共享池空间,若共享池空间不足,会导致其他SQL语句的解析信息被挤出共享池。create or replace procedure proc1as beginfor i in 1..100000 loop    execute imme

0评论2023-02-10755

SQL ORACLE case when函数用法
case when 用法(1)简单case函数:格式:  case 列名   when 条件值1 then 选项1  when 条件值1 then 选项2......  else 默认值 end例如:  select   case job_level  when '1' then '1111'  when '2' then '2222'   when '3' then '3333

0评论2023-02-10564

mysql下如何执行sql脚本 执行SQL脚本
1.编写sql脚本,假设内容如下:  create database dearabao;  use dearabao;  create table niuzi (name varchar(20));  保存脚本文件,假设我把它保存在F盘的hello world目录下,于是该文件的路径为:F:\hello world\niuzi.sql2.执行sql脚本,可以有2种方法: 

0评论2023-02-10699

MySQL 5.7版本sql_mode=only_full_group_by问题
用到GROUP BY 语句查询时com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'col_user_6.a.START_TIME' which is not functionally dependent on colu

0评论2023-02-10973

Oracle迁移到MySQL性能下降的注意点 oracle数据库迁移需要注意的问题
背景:最近有较多的客户系统由原来由Oracle改造到MySQL后出现了性能问题CPU 100%,或是后台的CRM系统复杂SQL在业务高峰的时候出现堆积导致业务故障。在我的记忆里面淘宝最初从Oracle迁移到MySQL期间也遇到了很多SQL的性能问题,记忆最为深刻的子查询,当初的

0评论2023-02-10580

ORACLE中通过SQL语句(alter table)来增加、删除、修改字段
1.添加字段:alter table  表名  add (字段  字段类型)  [ default  '输入默认值']  [null/not null]  ;2.添加备注:comment on column  库名.表名.字段名 is  '输入的备注';  如: 我要在ers_data库中  test表 document_type字段添加备注  comm

0评论2023-02-10584

MySQL与Oracle 差异比较之六触发器
触发器编号类别ORACLEMYSQL注释1创建触发器语句不同create or replace trigger TG_ES_FAC_UNIT  before insert or update or delete on ES_FAC_UNIT  for each rowcreate trigger `hs_esbs`.`TG_INSERT_ES_FAC_UNIT` BEFORE INSERT on `hs_esbs`.`es_fac_u

0评论2023-02-10914

mysql where条件:某时间字段为今天的sql语句
1.查询:注册时间为今天的所有用户数:select count(*) from customer where TO_DAYS(createtime) = TO_DAYS(NOW())2.获取当前时间到凌晨24点还有多长时间:(Java中可用于判断某时间是否为今天)final Calendar cal = Calendar.getInstance();    ca

0评论2023-02-10717

mysql中的sql
变量用户变量: 在用户变量前加@系统变量: 在系统变量前加@@运算符算术运算符有: +(加), -(减), * (乘), / (除) 和% (求模) 五中运算位运算符有:(位于), | (位或), ^ (位异或), ~ (位取反),(位右移),(位左移)比较运算符有: = (等于),(大于),(小于), = (大

0评论2023-02-10936

Oracle的HINT可以强制指定SQL的执行计划,比如选择索引、表的连接顺序以及表的连接方式等等。(转)
在Oracle中查看所有的表: select * from tab/dba_tables/dba_objects/cat; 看用户建立的表 :  select table_name from user_tables;  //当前用户的表 select table_name from all_tables;  //所有用户的表 select table_name from dba_tables;  //包

0评论2023-02-10857

Oracle sql 子字符串长度判断
Oracle sql 子字符串长度判断 select t.* from d_table t WHEREsubstr(t.col,1,1)='8' and instr(t.col,'/')0 and length(substr(t.col,1,instr(t.col,'/')))5; 字符串的前两位都是数字:select * from d_table t WHERE regexp_like(substr(t.col,1,2), '^[

0评论2023-02-10759

Oracle、MySql、Sql Server比对
MySql:廉价(部分免费):当前,MySQL採用双重授权(DualLicensed),他们是GPL和MySQLAB制定的商业许可协议。假设你在一个遵循GPL的***(开源)项目中使用MySQL,那么你能够遵循GPL协议免费使用MySQL。否则,你须要购买MySQLAB制定的那个商业许可协议。Windows $

0评论2023-02-10441

Oracle 存储过程,临时表,动态SQL测试
--创建事务级别的结果临时表create global temporary table tmp_yshy( c1 varchar2(100), c2 varchar2(100))on commit delete rows;--创建事务级别的存储sql语句的临时表create global temporary table tmp_sql( c1 varchar2(4000))on commit delete rows;测

0评论2023-02-10508

更多推荐