数据库概论之 JDBC 编程的原理与使用

大家好,已经好久没更新了 , 学校的学业有点忙 , 没有额外的精力去进行更新了 , 假期开始了 , 我们也要开始努力了
数据库相对来说难度不是那么高,大家只要勤加练习、熟记语法,我相信学好数据库不是什么问题,博主会从0剖析,逐步讲解数据库的知识点,并且会举很多实例。最重要的是,博主不会采用软件,使用最原始的方式 -> 命令行来讲解,这样讲解的好处是逐个语句进行书写,不会造成读者思路跟不上的问题!
在这里插入图片描述

一. JDBC 的工作原理

1.1 工作原理

MySQL 是一个客户端-服务器结构的程序 , 但是并不是所有的数据库是这样的 . Oracle / SQL Server也是客户端 - 服务器结构的 , 但是 SQLite 就不是

咱们通过代码实现的操作数据库的程序 , 本质上也是一个MySQL 客户端 , 但是咱们不能手动实现 MySQL 服务器 , 因为实在是太复杂了

像主流的数据库 , 都会提供一些 API 接口 , 方便程序员自己 DIY 数据库客户端 , 这就称为 “数据库SDK”

API : 提供了一些 函数/方法/类 , 可以让程序员直接调用来完成一些功能 , 比如我们之前学过的 Java 标准库里面提供的类 , 也可以叫做 " Java API "

SDK : 范围更大 , 在提供 API 的基础上 , 还会提供一些可执行程序(工具) 辅助开发或者调试

那么 API 是数据库提供的 , 那有可能不同厂商推出的 API 完全不同 , 这就增加了大家的学习成本 , 但是这个标准还不好让自己人设定 , 所以 Java 提供了一套标准的接口体系 , 我们只需要学习 Java 官方提供给我们的这套体系即可 , 数据库公司会尽量让他们的 API 贴近于官方体系 , 那么 Java 提供的这套操作数据库的 API 就叫做 JDBC .

那么每个厂商为了贴近这套官方体系 , 还可能需要额外的程序帮助完成工作 , 那么这个东西就叫做 " JDBC 驱动包".

1.2 JDBC驱动包的下载

JDBC 驱动包哪里获取呢 ?

可以去我们的 Maven 中央仓库

Maven 中央仓库

搜索 MySQL

点进去之后 , 选择版本 , 因为我们的 MySQL 就是 5.x 版本 , 所以我们的驱动包也要下载 5.x 系列的 ,一定要确保大版本在 5 ,小版本无所谓

点击 jar 进行下载

下载成功后 , 我们来看一下 jar 包 , 我们就可以把它理解为是一个压缩包 , 里面存储的都是 .class 文件 , 我们可以用解压缩软件查看

我随便点进去的某一个文件夹

1.3 JDBC驱动包的导入

下载好 JDBC 驱动包之后 , 我们创建项目

点击项目名 , 右键 , New , Directory

起一个叫做 lib 的文件夹

然后找到我们下载的 JDBC 驱动包 , 拖进 lib 文件夹

右键 lib , 然后 Add as Library

最后 , 我们就导入成功了

二. JDBC的使用

在接下来的一系列操作之前 , 我们先做一些准备工作

创建一个数据库

create database test;

使用数据库

use test;

创建一个数据表

create table Test(id int,name varchar(20));

2.1 描述数据库的位置

我们要想操作数据库 , 就需要先连接上数据库的服务器 , 要想连接上服务器 , 就需要描述出服务器所在位置

在 JDBC 中 , 我们用 DataSource 来描述数据库的位置

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCTest {
    public static void main(String[] args) {
        DataSource dataSource = new MysqlDataSource();
    }
}

所以我们采用向上转型的做法 , MysqlDataSource 实现了 DataSource , 这个了来自于驱动包 , 我们驱动包要是导入不成功 , 就不能成功使用

接下来我们具体指定数据库服务器位置

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCTest {
    public static void main(String[] args) {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl();//目前这句话有问题,括号里应该填写参数
    }
}

((MysqlDataSource)dataSource).setUrl();这句代码又实现了向下转型那有的同学问了 , 你转来转去的在干嘛 ?

那我们还有一种写法

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCTest {
    public static void main(String[] args) {
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setUrl();//目前这句话有问题,括号里应该填写参数
    }
}

但是不推荐第二种写法 , 因为第一种写法 , 我们的数据源是 DataSource 类型 , 后续写其他的代码 , 需要使用到数据源 , 那么它的类型是 DataSource 类型 , 他是通用类型 , 可以代表所有数据库 , 将来我们要换数据库了 , 只需要把实例化部分改成别的数据库即可 , 就不用改一大堆了

但是第二种写法 , 数据源是 MysqlDataSource 类型 , 后续其他位置需要数据源 , 对应的位置也都是 MySQL 数据库了 . 将来要是更换数据库 , 那么我们就需要把散落在各个位置的 MysqlDataSource 进行修改 , 十分麻烦 .

这其实就是多态的好处 , 我们之前学习 “封装” , 封装是为了程序员不必了解太多的实现细节 , 就可以直接使用 , 从而降低使用成本.

“多态” 就是在封装的基础上 , 程序员不需要关心实现的细节 , 甚至对象是什么类型都可以不用考虑了 , 更一步降低使用成本

那么接下来 , 我们继续完善代码 , 我们上面的setUrl()里面还没填参数

那么实现一下

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCTest {
    public static void main(String[] args) {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        
    }
}

括号里面这么长一串 , 我们写一次就好 , 之后不断复制就可以了.

IP地址 端口号 数据库名我们已经描述完了 , 接下来要在描述一下用户名以及密码

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCTest {
    public static void main(String[] args) {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("haha");
    }
}

2.2 建立数据库连接

网络通信中 , 有两种情况 :

  1. 有连接 : 相当于"打电话"
  2. 无连接 : 相当于"发微信"

数据库采用的就是有连接这种情况

使用 dataSource.getConnection来建立连接

但是 getConnetion 报错了 , 这是因为数据库采用的是有连接的形式 , 在连接之前 , 会先投石问路 , 看链路是否通畅 , 然后最后也要及时释放资源 , 但是假如和数据库连接失败 , 就会抛出异常 . 所以我们要处理一下异常

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JDBCTest {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("baba");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
    }
}

我们再加一条语句 , 方便查看具体效果

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class JDBCTest {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("baba");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

那么假如我们密码设置错误了

2.3 创建操作命令(Statement)

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTest {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("haha");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);

        //3.构造 SQL 语句,JDBC操作数据库,本质上还是通过SQL来描述数据库操作
        String sql = "insert into test values (1,'甄嬛')";
        //不光构造出来还不行,需要搭配 PreparedStatement 类使用
        PreparedStatement statement = connection.prepareStatement(sql);
    }
}

2.4 执行SQL语句

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTest {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("haha");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);

        //3.构造 SQL 语句,JDBC操作数据库,本质上还是通过SQL来描述数据库操作
        String sql = "insert into test values (1,'甄嬛')";
        //不光构造出来还不行,需要搭配 PreparedStatement 类使用
        PreparedStatement statement = connection.prepareStatement(sql);
        
        //4.执行 SQL 语句
        //input update delete都是通过 executeUpdate 来执行的
        //select 则是通过 executeQuery 来执行的
        //返回值代表这个操作影响到几行
        int n = statement.executeUpdate();
        System.out.println(n);
    }
}

2.5 释放资源

要注意的一点 : 后创建的先释放

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class JDBCTest {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("baba");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);

        //3.构造 SQL 语句,JDBC操作数据库,本质上还是通过SQL来描述数据库操作
        String sql = "insert into test values (1,'甄嬛')";
        //不光构造出来还不行,需要搭配 PreparedStatement 类使用
        PreparedStatement statement = connection.prepareStatement(sql);

        //4.执行 SQL 语句
        //input update delete都是通过 executeUpdate 来执行的
        //select 则是通过 executeQuery 来执行的
        //返回值代表这个操作影响到几行
        int n = statement.executeUpdate();
        System.out.println(n);

        //5.断开连接,释放资源
        statement.close();
        connection.close();
    }
}

那么我们执行代码 , 看一下效果


2.6 用户输入信息构造 SQL

那么我们想要让用户输入要插入的内容呢 ?

那么上面这种情况就写死了

我们可以这样做

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCInsert {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("baba");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        //System.out.println(connection);

        //3.让用户输入想要插入的数据
        //next 读到空白符(空格, 制表符, 翻页符, 换行符, 回车符, 垂直制表符.....) 推荐
        //nextLine 读到换行符
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要插入的同学学号:");
        int id = sc.nextInt();
        System.out.println("请输入要插入的同学的姓名:");
        String name = sc.next();

        //3.构造 SQL 语句,JDBC操作数据库,本质上还是通过SQL来描述数据库操作

        String sql = "insert into test values (" + id + ",'" + name + "')";
        //不光构造出来还不行,需要搭配 PreparedStatement 类使用
        PreparedStatement statement = connection.prepareStatement(sql);

        //4.执行 SQL 语句
        //input update delete都是通过 executeUpdate 来执行的
        //select 则是通过 executeQuery 来执行的
        //返回值代表这个操作影响到几行
        int n = statement.executeUpdate();
        System.out.println(n);

        //5.断开连接,释放资源
        statement.close();
        connection.close();
    }
}

其实这个方法并不好 , 因为比如这句代码 , 看起来就很乱

String sql = "insert into test values (" + id + ",'" + name + "')";

而且这种情况并不是最糟糕的 , 有一种叫做 “SQL注入攻击” , 因为 name 是用户自己构造的 , 那么用户故意构造一组其他 SQL 呢 , 比如

name = ');drop table test;

那么我给大家讲解一下正确方式

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCInsert {
    public static void main(String[] args) throws SQLException {
        //1.使用 DataSource 描述 MySQL 服务器的位置
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("baba");

        //2.和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        //System.out.println(connection);

        //3.让用户输入想要插入的数据
        //next 读到空白符(空格, 制表符, 翻页符, 换行符, 回车符, 垂直制表符.....) 推荐
        //nextLine 读到换行符
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要插入的同学学号:");
        int id = sc.nextInt();
        System.out.println("请输入要插入的同学的姓名:");
        String name = sc.next();

        //3.构造 SQL 语句,JDBC操作数据库,本质上还是通过SQL来描述数据库操作
        //使用 ? 作为占位符. 后续使用 statement 对象针对 ? 进行替换.
        String sql = "insert into test values(?, ?)";
        //不光构造出来还不行,需要搭配 PreparedStatement 类使用
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(1,id);//括号里面前面代表第一个问号,后面代表修改成功需要的值
        statement.setString(2,name);

        //4.执行 SQL 语句
        //input update delete都是通过 executeUpdate 来执行的
        //select 则是通过 executeQuery 来执行的
        //返回值代表这个操作影响到几行
        int n = statement.executeUpdate();
        System.out.println(n);

        //5.断开连接,释放资源
        statement.close();
        connection.close();
    }
}

我们来试一下

再去数据库查询一下

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加勒比海涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值