JDBC的使用

JDBC是什么?

JDBC是Java访问数据库的基石,三大框架之一的Hibernate只是更好的封装了JDBC而已。它是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API)
JDBC API 是一系列的接口,它使得应用程序能够进行数据库联接,执行SQL语句,并且得到返回结果


基本知识

Driver接口

  • Java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现
  • 在程序中不需要直接去访问实现了 Driver 接口的类,而是由驱动程序管理器类(java.sql.DriverManager)去调用这些Driver实现。

加载与注册 JDBC 驱动

  • 加载 JDBC 驱动需调用 Class 类的静态方法 forName(),向其传递要加载的 JDBC 驱动的类名
  • DriverManager 类是驱动程序管理器类,负责管理驱动程序
  • 通常不用显式调用 DriverManager 类的 registerDriver() 方法来注册驱动程序类的实例,因为 Driver接口的驱动程序类都包含了静态代码块,在这个静态代码块中,会调用 DriverManager.registerDriver()
    方法来注册自身的一个实例。

建立连接

  • 可以调用 DriverManager 类的 getConnection() 方法建立到数据库的连接
  • JDBC URL 用于标识一个被注册的驱动程序,驱动程序管理器通过这个 URL 选择正确的驱动程序,从而建立到数据库的连接。
  • JDBC URL的标准由三部分组成,各部分间用冒号分隔:
    jdbc:<子协议>:<子名称>
    协议:JDBC URL中的协议总是jdbc
    子协议:子协议用于标识一个数据库驱动程序
    子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息
    常用数据库的JDBC URL

访问数据库

  • 数据库连接被用于向数据库服务器发送命令和 SQL 语句,在连接建立后,需要对数据库进行访问,执行 sql 语句
  • 在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:Statement,PrepatedStatement,CallableStatement

Statement

  • 通过调用 Connection 对象的 createStatement 方法创建该对象
  • 该对象用于执行静态的 SQL 语句,并且返回执行结果。Statement 接口中定义了下列方法用于执行 SQL 语句:
    ResultSet excuteQuery(String sql)
    int excuteUpdate(String sql)
  • 但是Statement并不常用,接下来会说明

Result

  • 通过调用 Statement 对象的 excuteQuery() 方法创建该对象
  • ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现
  • ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next()方法移动到下一行
  • ResultSet 接口的常用方法:
    boolean next()
    getString()

PreparedStatement

  • 使用PreparedStatement可防止SQL注入攻击,另外最大程度提高性能,因此通常代替Statement使用
  • 可以通过调用 Connection 对象的 preparedStatement() 方法获取 PreparedStatement 对象
  • PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL 语句
  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1开始),第二个是设置的 SQL 语句中的参数的值

JDBC使用

JDBC连接数据库中,有两种方法:一种是普通连接,一种是通过建立连接池与数据库连接。
普通连接一般是:1.在主程序中建立数据库连接,2.进行SQL操作,3.断开数据库连接。但是这种模式存在某些问题:1.需要连接数据库的时候,就像数据库请求一个,每次都要将Connection加载到内存中然后验证用户密码,这样极大浪费了系统资源,若多人在线频繁操作,数据库可能会奔溃。2.每次使用完都得断开,否则,如果程序出现异常未能关闭,将会内存泄漏。3.无法控制连接对象数。
而连接池:就是一个缓冲池,允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。可保持最小及最大连接数。相比较下:优点在于:资源可重用、更快的系统反应速度、新的资源分配手段、统一连接管理避免数据库连接泄漏。
连接池工作原理

普通连接模式:

根据数据库导入相应的驱动包,我使用的是Oracle数据库,在工程里导入ojdbc6包。创建工具util包,在util包下创建DBUtil类:

public class DBUtil {
    //JDBC驱动路径
    private static String driver = "oracle.jdbc.driver.OracleDriver";
    //数据库地址
    private static String url = "jdbc:oracle:thin:@//192.168.126.126:1521/xiaoxinxin";
    //数据库用户名密码
    private static String user = "user_admin";
    private static String password = "admin123456";

    //通过驱动连接数据库,获取与数据库的连接
    public static Connection getConnnection() {
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    //关闭数据库连接
    public static void dbClose(Connection connection ,PreparedStatement preparedStatement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

DBCP连接池:

DBCP为Tomcat使用连接池的组件,具体介绍可再问度娘。该连接池需要同时导入ojdbc6包和该连接池需要的包。

package com.wzx.util;
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class DBUtilByDBCP {
    private static String driver = "oracle.jdbc.driver.OracleDriver";
    private static String url = "jdbc:oracle:thin:@//192.168.126.126:1521/xiaoxinxin";
    private static String user = "user_admin";
    private static String password = "admin123456";
    private static BasicDataSource basicDataSource = null;
    private static Connection connection = null;
    private static DBUtilByDBCP dbUtilByDBCP = null;

    private DBUtilByDBCP() throws SQLException {
        basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName(driver);
        basicDataSource.setUrl(url);
        basicDataSource.setUsername(user);
        basicDataSource.setPassword(password);
        //设置连接池初始连接数、最大连接数及最小连接数
        basicDataSource.setInitialSize(5);
        basicDataSource.setMaxActive(20);
        basicDataSource.setMinIdle(2);
    }

    //采用单例模式创建连接池对象,并获取连接
    public static Connection getConnection() throws SQLException {
        if (dbUtilByDBCP == null) {
            dbUtilByDBCP = new DBUtilByDBCP();
        }
        connection = basicDataSource.getConnection();
        return connection;
    }

    //关闭连接
    public static void dbClose(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

C3P0连接池:

Hibernate,Spring框架都有用到它,相比较DBCP,它有自动回收空闲连接的功能。同DBCP一样,需导入C3P0所需要的包。用法差不多,只是连接池对象改为:ComboPooledDataSource。这里就不再重复

执行SQL语句

以下代码是我写的Servlet程序中用户登录验证的方法,对数据库的增、删、改、查大都差不多,这里只写一例。

public class UserDao {

    public boolean login(String userName, String uerPassword){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        //要执行的Sql语句,参数用?代替
        String sql = "select * FROM user_info WHERE user_name = ? AND user_password = ?";
        boolean connetionFlag = false;
        try {
            //获取数据库连接
//        connection = DBUtil.getConnnection();
//            connection = DBUtilByDBCP.getConnection();
            connection = DBUtilByC3P0.getConnection();
            if (connection == null){
                return false;
            }
            //准备SQL语句,并将参数传入
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, userName);
            preparedStatement.setString(2, uerPassword);
            //执行SQL语句,获取返回的数据
            resultSet = preparedStatement.executeQuery();
            if (!resultSet.next()) {
                connetionFlag = false;
            } else {
                connetionFlag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //执行完SQL语句,关闭与数据库的连接
//            DBUtil.dbClose(connection, preparedStatement, resultSet);
//            DBUtilByDBCP.dbClose(connection);
            DBUtilByC3P0.dbClose(connection);
            return connetionFlag;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值