网站Logo 苏叶的belog

JDBC

wdadwa
5
2025-12-20

一,JDBC概述

JDBC 全称 java DataBase Connectivity,java 数据操作。

  • JDBC 就是 java 语言操作关系型数据库的一套 API。

  • JDBC 的目的是用同一套 java 代表,操作不同的关系型数据库。

  • JDBC 本质是 Sun 公司定义的一套操作所有关系型数据库的规则,即接口

    各个数据库厂商去实现这套接口,提供数据库驱动 jar 包,我们可以使用这套接口 JDBC 编程,真正执行的代码是驱动 jar 包中的实现类

    好处:java 代表不需要针对不同的数据库分别开发 jdbc,可以随时替换底层数据库而代码不需要改变。

注意:所有 Java ORM 框架,本质上都是在 JDBC 上「套娃」!

  • MyBatis、Hibernate、JPA、Spring Data JDBCTemplate... 全都是 JDBC 的高级包装

  • 从底层到上层:数据库访问的「套娃」结构

    业务代码
        ↓
    ORM框架(MyBatis、Hibernate)       ← 你写的代码
        ↓
    JDBCTemplate、MyBatis Executor      ← 框架核心
        ↓
    JDBC Driver(mysql-connector-java) ← 数据库驱动
        ↓
    MySQL协议(TCP Socket通信)          ← 网络协议
        ↓
    MySQL数据库服务器
    

二,快速入门

以 MYSQL 为例,先导入mysql-connercot-java这个 jar 包到项目中。

  1. 注册驱动

    Class.forName("com.mysql.jdbc.Driver");//mysql5.0之后的写法
    Class.forName("com.mysql.cj.jdbc.Driver");//mysql8.0之后的写法
    
  2. 获取连接

    String url = "jdbc:mysql://127.0.0.1:3306/wdadwa?&useSSL=false&serverTimezone=UTC";
    String username="root";
    String password="123456";
    Connection conn = DriverManager.getConnection(url, username, password);
    
  3. 定义 SQL 语句

    String sql="select * from student";
    
  4. 获取执行 SQL 的对象

    Statement stmt = conn.createStatement();
    
  5. 执行 SQL

    ResultSet resultSet = stmt.executeQuery(sql);
    
  6. 处理返回结果

  7. 释放资源

    stmt.close();
    conn.close();
    

三,API详解

3.1 DriverManger

作用:

  1. 注册驱动
  2. 获取数据库连接

两个重要的方法

DriverManager.registerDriver(new Driver());//注册驱动
Connection conn = DriverManager.getConnection(url, username, password);//建立连接对象

第一个注册驱动在 Mysql5.0 之后就不需要写了,Class.forName(""com.mysql.jdbc.Driver"") 在底层也是通过这个方式注册的驱动.

DriverManger 建立连接对象三个参数详解:

  1. 第一个参数:

    语法:jdbc:mysql://ip地址(域名):端口号/数据库名名?参数键值对1&参数键值对2...

    举例:jdbc:mysql://127.0.0.1:3306/db1

    如果连接的是本机 mysql, 默认端口 3306,url 可以简写为:jdbc:mysql////数据库名?参数键值对1&参数键值对2...

    参数键值对有:

    1. useSSL=false禁用安全连接方式,解决警告提示.
    2. useServerPrepStmts=true打开SQL预编译功能
  2. 第二个参数:用户名

  3. 第三个参数:密码

3.2 Connection

作用:

  1. 获取执行SQL的对象
  2. 管理事务

利用 Connection 获取执行 SQL 的对象分为:

  • 普通执行 SQL 对象

    Statement stmt = conn.createStatement();
    
  • 预编译 SQL 的执行对象 (防止 SQL 注入)

    PreparedStatement preparedStatement = conn.prepareStatement(sql);
    
  • 执行存储过程的对象(存储过程不常用 )

    CallableStatement callableStatement = conn.prepareCall();
    

利用 Connection 进行事务管理

//开启事务
setAutoCommit(boolean autoCommit);//true自动提交事务,false手动提交事务
conn.commit();//提交事务
conn.setAutoCommit(false);//关闭事务的自动提交
conn.rollback();//回滚事务

一般在 java 中使用 try catch 包围起来,当出现异常就回滚事务。

3.3 Statement

作用:执行 SQL 语句。

Statement 提供了三种方法来执行 SQL

  1. executeQuery用来执行 DQL 语句

    String sql="select * from student where name='"+name+"'and password='"+pwd+"'";
    //即通过 '"字符串"'这种形式把字符串包围起来
    ResultSet resultSet = stmt.executeQuery(sql);
    
  2. executeUpdate用来执行 DDL,DML 语句

    String sql="update student set age=10 where age=21";
    int i = stmt.executeUpdate(sql);
    //执行DDL语句返回的可能是0,执行DML语句返回的是被影响的行数
    
  3. execute可以执行任意 sql 查询

    boolean execute = stmt.execute(sql);
    //如果查询结果时ResultSet,这个方法就会返回true,如果不是ResultSet,比如insert或者update,就会返回false。
    

3.4 ResultSet

作用:封装了 DQL 查询语句的结果集合。

使用 ResultSet 中方法获取查询结果:

boolean next();
//将光标从当前位置向下移动一行,并判断当前行是否为有效行(移动后)
//返回值true,有效行
//返回值false,无效行
//默认从数据行的上一行作为起始位置

2953321-20230422205118560-97045192.png

xxx getXXX(参数);//获取数据
//xxx代表数据类型,如int getInt(参数),String getString(参数)
//参数:有两种重载形式
//int:根据列的编号获取元素,从1开始
//String:根据列的名字获取元素
//举例:
ResultSet res = stmt.executeQuery(sql);
res.getInt(1);//获取id
res.getInt("id");//获取id
 while(res.next()){
     int anInt = res.getInt(4);
     System.out.println(anInt);
}
res.close();//写完后记得释放资源

3.5 PreparedStatement

PreparedStatement 是 Statement 的子类。

作用:与变量 SQL 并执行,预防 SQL 注入问题。

SQL 注入:通过操作输入来修改事先定义好的 SQL 语句,用来达到执行代码对服务器进行攻击的方法。

SQL 注入产生的原因:字符串拼接产生的问题

String name="wdadwa";
String pwd="' or '1'='1";
String sql="select * from tb_user where username='"+name+"' and password='"+pwd+"' ";
System.out.println(sql);//select * from tb_user where username='wdadwa' and password='' or '1'='1' 
//这样的SQL语句会导致查询返回结果为整张表,因为1=1是个恒等式,这个SQL等同于select * from tb_user

PreparedStatement 使用

  1. 获取 PreparedStatement 对象

    String sql="select * from student where name=? and age=?";//用占位符?代替变量
    PreparedStatement pstmt=conn.prepareStatement(sql);
    
  2. 设置参数值

    //PreparedStatement对象:setXxx(参数1,参数2):给?赋值
    //Xxx:数据类型,比如setInt(参数1,参数2);
    //参数1:?占位符的编号,从1开始
    //参数2:?的值
    pstmt.setString(1,"张三");
    pstmt.setInt(2,10);
    
  3. 执行 SQL

    ResultSet resultSet1 = pstmt.execute();//执行SQL语句
    ResultSet resultSet2= pstmt.executeQuery();//executeQuery执行DQL语句
    ResultSet resultSet3 = pstmt.executeUpdate();//executeUpdate用来执行DDL,DML语句
    

    底层原理:将"' or '1'='1"中的单引号作为文本使用转义字符反斜杠转义了,从而区分了 sql 语句的单引号和文本的单引号

    实际传入的是

    select * from tb_user where username='wdadwa' and password='\' or \'1\'=\'1'
    

PreparedStatement 预编译:

  1. 在获取PreparedStatement对象时,将SQL语句发送给MYSQL服务器进行检查,编译(这些步骤很耗时)
  2. 执行时就不需要再进行这些步骤了
  3. 如果sql模板一样,只需进行一次检查和编译即可。

预编译功能需要在建立连接对象的时候传入参数useServerPreStmts=true

四,数据库连接池

数据库连接池简介:

  • 数据库连接池是个容器,负责分配,管理数据库连接

  • 允许应用程序重复使用一个现有的数据库连接,而不是重新再建一个。

  • 释放空闲时间超过最大空闲时间的数据库连接,避免因为没有释放数据库连接导致的数据库连接遗漏

    好处:

    • 资源重用
    • 提高系统响应效率
    • 避免数据库连接遗漏

数据库连接池实现

  • 标准接口:DataSource

    官方提供的数据库连接池标准接口,由第三方组织实现此接口。

    功能:获取连接

    Connection getConnection()
    
  • 常见的数据库连接池:

    1. DBCP
    2. C3P0
    3. Druid
  • Druid:

    Druid 连接池是阿里巴巴开源的数据库连接池项目,是 java 语言最好的数据库连接池之一。

    下载地址Central Repository: com/alibaba/druid (maven.org)

使用方法:

  1. 导入 jar 包

  2. 定义配置文件druip.properties

    模板:

    #驱动类名,固定模板
    driverClassName=com.mysql.cj.jdbc.Driver 
    #url
    url=jdbc:mysql://localhost:3306/test?useUnicode=true&
    #字符编码 等配置
    characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
    #数据库的账号密码
    username=root
    password=123456
    #初始化连接数
    initialSize=10
    #最大连接数
    maxActive=100
    #最大等待时间(毫秒
    maxWait=3000
    
  3. 加载配置文件

    Properties prop=new Properties();
    prop.load(new FileInputStream("src/druid.properties"));//配置文件路径
    
  4. 获取数据库连接池对象

    DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
    
  5. 获取连接

    Connection connection = dataSource.getConnection();
    
动物装饰