当前位置: 首页 > news >正文

MySQL JDBC编程

✏️作者:银河罐头
📋系列专栏:MySQL

🌲“种一棵树最好的时间是十年前,其次是现在”

文章目录

  • 前置知识
    • API
  • JDBC的使用
    • 安装
    • 数据库代码
      • 插入操作
      • 查找操作

前置知识

API

API(Application Program Interface)被定义为应用程序可用以与计算机操作系统交换信息和命令的标准集。

你拿到个东西能给你提供哪些功能/服务

实现客户端比较简单,各种数据库本身就提供了一系列API,可以让我们比较方便的实现这个客户端。

实现服务器很难,存储引擎,使用什么样的数据结构去组织数据;SQL执行引擎,基于编译原理的知识,能够对SQL进行解析和优化。

(之前学JavaSE看过API文档,Java的标准库会给我们提供一些API,有随机数、scanner、集合类等一组类/方法)

操作系统,也会提供一些API,比如操作硬盘的文件,访问一下硬盘的内容,重置一下网卡的状态,

包括模拟鼠标事件,模拟键盘事件…

也是以类/方法提供给我们的

数据库(MySQL)也会提供一组API,通过这组API可以对数据库完成增删改查的操作

Windows API(模拟鼠标点击的API就在这里)

C标准库的API

#include <stdio.h>

scanf,printf,fopen,fclose…

MySQL也提供了很多API,MySQL的API是为了让我们实现客户端的。

MySQL本来的API是C语言风格的,但考虑到MySQL使用非常广泛,也提供了其他多个语言的API,其他版本的API本质上还是调用C的API(跨语言调用)

像Oracle,SQLServer,SQLite等这些数据库的API不一样。

基层程序员学数据库编程,就得学好几套API,极大的提高了学习的成本

Java圈子里JDBC站出来了,JDBC这套API已经成为Java标准库的一部分。由于Java影响力很大,以自身作为标准,此时各种数据库厂商都提供了能够适应JDBC相关的"驱动包"。这个驱动包相当于API的具体实现。API约定了API有啥/咋用的

此时,只用掌握这套API,无论操作哪个数据库,操作的代码基本相同。

JDBC屏蔽了不同数据库原生API之间的差异,使用同一套API规范了所有数据库的编程操作

image-20221117164055275

JDBC的使用

安装

1.先能够安装对应数据库的驱动包(驱动包:数据库厂商提供的具体实现)

像MySQL这样的第三方软件,提供的驱动包,可以去"中央仓库"下载。(中央仓库:类似于手机的应用商店)

https://mvnrepository.com/
去这个网址下载

image-20221117165557298

选的大版本是5.1即可(和你的数据库服务器是对应的)

image-20221117165836649

下载好了之后在文件夹中打开

.jar是一个Java格式的压缩包,类似于.rar .zip一样

.jar里面有很多.class文件

.class文件是.java编译生成的二进制字节码文件

写个程序发布出去,主要是通过.jar的形式

1)在项目创建目录,把刚才的.jar包导入idea

2)右键这个lib目录(目录名字可以随便写)

此时idea就能解析出jar包里的内容

数据库代码

插入操作

3)编写数据库代码

image-20221117185319278

Datasource是jdbc提供的一个接口

JDBC里面的很多关键API都是interface,是由具体的数据库驱动包来提供对应的实现类

image-20221117185805352

image-20221117190222749

为什么这里要先向上转型然后再向下转型?

image-20221117190334883

也可以不做任何转型,直接new MysqlDataSource,就都可以直接用了。

这里看似"多此一举",好处是:

后续代码使用DataSource的实例,避免MysqlDataSource这个名字扩散到代码的各个地方(高内聚),未来要是换数据库,就只用改这一个地方

URL=>唯一资源地址符,也就是"网址",它描述了互联网上的唯一的一个资源的位置

image-20221117192305093

只用复制粘贴就行,不用背

image-20221117193936890

image-20221117194548635

上述数据源的创建操作,只是描述了数据库在哪,并没有真正进行访问,紧接着的"连接操作"才是真正开始通过网络进行通信

不同的数据库,对于数据源的描述是有差异的,有的数据库通过用户名密码来验证,有的不是,比如SQLite

image-20221117195736532

Connection是网络通信中的重要概念,叫做连接(Connection),不叫链接(Link)

网络连接是找个地方记录下,哪个客户端和哪个服务器,即将要进行通信了。

优化,通过技术手段去优化永远是落入下风的,高端的优化是业务上的优化。

每个客户端请求,都是需要小小服务器的系统资源的,(资源包括不限于CPU,内存,硬盘,网络IO带宽资源)。服务器的硬件资源是有限的,

Java的异常分为:

1.受查异常(必须显式处理)

这个显示处理:分为两种

1)try自己把这个异常捕获处理

2)throws 抛异常,交给jvm处理

2.非受查异常(可以忽略)

image-20221117203104553

image-20221117203227535

image-20221117205130028

PreparedStatement背后做了很多事,比如会对SQL语句进行一些预处理(对语法进行解析之类的)

以前通过cmd输入的sql,都是把sql直接发给服务器,让服务器来解析

image-20221117205118417

当连接不再使用时,就需要释放连接,把之前的记录给"擦除掉"

C++在使用内存的时候,都是手动申请,手动释放。

Java是手动申请,自动释放

但是像这种连接资源还是需要手动释放的。

内存泄露不好发现,很多编程语言引入了GC(垃圾回收),Java,Python,Go,PHP,JS …

大大降低内存泄露的概率

语言=>语法规范

C++有语法规范,是C++标准委员会维护的,算是开源的,但是不是代码。

Java也有语法规范,Oracle实现的, 也算是开源的

C++的编译器,gcc,clang,也是开源的,实现了C++的语法规范

Java的jdk开源的,open-jdk也是开源的

Python是开源的,Python这个词既是语法规范,又是解释器实现

image-20221117212319492

jdbc支持两种风格的代码,一个是DriverManager,一个是DataSource

1.DriverManager使用的时候需要借助反射,不推荐

反射不是常规编程手段,是特殊情况下的特殊手段

2.DataSource相比于DriverManager,内置了数据库连接池,可以重复利用连接

字符串常量池、进程池、线程池、内存池、数据库常量池

image-20221117213757510

image-20221117213836228

写死的数据不好,更希望是动态的

image-20221117214604206

不建议用字符串拼接的方式进行SQL的构造,

eg:输入name,这样输:“); drop table xxx”

更靠谱的方式是用PreparedStatement来通过占位符替换的方式,来实现动态SQL的构造

image-20221117215439955

image-20221117215834174

修改和删除代码和插入是一样的

//插入
public class JDBCInsertDemo {
    public static void main(String[] args) throws SQLException {
        //使用jdbc往数据库中,插入一条记录
        //需要提前准备好数据库(java),数据表(student)
        //1.创建一个数据源
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");

        //MysqlDataSource mysqlDataSource=new MysqlDataSource();
        //mysqlDataSource.setUrl();
        //2.和数据库建立网络连接。(写的jdbc代码本质上是实现一个mysql客户端,通过网络和服务器进行通信)
        Connection connection=dataSource.getConnection();

        //通过控制台输入用户的信息
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入学号: ");
        int id = scanner.nextInt();
        System.out.println("请输入姓名: ");
        String name = scanner.next();
        //3.构造一个sql语句,来完成插入操作
        //String sql = "insert into student values("+ id +",'"+ name +"')";
        String sql="insert into student values(?,?)";
        //jdbc中还需要搭配一个特定的对象,来描述这里sql的情况
        PreparedStatement statement=connection.prepareStatement(sql);
        statement.setInt(1,id);
        statement.setString(2,name);
        System.out.println("sql: " + statement);
        //4.执行sql语句。(控制客户端给服务器发送请求)
        //针对增,删,改,是用executeUpdate来执行
        //针对查,是用executeQuery来执行
        //执行就是给服务器发送网络请求
        //返回结果的含义是,这个操作影响到几行
        int ret = statement.executeUpdate();
        System.out.println("ret = " + ret);
        //5.断开和数据库的连接,并且释放必要的资源
        statement.close();
        connection.close();
    }
}

查找操作

查找操作相比于插入多了一个步骤,遍历结果集

image-20221118095047594

image-20221118095104196

非常类似于迭代器遍历(hasNext());

这里的next(),既是向下移动光标,又是判断下面一行是否有数据

1: 张三
1: 张三
2: 李四
3: 王五

如果是加限制条件,只用修改sql语句

String sql = "select * from student where id = 1";

命令行属于,官方自带的,通用的交互式的客户端

写代码则是让java程序快速的,重复多次的,执行一些相对固定的sql

写代码,也是实现一个客户端,不过这是一个通用的客户端

JDBC实际工作上中,可能不会直接用,因为JDBC代码写起来有点麻烦。

因此就有了一些库和框架,就对JDBC做了进一步的封装,让我们用起来更方便,

Mybatis,或者JPA这种,让我们写起来非常方便

但是学习JDBC还是有非常大意义的,框架一直在变更,JDBC是恒定的,框架也都是基于JDBC的, 如果你发现现有的框架,难以满足你的需求,就可以基于JDBC进行魔改和自定义

public class JDBCSelectDemo {
    public static void main(String[] args) throws SQLException {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("123456");
        Connection connection = dataSource.getConnection();
        String sql = "select * from student where id = 1";
        PreparedStatement statement = connection.prepareStatement(sql);
        //结果集合
        ResultSet resultSet = statement.executeQuery();
        while(resultSet.next()){
            //next 相当于移动一下光标,光标指向下一行,然后移动到末尾,返回false
            //使用getXX方法获取到每一列
            //获取Int,就使用getInt();获取String,就使用getString()
            //这里的参数就是数据库表的列名
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            System.out.println(id + ": " + name);
        }
        //释放资源
        resultSet.close();
        statement.close();
        connection.close();

    }
}

相关文章:

  • 计算机基础学习(好文必看)
  • Python冷知识:如何找出新版本增加或删除了哪些标准库?
  • JAVA初阶——继承和多态
  • python学习思路
  • MySQL纯代码复习(上)
  • 牛客刷题记录(常见笔试题)
  • 次元裂缝已打开,AI绘画突飞猛进,其潜力究竟有多大
  • 基于DJYOS的UART驱动编写指导手册
  • i++的错误使用
  • 这次把怎么做好一个PPT讲清-总体篇
  • web前端-第三次作业-按钮
  • 分享一个单片机GUI库,简洁,使用
  • 数据结构体进阶链表【带头双向循环链表,单向链表的优化,从根部解决了顺序表的缺点】一文带你深入理解链表
  • 【数据结构】栈和队列
  • 硬核Vue3响应式原理解析,为你保驾护航渡过寒冬
  • 轻松掌握 jQuery 基础
  • Python每日一练 03
  • 【计算机毕业设计】Springboot医疗管理系统源码
  • 【2022硬件设计开源盛宴】一年一度的hackaday大赛结束,冠军便携式风力涡轮机,共提交326个电子作品,奖金池15万美元
  • 基于51单片机的智能路灯控制系统proteus仿真原理图PCB