目录
一、概念
二、Java代码操作MySQL
1、创建一个项目
2、引入MySQL的驱动包,作为项目的依赖
3、把 jar包 导入到项目中
4、创建一个数据源
5、建立网络上的连接
6、构造SQL语句
7、执行 sql 语句
8、释放必要的资源.关闭连接
一个成熟的数据库,一般都会提供一些API,供程序员使用
API : Application programming Interface 应用程序编程接口(广义的概念),可以理解为,你写好了一个程序,这个程序要给别人提供哪些功能,这些功能往往是通过一些 函数 / 类 这样的方式来提供的
interface 也是接口,但是特指 Java 语法中的一种特殊的语法格式(狭义的概念),Java中的interface 也是一种提供API的方式
成熟的数据库,会提供一些成熟的API 让程序员使用(API 就是一些 类 / 方法),不同的数据库,提供的API之间的差异也很大
JDBC 就是 Java 这边提出的一套操作数据库的API,让所有的数据库都能够按照一样的方式来进行操作使用,从此之后,Java程序员只需要掌握一套API,就可以操作各种数据库
把驱动包下载下来,导入到项目中
可以通过下面几种方法下载:
(1) 去 oracle 官方网站
(2) 去 github
(3) 中央仓库
这里,我选择的是在中央仓库下载:https://mvnrepository.com/
在打开网页后,在搜索栏中输入MySQL进行查找
进去之后,可以看到很多版本,此处数据库驱动包的版本要和数据库服务器的版本一致(小版本不要求,大版本得一致)
然后找到自己所需要下载的版本,这里我选择的是5.1.49的版本
选择好版本之后,点击图中圈起来的地方就可以触发下载
.jar 是类似于 .rar 这样的压缩包,是Java定义的一种压缩格式, .jar 中主要是包含了很多的 .class文件,jar包是Java发布程序的一种典型方式
首先在项目中创建一个目录
(1) 复制 jar 包到项目的目录中,这个目录手动创建一个即可
(2)右键这个jar 包的目录
点了这里之后,idea 就知道了,这个目录里是库文件(jar 包),一般来说,点击 ok 就成功了
此时,准备工作完成了,接下来就可以编写代码了
数据源 指的是数据库服务器在哪里
这个代码也是一个非常常见的向上转型的操作 此时,向下转型又转回来了,目的是为了使用这个 setUrl 方法,这个方法是子类才有的
当然直接这样写也是可以的:
但是,按照上述转型的写法,本意是希望,让" MysqlDataSourse" 这个类,不要扩散到代码的其它部分(目的是想降低MySQL驱动包,和咱们项目代码之间的耦合关系,避免后续更换数据库的时候有更大的成本)
但是,实际上,我们目前的代码比较简单,也不太涉及到耦合的事情,此时转型或者直接写都是可以的
那么什么是 URL 呢?
URL 唯一资源定位符. 通常使用 URL 来描述网络上一个资源的位置
而 MySQL 的本体是服务器,也就相当于网络上的资源,因此我们使用URL是 OK 的
这里的URL具体是怎么写的不需要背,用到的时候复制粘贴即可
设置了URL之后,还需要设置用户名和密码
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("123456");
用户名,大家都是 root,密码是安装数据库的时候设置的密码
到这里,我们只是描述了一下数据库服务器所在的地址,还没有真正链接数据库服务器
//1、创建一个"数据源"
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java_code?characterEncoding=utf8&useSSL=false");
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("123456");
注意,这里只能使用方框中的Connection!!!
这时,会出现一个红色的波浪线
这个是 jdbc 中提供的受查异常
这个操作时非常容易出异常的,进行链接的时候有很多很多的原因,会导致链接不上
此时,只需要 throws 一下即可
那么这里的Connection 是什么意思呢?
一个Java程序,可以连多个数据库服务器,和每个数据库服务器进行同学都得有一个独立的连接,类似于微信里的多个通话
//2.和数据库服务器建立连接
Connection connection = dataSource.getConnection();
本身我们的 SQL 语句,是String类型的
JDBC提供了 Statement 对象,让我们把String 转换成 Statement 再发给服务器执行
但是,一般会使用PreparedStatement(预处理的语句)对象来代替Statement
Statement 是把 Sql 原封不动的直接发给数据库服务器,数据库服务器自己负责解析SQL
preparedStatement 会先在客户端这边初步解析一下SQL(验证语法格式是否符合要求之类的)
//3、构造 SQL 语句
String sql = "insert into student values(1,'张三')";
PreparedStatement statement = connection.prepareStatement(sql);
executeUpdate适用于插入、修改、删除(本质都是 “写” 操作)
返回值就是这次的操作,影响到了几行
//4、执行Sql语句
int n = statement.executeUpdate();
System.out.println("n = " + n);
创建的语句对象和连接对象,都会有一些计算机的 硬件 / 软件 上的资源
这些资源不用了就应该要及时释放
Java中,虽然有“垃圾回收”机制,自动释放资源,但是计算机的资源不仅仅是内存资源,其它的资源就需要手动释放
一般是会提供 close 方法,专门释放资源的方法
//5、释放必要的资源.关闭连接
statement.close();
connection.close();
释放资源的时候,要注意关闭顺序
先创建的对象后关闭,后创建的对象先关闭
此时,就完成了数据库的插入数据
但是还有一个问题,当前我们插入的数据内容,是写死的
我们更希望插入的数据能够在运行时动态的变化
1、这个写法看起来比较混乱
2、这种拼接字符串的方式并不安全
PreparedStatement 就给我们提供了 基于占位符 的写法,更优雅、更安全的解决上述问题
这里的 ? 是一个占位符,占据一个位置,后续PreparedStatement 会把变量的数值,带入到 ? 中
当前要设置的数据类型是啥,使用的方法名字就是啥
这样的写法,代码上更加简单明了,执行过程中,setXXX 内部也会进行严格的校验,避免出现SQL注入攻击的情况
此时,也能插入成功
删除操作和修改操作,与上面的操作,几乎完全一样,只不过构造的SQL不一样
插入、删除、修改,返回值都是一个简单的整数
但是对于查询来说,返回值是一个“临时表”
想象表格中有一个“光标”
这个光标初始情况下,指向第一行记录的前一个位置
每次调用 next ,就会让光标往下走一行
如果光标往下走成功了,就会返回 true ,进入循环
在循环体中,就可以取出这一行的每一列
取完这一行后,下次又要调用next
当光标取完了最后一行,再次指向 next ,此时就会返回 false,循环结束
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCDemo2 {
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";
PreparedStatement statement = connection.prepareStatement(sql);
//执行查询结果,要使用 executeQuery.返回值是一个ResultSet类型的对象,表示了一个"表格"
ResultSet resultSet = statement.executeQuery();
//遍历结果集合
while(resultSet.next()){
//获取到这一行的学号列
int id = resultSet.getInt("id");
//获取这一行的姓名列
String name = resultSet.getString("name");
System.out.println("id: "+ id + ",name: " + name);
}
//释放资源
resultSet.close();
statement.close();
connection.close();
}
}