25、jdbc操作数据库(2)

本文详细介绍了使用JDBC操作数据库时涉及的基本接口和类,包括Driver、DriverManager、Connection、Statement、PreparedStatement、CallableStatement、ResultSet等,解析了它们的作用及底层实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说一下使用jdbc时涉及到的一些基本的接口和类

java.sql.Driver

是数据库驱动接口,com.mysql.jdbc.Driver是mysql对应的驱动,由数据库供应商实现,用于提供驱动,实现了java.sql.Driver接口。

java.sql.DriverManager

管理驱动的类,可以使用DriverManager通过驱动来获取数据库连接。

java.sql.Connection

对数据库连接进行管理的接口,一个Connection就相当于一个通往对应数据库的通道。

对以上几个做一个详细介绍,直接看源码:

//com.mysql.jdbc.Driver 实现了 java.sql.Driver接口
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    //向驱动管理器注册自己
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }

    //构造一个 com.mysql.jdbc.Driver 用于注册
    public Driver() throws SQLException {
        // Required for Class.forName().newInstance()
    }
}

// 驱动管理器类中,看一下如何注册驱动、获取数据库连接的
public class DriverManager {
		//注册驱动最终调用的方法
		public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) throws SQLException {
	      //如果驱动程序还没有添加到列表 registeredDrivers 中,请注册它
	      if(driver != null) {
	          registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
	      } else {
	          throw new NullPointerException();
	      }
	  }
	  
	  //获取连接最终调用的方法
    private static Connection getConnection( String url, java.util.Properties info, Class<?> caller) throws SQLException {
        
        //当callerCl为null时,我们应该检查应用程序(它间接调用这个类)的类加载器,
        //这样就可以从这里加载rt.jar外部的JDBC驱动程序类。
        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

        // 遍历试图建立连接的已加载的 registeredDrivers。 
        for(DriverInfo aDriver : registeredDrivers) {
            // 如果调用方没有加载驱动程序的权限,那么跳过它。
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                Connection con = aDriver.driver.connect(url, info);
                if (con != null) { 
                    return (con);
                }
            }
        }  
    }
}

java.sql.Statement

对数据库操作的一个接口,可以发送sql、执行sql,它是先组装sql,然后发送sql查询结果,因此存在缺陷,其缺陷在于它发送的sql是将参数拼接完之后再进行编译的,所以容易发生sql注入攻击的危险,一般不用,这里不做详细介绍。
何为sql注入攻击,例如:发送的如下SQL

"SELECT * FROM USER WHERE USER_NAME = "+ USER_NAME +"AND PWD = "+PWD;
这时我这样设置:USER_NAME = user | PWD = 111 or 1=1,则SQL就会变成
SELECT * FROM USER WHERE USER_NAME = user AND PWD = 111 or 1=1
这样就直接规避掉了用户名和密码的校验。

java.sql.PreparedStatement

对数据库操作的一个接口,可以发送sql、执行sql,在获取PreparedStatement对象时,就已经将sql发送出去编译成了可执行的sql语句,也就是常说的预编译,SQL中使用占位符的方式来表示参数,占位符的地方只是参数,不能所作sql中固定的语法
例如:发送的sql="SELECT * FROM USER WHERE USER_NAME = ? AND PWD = ?";
然后再另外使用方法的方式去设置 ? 占位符处的参数,防止了sql注入的风险,通过Connection接口的connection.prepareStatement(sql)方法获取PreparedStatement,具体实现调用的是  com.mysql.jdbc.ConnectionImpl 中的方法。

java.sql.CallableStatement

和 PreparedStatement 功能大致相同,只是CallableStatement对象可以用于执行存储过程,而PreparedStatement只可以执行基本的SQL语句。

java.sql.ResultSet

用于存储查询返回的结果集,对于mysql来说,最终是通过com.mysql.jdbc.PreparedStatement中的方法获取的ResultSet对象。

java.sql.DatabaseMetaData

此对象用于获取数据库的整体综合信息,可以使用Connection对象的connection.getMetaData()方法直接获取。

java.sql.ResultSetMetaData

用于获取关于ResultSet对象中列的类型和属性信息,通过ResultSet对象的resultSet.getMetaData()方法直接获取。

java.sql.Types

这个类中定义了用于标识SQL类型的常量,称为JDBC类型。

这里总结一下:开发者使用jdbc操作数据库时,添加驱动时需要添加对应数据库厂商提供的驱动包中的Driver,而后具体操作时,直接调用 java.sql.* 包中接口的方法即可,最终底层调用的是对应数据库厂商提供的com.*.jdbc.*包中的实现类中的方法,数据库厂商提供的驱动包实现了java.sql.*包中接口的方法,这就是代码层面上的jdbc。java提供一组接口,数据库厂商实现这些接口,根据自身的特点编写不同的实现,而程序员只需使用java中的接口即可,利用了多态的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值