关于java中的jdbc、数据库驱动、数据库连接池的学习与理解

一、什么是jdbc

1.JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

2.jdbc的java api有哪些,四个常用的接口和一个类(Connection接口、Statement接口、PreparedStatement接口、ResultSet接口和DriverManager类),那我们怎么使用它,下面我就贴出一个简单的实例:

 JDBC的六个固定步骤 
1.注册数据库驱动(利用反射);
2.取得数据库连接对象Connection ;
3.创建SQL对象 ;
4.执行SQL命令,并返回结果集 ;
5.处理结果集 ;
6.依次关闭结果集;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/*
 * jdbd原生开发步骤
 */
public class Demo {
    public static void main(String[] args) throws Exception {
        //注册驱动,反射方式加载
        Class.forName("com.mysql.jdbc.Driver");
        //设置url
        String url = "jdbc:mysql://127.0.0.1:3306/test";
        //设置用户名
        String username = "root";
        //设置密码
        String password = "123456";
        //获得连接对象、Connection接口的使用以及DriverManager类的使用
        Connection con = (Connection)DriverManager.getConnection(url, username, password);
        //System.out.println(con);
        //获得执行者对象、PreparedStatement接口的使用
        String sql = "select * from user";
        PreparedStatement ps = con.prepareStatement(sql);
        //获得结果集、Statement接口的使用
        ResultSet rs = ps.executeQuery();
        //结果集处理、ResultSet接口的使用
        while(rs.next()){
            System.out.println(rs.getString("id")+"  "+rs.getString("name")+"  "+rs.getString("age")+"  "+rs.getString("address"));
        }
        //释放资源
        rs.close();
        ps.close();
        con.close();
    }
}

3.jdbc的原理,一张图片,让你明白jdbc与驱动的关系

解释:java提供访问数据库规范称为jdbc,而生产厂商提供规范的实现类称为驱动。jdbc是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。

二、什么是数据库驱动

1.其实上面我们已经很完美的解释了什么是数据库驱动,下面我们还可以通过这么理解数据库驱动,首先有数据库服务、连接、客户端,mysql安装包下载安装数据库服务然后启动服务,这就是数据库服务。客户端指的就是你的程序。连接指的就是把数据库服务和客户端连接起来就是我们所说的驱动了。

三、什么是数据库连接池

1.实际的开发中"获得连接"或者"释放资源"是非常消耗系统资源的两个过程,指的就是我们的程序每次都要和数据库进行连接和释放资源,这样就很浪费资源了,所以为了解决这个问题,通常我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池。

2.用池来管理Connection,这样可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了。

3.下面我们就使用一个简单的实例来完成我们的对它的理解(DBCP连接池为例):

3.1.DBCP 是 Apache 软件基金组织下的开源连接池实现,要使用DBCP数据源,需要应用程序应在系统中增加如下两个 jar 文件:

Commons-dbcp.jar:连接池的实现

Commons-pool.jar:连接池实现的依赖库

Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

3.2.创建dbcp.properties文件

#数据库驱动  
driverClassName=com.mysql.jdbc.Driver  
#数据库连接地址  
url=jdbc:mysql://localhost/test  
#用户名  
username=root  
#密码  
password=123456  
#连接池的最大数据库连接数。设为0表示无限制  
maxActive=30  
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制  
maxIdle=10  
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制  
maxWait=1000  
#超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)  
removeAbandoned=true  
#超过时间限制,回收没有用(废弃)的连接(默认为 300秒)  
removeAbandonedTimeout=180  

3.3.在获取数据库连接的工具类(如jdbcUtils)的静态代码块中创建池

import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
      /**
     * 在java中,编写数据库连接池需实现java.sql.DataSource接口,每一种数据库连接池都是DataSource接口的实现
     * DBCP连接池就是java.sql.DataSource接口的一个具体实现
     */
public class JdbcUtils_DBCP {
  
    private static DataSource ds = null;
    //在静态代码块中创建数据库连接池
    static{
        try{
            //加载dbcp.properties配置文件
            InputStream in =JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
            Properties prop = new Properties();
            prop.load(in);
            //创建数据源
            ds =BasicDataSourceFactory.createDataSource(prop);
        }catch (Exception e) {
            throw newExceptionInInitializerError(e);
        }
    }
    //从数据源中获取数据库连接
    public static Connection getConnection()throws SQLException{
        //从数据源中获取数据库连接
        return ds.getConnection();
    }
    //释放连接
    public static void release(Connection conn){
          if(conn!=null){
            try{
                //将Connection连接对象还给数据库连接池
                conn.close();
            }catch (Exception e) {
                e.printStackTrace();
           }
       }
   }
}

3.4.从应用中获取连接

        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try{
            //获取数据库连接
            conn =JdbcUtils_DBCP.getConnection();
            ……
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            //释放资源
            JdbcUtils_DBCP.release(conn);
        }

4.下面我们再来使用一个简单的实例来完成我们的对它的理解(Druid连接池为例)

4.1.Druid阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行快速整合。

4.2.Druid的使用

@Test
/**
 * Druid的使用:
 * 手动设置参数的方式
 */
public void demo1(){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    // 使用连接池:
    DruidDataSource dataSource = new DruidDataSource();    
    // 手动设置数据库连接的参数:
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost/test");
    dataSource.setUsername("root");
    dataSource.setPassword("123456");
    try{      
        // 获得连接:
        //	conn = JDBCUtils.getConnection();以前写法
        conn = dataSource.getConnection();
        // 编写SQL:
        String sql = "select * from account";
        // 预编译SQL:
        pstmt = conn.prepareStatement(sql);
        // 设置参数:
        // 执行SQL:
        rs = pstmt.executeQuery();
        while(rs.next()){
            System.out.println(rs.getInt("id")+"  "+rs.getString("name")+" "+rs.getDouble("money"));
        }
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //释放资源
        JDBCUtils.release(rs, pstmt, conn);
    }
}

4.3.Druid的使用(配置文件的方式、工厂类DruidDataSourceFactory)

/**
 * Druid的使用:
 * 配置方式设置参数
 * Druid配置方式可以使用属性文件配置的。
 * 文件名称没有规定但是属性文件中的key是固定的并且是全小写的
 * 配置文件:
 *     driverclassname=com.mysql.jdbc.Driver
 *     url=jdbc:mysql://localhost:3306/test
 *     username=root
 *     password=123456
 */
@Test
public void demo2(){
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try{
        //从属性配置文件中获取要连接的参数,配置文件中的key要是全小写:
        Properties pp = new Properties();
        pp.load(new FileInputStream("druid.properties"));//将配置文件加载到内存(程序)中 
        //使用连接池
        DataSource dataSource =  DruidDataSourceFactory.createDataSource(pp);
        // 获得连接:
        //	conn = JDBCUtils.getConnection();//以前写法
        conn = dataSource.getConnection();
        // 编写SQL:
        String sql = "select * from account";
        // 预编译SQL:
        pstmt = conn.prepareStatement(sql);
        // 设置SQL语句中参数:此时没有要设置的参数
        // 执行SQL:
        rs = pstmt.executeQuery();
        while(rs.next()){
            System.out.println(rs.getInt("id")+" "+rs.getString("name")+" "+rs.getDouble("money"));
        }
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //释放资源
        JDBCUtils.release(rs, pstmt, conn);
    }
}

4.3.1.什么是数据源

由SUN制定的用于获取数据库连接的规范接口。它存在于 javax.sql包中,用来代替 DriverManager 的方式来获取连接,JDBC2.0 提供了javax.sql.DataSource接口,它负责建立与数据库的连接,当在应用程序中访问数据库时不必编写连接数据库的代码,直接引用DataSource获取数据库的连接对象即可。用于获取操作数据Connection对象。

4.3.2.数据源与数据库连接池

数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,当需要访问数据库时,只需要从数据库连接池中获取空闲的数据库连接,当程序访问数据库结束时,数据库连接会放回数据库连接池中。

4.3.3.关于Datasource与数据库连接池的区别。

数据库连接有两种方式:

1 :直连数据库方式

当调用DataSource.getConnection()时,其实它调用的是DriverManager.getConnection(url, user, password)来获取一个Connection,Connection使用完后被close,断开与数据库的连接,我们称这总方式是直连数据库,因为每次都需要重新建立与数据库之间的连接,而并没有把之前的Connection保留供下次使用.

2:池化连接方式 
1.可以说这种方式就是使用了连接池技术.DataSource内部封装了一个连接池,当你获取DataSource的时候,它已经敲敲的与数据库建立了多个Connection,并将这些Connection放入了连接池,此时调用DataSource.getConnection()它从连接池里取一个Connection返回,Connection使用完后被close,但这个close并不是真正的与数据库断开连接,而是告诉连接池"我"已经被使用完,"你"可以把我分配给其它"人"使用了.就这样连接池里的Connection被循环利用,避免了每次获取Connection时重新去连接数据库.


对DataSource的两种实现方式已经介绍完毕,现在知道DataSource与连接池之间的是关系而不是区别了吧,因为DataSource与连接池根本就不是同一类型的东西,只有同一类型的东西才存在区别,例如:oracle与db2都是数据库,它们才存在区别.
 
DataSource与连接池的关系是:DataSource利用连接池缓存Connection,以达到系统效率的提升,资源的重复利用.
 
而连接池它可以单独存在,不需要依靠DataSource来获取连接,你可以直接调用连接池提供的方法来获取连接.
 
目前大多数应用服务器都支持池化连接方式的DataSource.
 
常用的连接池有c3p0,dbcp,Proxool...
 
一般场景:JNDI-> DataSource->连接池(c3p0,dbcp,Proxool等)->DriverManager->connection

参考资料:https://www.xuebuyuan.com/3222156.html

四、结束

Always keep the faith!!!

 

  • 12
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值