- JDBC背景知识:
- JDBC的使用
- 1:驱动包的下载
- 2:驱动包引入
- 3;代码实现
- 1:创建数据源
- 2:和数据库创建网络连接
- 3:构造sql语句
- 4:执行sql
- 5:释放资源
- sql语句的构建细节
- 查找操作:
JDBC背景知识:
实际开发;sql大多是通过代码控制执行的。用这里方式代替我们的小黑框执行。JDBC只支持标准的sql关系型数据库,redis是非关系型nosql数据库,不支持sql,也不支持jdbc。这部分的操作并不复杂;只是一下引入很多复杂的接口和方法等;而我们日常学习也比较少运用这些;就需要我们反复的连续。
mysql客户端/服务器:客户端是比较容易实现;数据库提供;很多API可以让我们比较方便的实现这个客户端;只需要实现调用这些接口、方法;而实现一个数据库服务器是非常难的;
API的概念:以类或方法提供给人用的就可以叫api;就是把底层东西进行封装;比如:。
mysql的API:C语言风格的;因为使用广泛;所以诞生有很多个语言的版本;但是其它版本本质上还是在调用C的API(跨语言调用)。
mysql有都个版本;Oradcle、SQLServer、SQLite等数据库也有API;这些都各不相同;所以我们的学习成本就高了很多。
JDBC的诞生:java做了一件很伟大的事情;把这些API进行统一;JDBC就诞生;我们只需要学习这套API就能使用这些不同的数据库。java:你这些数据库想要给我们使用;你就得为我们提供能适应JDBC的驱动包;jdbc约定好api,但是api具体实现还是得看这些厂家怎么实现(驱动包)…
JDBC的使用
1:驱动包的下载
(mysql官网下载驱动包;但是很难找,还要登录注册,密码又得要很复杂。也可以去中央仓库)
选择5.多版本;.jar是一个java格式压缩包;里面有很多.class文件;写个出现发布出去;主要是通过.jar形式。
2:驱动包引入
把jar拷贝,在项目下新建一个目录,目录名随便取(一般是lib)拷贝在这个目录的lib里
意思是把这个目录当做库使用;这时候就添加进去了,idea自动解析jar里面的内容
3;代码实现
数据库连接Connection:Connection接口实现类由数据库驱动提供,获取Connection对象通常有两种方式。
DataSource和DriverManager
DriverManager需要借助反射;这种不是常规编程手段;特殊情况时特殊手段;大众是比较不熟悉的
DriverManager类来获取的Connection连接,是无法重复利用的,每次使用完以后释放资源
时,通过connection.close()都是关闭物理连接。
// 加载JDBC驱动程序
Class.forName("com.mysql.jdbc.Driver");
// 创建数据库连接
Connection connection = DriverManager.getConnection(url)
一种是通过DataSource(数据源)对象获取; DataSource内置数据量连接池;可以重复利用连接(Datasource获取的数据库连接不用关闭物理连接,只重置,重新初始化后又放回连接池)连接复用:可以复用连接池初始化的连接,可以避免频繁的创建和释放连接引起的大量性能开销。随时可以拿出来用。(连接池在初始化时将创建一定数量的数据库连接,这些连接是可以复用的,每次使用完数据库连接,释放资源调用connection.close()都是将Conncetion连接对象回收。)
MysqlDataSource mysqlDataSource=new MysqlDataSource();mysqlDataSource.setURL("jdbc:mysql//127.0.0.1:3306/liao/chat?characterEncoding=utf8&useSSL=false");mysqlDataSource.setUser("root");mysqlDataSource.setPassword("111111");Connection connection= (Connection) mysqlDataSource.getConnection();
//为什么这里还需要强转Connection类型;返回的是mysql这里获取的子类型;这里的源码还不好看;jar包里不是源代码;只有.class文件;得去mysql官网看开源代码;其实我们只需要知道怎么获取就可以了。
1:创建数据源
第一步:创建数据源;用来来描述数据库在哪.
DataSource:java标准库提供的jdbc接口;可以看作数据源,它封装了数据库参数,连接数据库,程序中操作DataSource对象即可对数据库进行增删改查操作。
MySQLDataSource:我们下载驱动包中的一个实现DataSource接口的类.(驱动包的实现类,sqlserver数据库有sqlserverDataSource等)
DataSource dataSource=new MysqlDataSource();// 向上转型;父类型new的子类实例;可以调用父类特有方法;调用重写方法时是执行子类的。//注意:这里如果不作任何的向上转型也行;直接使用 MysqlDataSource mysqlDataSource =new MysqlDataSource();也是可以直接使用。//但是这里使用向上转型可以避免MysqlDataSource到处扩散;我们使用的就是DataSource;未来换数据库只需要改动这一个代码即可
java很多API都是interface;需要数据库驱动包提供具体的实现类
第二歩:设置数据库的 位置(URL), 登录数据库的用户名和密码.
“jdbc:mysql://127.0.0.1:3306/liao?characterEncoding=utf8&useSSL=false”
URL的每一部分:
当前我们数据库是本机下;这里就是环回ip地址。127.0.0.1:3306。,
我们数据库当时默认是这个端口号。liao是我们的数据库名。
?characterEncoding=utf8设置字符集;得保证你创建的数据库是utf8编码。
useSSL=false关闭加密功能;咱没必要加密手动关闭;避免出现其它不必要的问题。
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/liao?characterEncoding=utf8&useSSL=false");//但是这里又为什么要向下转型呢;那这样子如果换数据库不是还得改代码吗//光有数据库还不够,得要用户名和密码((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("");
2:和数据库创建网络连接
刚才的数据源创建操作;只是描述服务器在哪;还没有真正进行访问;这歩的连接操作才是真正的开始通过网络进行通信。
//2: 建立连接Connection connection= (Connection) dataSource.getConnection();
这里需要抛异常;java异常分两类;1)受查异常;必须要显式处理 2)非受查异常;可以忽略。try自己把异常捕获处理;throws交给别人处理;交给jvm处理,遇到异常jvm就停止执行
3:构造sql语句
Statement对象:将SQL语句发送到数据库中。JDBC API中主要提供了三种Statement对象。
Statement:用于执行不带参数的sql语句
PreparedStatement:用于执行带参或不带参;sql语句会预编译在数据库系统;执行速度比Statement;用的多。
CallableStatement:用于执行数据库储存过程的调用
准备过程;描述sql语句是什么样的;还没真正开始执行。
//3.构造sql语句;String sql = "insert into student values(1, 张三)";//获取连接后;利用这个连接把调用这个方法;把sql进行准备过程PreparedStatement statement=connection.prepareStatement(sql);
PreparedStatement背后做很多事情;预处理;解析等
4:执行sql
两种执行方法:
executeQuery() 方法执行后返回单个结果集的,通常用于select语句
executeUpdate()方法返回值是一个整数,指示受影响的行数,通常用于update、insert、delete
语句
//4: 执行;返回的结果是这个操作影响几行数据int ret=statement.executeUpdate();
5:释放资源
虽然java使用手动申请;自动释放。但是这种连接资源还是得释放的。不然你再创建连接又要浪费一份空间;也避免内存泄漏;释放的顺序得要和创建的顺序相反。比如:我回家;先家门;然后开房门;我要出门时;我得先关房门;然后再关家门。
//5:断开连接statement.close();connection.close();
成功了;这里张三得加字符串;这里完完全全得是sql的语句写法。
sql语句的构建细节
对于刚才的sql语句构建;我们更希望插入的数据是动态的。所以这里代码修改一下。达到我们能手动在键盘是输入sql语句的效果。你得构建出sql语句的字符串;包括符合等也是需要需要搞成字符拼接上去;你要拼接出sql语句的字符串就可以了。
这样代替后;功能变强了;但是又引入新的问题;代码不容易阅读、容易引起sql注入攻击。
sql注入攻击:我的提示让你好好的输入姓名和学号;但是一有些小子;输入");drio table XXX…… 这样子输入,直接改变了你sql的结尾位置 ")读到这里结束,然后再读drop table就不是字符串你们简单了,而是执行操作了。
解决方案:使用PreareedStatament来通过占位符替换方式;实现sql的动态构造
其它的增加;删除修改只需要改变一下sql语句即可
查找操作:
相较于增删改多了个步骤;遍历结果集;就是你查东西;总得要显示出来吧;比如:我让chatgpt查询蔡徐坤多少岁;chatgpt执行这个操作;它得给我显示出这个结果。类似于迭代器的遍历;最后释放资源也是和创建时的顺序相反。
ResultSet对象:ResultSet对象它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法提供
了对这些行中数据的访问。
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Scanner;public class test1 {public static void main(String[] args) throws SQLException {//1:创建数据源;第一歩DataSource dataSource=new MysqlDataSource();//第二歩((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/liao?characterEncoding=utf8&useSSL=false");//但是这里又为什么要向下转型呢;那这样子如果换数据库不是还得改代码吗;向下转型能访问子类特有方法.先留疑?//光有数据库还不够,得要用户名和密码((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("111111");//2: 建立连接Connection connection= (Connection) dataSource.getConnection();//3.构造sql语句;String sql = "select * from student where id = 1";PreparedStatement statement=connection.prepareStatement(sql);//4: 结果集合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);}//5:断开连接resultSet.close();statement.close();connection.close();}
}