✏️作者:银河罐头
📋系列专栏: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规范了所有数据库的编程操作
JDBC的使用
安装
1.先能够安装对应数据库的驱动包(驱动包:数据库厂商提供的具体实现)
像MySQL这样的第三方软件,提供的驱动包,可以去"中央仓库"下载。(中央仓库:类似于手机的应用商店)
https://mvnrepository.com/
去这个网址下载
选的大版本是5.1即可(和你的数据库服务器是对应的)
下载好了之后在文件夹中打开
.jar是一个Java格式的压缩包,类似于.rar .zip一样
.jar里面有很多.class文件
.class文件是.java编译生成的二进制字节码文件
写个程序发布出去,主要是通过.jar的形式
1)在项目创建目录,把刚才的.jar包导入idea
2)右键这个lib目录(目录名字可以随便写)
此时idea就能解析出jar包里的内容
数据库代码
插入操作
3)编写数据库代码
Datasource是jdbc提供的一个接口
JDBC里面的很多关键API都是interface,是由具体的数据库驱动包来提供对应的实现类
为什么这里要先向上转型然后再向下转型?
也可以不做任何转型,直接new MysqlDataSource,就都可以直接用了。
这里看似"多此一举",好处是:
后续代码使用DataSource的实例,避免MysqlDataSource这个名字扩散到代码的各个地方(高内聚),未来要是换数据库,就只用改这一个地方
URL=>唯一资源地址符,也就是"网址",它描述了互联网上的唯一的一个资源的位置
只用复制粘贴就行,不用背
上述数据源的创建操作,只是描述了数据库在哪,并没有真正进行访问,紧接着的"连接操作"才是真正开始通过网络进行通信
不同的数据库,对于数据源的描述是有差异的,有的数据库通过用户名密码来验证,有的不是,比如SQLite
Connection是网络通信中的重要概念,叫做连接(Connection),不叫链接(Link)
网络连接是找个地方记录下,哪个客户端和哪个服务器,即将要进行通信了。
优化,通过技术手段去优化永远是落入下风的,高端的优化是业务上的优化。
每个客户端请求,都是需要小小服务器的系统资源的,(资源包括不限于CPU,内存,硬盘,网络IO带宽资源)。服务器的硬件资源是有限的,
Java的异常分为:
1.受查异常(必须显式处理)
这个显示处理:分为两种
1)try自己把这个异常捕获处理
2)throws 抛异常,交给jvm处理
2.非受查异常(可以忽略)
PreparedStatement背后做了很多事,比如会对SQL语句进行一些预处理(对语法进行解析之类的)
以前通过cmd输入的sql,都是把sql直接发给服务器,让服务器来解析
当连接不再使用时,就需要释放连接,把之前的记录给"擦除掉"
C++在使用内存的时候,都是手动申请,手动释放。
Java是手动申请,自动释放
但是像这种连接资源还是需要手动释放的。
内存泄露不好发现,很多编程语言引入了GC(垃圾回收),Java,Python,Go,PHP,JS …
大大降低内存泄露的概率
语言=>语法规范
C++有语法规范,是C++标准委员会维护的,算是开源的,但是不是代码。
Java也有语法规范,Oracle实现的, 也算是开源的
C++的编译器,gcc,clang,也是开源的,实现了C++的语法规范
Java的jdk开源的,open-jdk也是开源的
Python是开源的,Python这个词既是语法规范,又是解释器实现
jdbc支持两种风格的代码,一个是DriverManager,一个是DataSource
1.DriverManager使用的时候需要借助反射,不推荐
反射不是常规编程手段,是特殊情况下的特殊手段
2.DataSource相比于DriverManager,内置了数据库连接池,可以重复利用连接
字符串常量池、进程池、线程池、内存池、数据库常量池
写死的数据不好,更希望是动态的
不建议用字符串拼接的方式进行SQL的构造,
eg:输入name,这样输:“); drop table xxx”
更靠谱的方式是用PreparedStatement来通过占位符替换的方式,来实现动态SQL的构造
修改和删除代码和插入是一样的
//插入
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();
}
}
查找操作
查找操作相比于插入多了一个步骤,遍历结果集
非常类似于迭代器遍历(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();
}
}