MySQL | JDBC连接数据库详细教程

目录

1.JDBC是什么

(1)API

(2)JDBC来源背景 

(3)下载驱动包

2.JDBC操作数据库

准备工作

(1)导入项目

(2)准备好数据库和数据表

编写代码

(1)创建"数据源"DataSource.

(2)和数据库服务器连接(连接对象)

(3)能够构造一个操作数据库的sql语句(语句对象)

(4)执行sql

(5)执行完毕,释放资源

 3.完整代码:

JDBC插入数据表记录

JDBC查询数据表记录

JDBC修改数据表记录

JDBC删除数据表记录

4.常出现的一些问题:

5.结语


1.JDBC是什么

(1)API

         我们可以把API(Application Programming Interface)应用程序接口理解成"一组类"或者"一组方法",都是现成的(别的大佬写好的),可以直接进行调用,就可以实现一些效果.MYSQL是一个基于C/C++实现的数据库,本身也提供了一系列的API,让程序猿调用,从而通过代码来操作数据库.API是一个通用的概念,不仅仅局限于Java中.

        对于Java来说,Java提供了"标准库",只要安装了Java,此时就可以使用标准库中的类和方法(标准库的API).也可以使用其他大佬写好的类和方法(第三方标准库的API),就不是自带的了,需要额外去安装.同理,C/C++也是一样,都有标准库自带的API,也有第三方库的API.

        当然在有的库中,提供的API特别特别的多,形成了一系列的体系,这种的情况,也可以把它称为是SDK(SoftwareDevelopment Kit)软件开发工具包,也是一个更广泛的概念,不局限于Java.在Java中所用到的JDK,就是一个SDK,只不过给他起了个专属的名字,叫Java软件开发工具包.

(2)JDBC来源背景 

        MySQL本身提供了一组API供程序猿调用,Oracle,SQLite...都提供了这样的API让程序猿调用.这些不同的数据库API提供的功能大同小异,但是细节上还是存在很大差异.这些数据库都是不同的厂商/不同的人开发的,那么就会有"我开发MySQL的人,凭什么要和SQL Server的API一致?"的想法.并且,如果在项目中用到不同的数据库,一个程序猿需要学习很多份的api的使用,非常的麻烦,使得程序猿有更重的学习负担.所以程序猿很渴望大家的API都保持一样,但是各个数据库厂商都互不相让.此时Java大佬站出来,提出方案:我这边搞一套API接口标准,大家都照着我的这一套来适配过来,每个数据库厂商额外写一些代码,能够按照Java提供的这一套标准把原来的原生API重新封装以下,后续程序猿就只需要学习掌握Java这一套API就可以无缝的切换各种数据库了.这一套API,就是JDBC.

 

 Java是通过JDBC这样的技术来操作MYSQL的.

        JDBC最大的意义就是,Java提供的一套关于数据库操作的接口,各个数据库厂商要把自己的api对接到适配到JDBC上.程序猿只要掌握一套api,就可以操作不同的数据库了.

(3)下载驱动包

        JDBC是Java标准库提供的,只要安装了JDK就会自带JDBC.但是,使用JDBC来操作mysql就需要下载导入mysql的驱动包.对于Java来说,日常开发会用到大量的第三方库,就有大佬把这些第三方库的安装包收集到一起,统一整理到一个网站上,称为"中央仓库",类似于收集APP的应用商店一样,那么我们可以直接去中央仓库`去进行下载mysql提供的JDBC的驱动包了,因为去mysql官网下载-Oracle官网非常的复杂麻烦.(驱动包的版本和数据库服务器版本不完全一致,只是最前面第一位的大版本要求匹配即可.)

 网址:https://mvnrepository.com/ 

-

 

        .jar后缀的文件(.jar的方式是最常见的一种发布Java程序的方式)

        .jar其实是一个类似于.rar这样的压缩包文件,这里包含了很多的.class(.java编译生成的字节码文件).写好的.java程序,就可以把编译出来的.class拷贝给别人,别人就能运行使用了.但是由于一个程序中,往往.class字节码文件会很多,涉及到一些复杂的目录结构,直接拷贝一堆.class非常不友好~~于是约定把这些要发布的.class按照特定的格式,打包压缩就得到了.jar文件,后续直接拷贝.jar文件即可,并且JVM可以直接识别.jar内部的.class并直接运行.

2.JDBC操作数据库

准备工作

(1)导入项目

        1)项目中随便创建一个目录lib

        2)把下载好的.jar拷贝到lib中

        3)右键该目录,最下方会显示👇(告诉IDEA,当前这个目录是存放第三方库的目录.此时IDEA就能够识别到咱们拷贝进来的驱动包了,展开可以看到里面有许多的.class字节码文件)

(2)准备好数据库和数据表

        虽然JDBC也能进行建表操作,但一般都是提前创建好的.(👇👇我们往student表进行数据库的操作).

编写代码

(1)创建"数据源"DataSource.

DataSource数据源,告诉要操作的数据库,数据是在哪里.在Mysql中,需要设定好mysql服务器的位置,要去访问数据库的名字,用户名和密码.

DataSource是要能够对接到各种不同的数据库的,提供的是大家都一样的部分.但不同的数据库,设置数据源的方式其实是不一样的.对于mysql是设置url,user,password;对于别的数据库,就不一定了.

在要搭配具体的数据源对象来进行设置.比如SQLite数据库,不是客户端服务器结构的程序,设置数据源的时候,只需要设置一下文件的路径,不涉及url,也没有用户名和密码.

代码如下: 

DataSource dataSource = new MysqlDataSource();//向上转型
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java111?characterEncoding=utf8&useSSL=false");//向下转型,转回来~ 设置url
((MysqlDataSource) dataSource).setUser("root");//设置用户名
((MysqlDataSource) dataSource).setPassword("111");//设置密码

代码解析: 

Java自带的interface,interface是不能new实例的,需要new一个 实现了 这个interface的 class的实例.

MysqlDataSource这个类就来自于mysql的驱动包.

这个过程就是所谓的"数据库厂商写的代码和JDBC进行对接".也就相当于,让数据库厂商,实现JDBC中提供的interface,进一步的实现其中约定好的抽象方法.

//设置URL.

mysql可以手动创建各种名字的用户,默认自带一个root用户(管理员账户,权限最大的账户);数据库没有密码,passwrod就给成"",里面不要加内容就行.

URL是一个非常重要的概念.叫做唯一资源定位符.                 格式:协议的名称://IP地址:端口号/数据库名?参数=值&参数=值..

mysql是一个"客户端-服务器"结构的程序,服务器是保存数据的本体.当前所写的jdbc代码,就是在写一个客户端.(我们所用过的cmd黑框,是mysql自带的客户端).客户端时要通过网络 访问到数据库服务器的,来进一步的进行增删改查.此刻的Url就是描述了服务器/服务器上的资源在网络中所在的位置.

jdbc:mysql  干什么用的url,这里表示给jdbc中的mysql使用的url.

127.0.0.1    IP地址,描述的是一个主机/电脑在网络中的位置.这里表示你本机(自己的电脑).

3306           端口号,区分了主机上的应用程序.mysql默认的端口号是3306.

test_           自定义的数据库名,一定要和mysql创建的数据库名对应一致

userSSL=false  关闭加密通信.(不写的话,默认是开启,有的电脑上对应的依赖程序可能有问题,导致连不上).

serverTimeZone=HongKong 设置时区,MySQL有的版本使用JDBC链接的时候需要设置一下.

(2)和数据库服务器连接(连接对象)

进行 客户端-服务器 之间的通信时,常有两种通信模式:1)有连接 这里的JDBC属于"有连接";2)无连接.

        有连接,类似于打电话.拨号之后,对方接通了才能说话.对方要是挂断了,通信也就断了.

        无连接,类似于发短信/发微信.无论对方是否接收,我都能把数据给发过去.

代码如下:

Connection connection = dataSource.getConnection();

解析:

这个Connection对象就表示"客户端和服务器之间的连接对象".(先拨号)

 对受查异常进行处理.

Connection一定得是java.sql包底下的!

如果一切顺利,连接建立成功,此时就能够得到Connection对象.

但是,在getConnection也很可能失败(服务器没有接收到连接).原因有很多种,包括但不限于:

1) 数据库服务器没有正常启动. 2) url写错了. 3) 用户名写错了. 4) 密码写错了. 5) 网络断开了(网线掉了....)

(3)能够构造一个操作数据库的sql语句(语句对象)

代码:

System.out.println("请输入学号: ");//用户输入
int id = scanner.nextInt();
System.out.println("请输入姓名: ");
String name = scanner.next();
//String sql = "insert into student values (4,'zhaoliu')";//写法1:要先确保数据库名和表名存在.写死了,如果想插入不同的数据要修改代码重新编译
// String sql = "insert into test values(" + id + ", '" + name + "')";//拼接字符串的写法.缺点:影响可读性;可能会引起sql注入攻击
//优化:
String sql = "insert into test values(?, ?)";//用?占位符的写法,需要后续写代码进行内容替换
PreparedStatement preparedStatement = connection.prepareStatement(sql);//推荐,通过PreparedStatement提供的api来完成动态内容的设置~
//JDBC内部会做出校验,避免上述危险操作.(set...有很多这样的方法,看当前是什么类型的数据就使用哪个方法)
preparedStatement.setInt(1, id);//相当于从1开始的下标,对第一个问好进行内容替换.
preparedStatement.setString(2, name);

解析: 

字符串结构的sql,往往还需要构造一个"语句对象".

仅仅表示的是一个普通的语句对象.

则是一个带有"预编译"功能的语句对象.(内部会对sql进行解析校验).

一个字符串sql发送到数据库服务器上,是先对sql进行解析,进行各种校验(判定sql是否符合语法要求等..)才能执行.这个解析操作也是需要花费一定的开销的.虽然开销不是很大,但是mysql服务器要同时给多个客户端提供服务.为了减轻数据库服务器的负担,就可以在客户端这边来完成,此时把解析后的结果发送给服务器,服务器直接执行即可.

(4)执行sql

代码:

//返回值是一个 int 类型, 表示这个操作影响了几行数据.
int n = preparedStatement.executeUpdate();
System.out.println("n = " + n);

解析:

把解析好的语句发送给了数据库服务器了,并且返回了一个int类型的值,表示这个操作影响了几行数据,等价于cmd中的数字👇

update,insert,delete用上面这个(返回int),select用下面这个(返回Reaultset的结果集,是一个临时表).

执行这个方法,就会在内部 给数据库服务器发起请求,请求中就包含了解析后的sql;等待数据库执行sql;过一会 数据库执行完sql之后,返回响应;这个方法再获取到响应,并把数据库返回的结果通过返回值体现出来.

这个程序中可以构造多个sql,并且执行多次的.

(前面的三大步相当于装填炮弹,第四步是发射炮弹~~~)

(5)执行完毕,释放资源

代码:

//主要是释放 语句对象 和 连接对象. DataSource 是不必释放的.
preparedStatement.close();
connection.close();

解析:

需要进行资源释放.释放顺序,先创建的后释放.

        我们知道,C有动态内存管理(malloc申请内存/free释放内存).内存是有限的,用了之后不释放,继续再申请,迟早会把内存耗尽.

而Java有 垃圾回收机制(GC),GC可以自动帮我们回收不用的内存.所以内存这个资源,java是能帮我们自动回收的.但是在编程过程中涉及到的"有限资源",不仅仅是"内存".如果是内存,java可以帮我们自动释放;如果是其他资源,需要程序猿手动释放~~        

 3.完整代码:

JDBC插入数据表记录

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.sql.Statement;
import java.util.Scanner;
public class JDBCDemo {
    public static void main(String[] args) throws SQLException {
        // 接下来通过 JDBC 进行一个简单的 插入数据 的操作.
        // JDBC 代码写起来, 对于初学者来说, 有一点 "繁琐" . (接下来会见到很多新的概念, 新的类, 新的方法).
        // 步骤会比较多. 每个步骤都不难, 都是 "固定讨论"
        Scanner scanner = new Scanner(System.in);
        // 1. 创建 "数据源" (DataSource)
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java111?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource) dataSource).setPassword("111");
        // 2. 和数据库服务器建立连接
        Connection connection = dataSource.getConnection();
        // 3. 能够构造一个操作数据库的 sql 语句.
        System.out.println("请输入学号:");
        Scanner sc1 = new Scanner(System.in);
        int id = sc1.nextInt();
        System.out.println("请输入姓名:");
        Scanner sc2 = new Scanner(System.in);
        String name = sc2.next();
        // String sql = "insert into test values(" + id + ", '" + name + "')";
        String sql = "insert into test values(?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setInt(1, id);
        preparedStatement.setString(2, name);
        // 4. 执行 sql, 把刚才解析好的语句发给数据库服务器了.
        //    返回值是一个 int 类型, 表示这个操作影响了几行数据.
        int n = preparedStatement.executeUpdate();
        System.out.println("n = " + n);
        // 5. 执行完毕, 有收尾操作. 释放前面创建的各种资源.
        //    主要是释放 语句对象 和 连接对象. DataSource 是不必释放的.
        preparedStatement.close();
        connection.close();
    }
}

JDBC查询数据表记录

上述是进行插入数据操作,以下所做的查询操作也大同小异~~不同的是多了一段遍历结果集的代码~ 

代码:

import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class selectMysql {
        //JDBC查询数据表记录
    public static void main(String[] args) throws SQLException {
        //1创建数据源
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/test_?characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("");
        //2建立连接
        Connection connection = dataSource.getConnection();
        //3构造sql
        String sql = "select * from student";
        PreparedStatement statement = connection.prepareStatement(sql);
        //4执行sql
        ResultSet resultSet = statement.executeQuery();//结果集(把它看作一个表格结构的数据) 得到的是一个临时表
        //5遍历结果集
        while(resultSet.next()){
            /*用next()来取出下一行的数据,如果能够取出返回true,如果取不出来到达末尾了则返回false,循环结束
            有一个光标指向结果集的某一行,next()就是在处理移动光标.
            初始情况下,光标指向的是在第一行数据的前一个位置
            进入while循环,首先调用next,光标往后移动一行.看这一行的数据能不能够取出来,能够取出来next返回true,循环继续执行,在循环体里头就可以针对这一行进行操作了.再next...直到next返回false循环结束
            这个循环就是在控制光标往后移动的过程-------->取出每一行*/
            //针对这里的光标指向的行进行处理
            //这里的get也有很多方法,具体情况具体调用~
            //------->取出每一列
            int id = resultSet.getInt("id");//id为列的名字 返回一个int类型的值
            String name = resultSet.getString("name");//name也为列的名字 返回一个String类型的值
            System.out.println("id= "+id+" name= "+name);//取出这一行记录 取出来之后,我们就可以随便对他进行操作了.这里我们进行打印
        }
        //6释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

运行结果: 

 

JDBC修改数据表记录

【修改】和【删除】这里只给出改动的地方,其余的请参照【插入】~

// 3.输入学号和姓名
System.out.println("请输入要修改的学号");
Scanner sc1 = new Scanner(System.in);
int id = sc1.nextInt();
System.out.println("请输入要修改的姓名");
Scanner sc2 = new Scanner(System.in);
String name = sc2.next();
// 4.构造SQL语句完成修改操作
String sql = "update student set name = ? where id = ?";
// jdbc中还需要搭配一个特定的语句对象, 来搭配描述这里的sql情况
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, name);
statement.setInt(2, id);

JDBC删除数据表记录

// 3.输入学号和姓名
System.out.println("请输入要删除的学生的学号");
Scanner sc = new Scanner(System.in);
int id = sc.nextInt();
// 4.构造SQL语句完成删除操作
String sql = "delete from student where id = ?";
// jdbc中还需要搭配一个特定的语句对象, 来搭配描述这里的sql情况
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);

4.常出现的一些问题:

5.结语

        JDBC,是一种用于执行SQL语句的Java API,它是Java中的数据库连接规范.这个API由java.sql.*和javax.sql.*包中的一些类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问.

        在实际开发中,却很少会用到JDBC(麻烦.因为jdbc代码重复性非常高),更多的是使用 MyBatis,MyBatis Plus JPA等封装好的.但是本质上,这些封装好的库/框架,都还是调用的JDBC(底层的实现还是基于JDBC).


寄语 : 不要忘了你希望的远方