准备工作
JDBC(Java Data Base Connectivity, Java数据库连接)是Java程序和数据库之间的桥梁,包含了一套Java定义的用于执行SQL语句的接口,使开发者能够编写数据库的程序。JDBC 的主要作用是:与数据库建立连接、发送SQL语句和处理数据库执行结果。
创建Maven工程并配置国内镜像
我们先找到我们IDEA的文件所在位置:右键IDEA,点击属性:
点击文件所在位置,找到plugins 文件夹,点击进去:
首先先备份一份setting ,然后再进行修改,然后打开,找到下面的一串代码:
将其替换为下面的代码:
html
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
-->
<!-- 加入如下mirror节点 使用国内阿里云仓库镜像 开始 -->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<mirror>
<id>central</id>
<mirrorOf>*</mirrorOf>
<name>aliyun central</name>
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
<mirror>
<id>spring</id>
<mirrorOf>*</mirrorOf>
<name>aliyun spring</name>
<url>https://maven.aliyun.com/repository/spring</url>
</mirror>
<!-- 加入如下mirror节点 使用国内阿里云仓库镜像 结束-->
</mirrors>
这样我们的 maven 就变成国内的了。
然后配置驱动包:
打开官网https://mvnrepository.com/
再上面的搜索栏输入 mysql :
第一个是最新版本,第二个包含历史版本,我们点第一个即可:
找到你对应的MySQL版本,然后点击进去:
点击下面的红色框内容进行复制
回到你的IDEA,创建Mudule 工程
点击pom.xml 文件下:
然后把你粘贴的内容复制过来:先输入标签头<dependencies><dependencies>
,在他们之间将内容粘贴过去:
如果右上角出现下面这个,点击m 即可:
连接MySQL 并操作
我们在新建好的mudule下找到 java 源代码源文件新建一个类。
DriverManager
DataSource驱动管理类,用于管理JDBC驱动程序,可以从驱动程序中获取数据库连接
java
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false", "root", "123456");
DataSource
DataSource数据源是DriverManager的替代方案,是获取数据库连接的首选方法,推荐使用。
java
//创建MySQL 数据源对象
MysqlDataSource mysqlDataSource = new MysqlDataSource();
//设置数据库连接串
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false");
//用户名
mysqlDataSource.setUser("root");
//密码
mysqlDataSource.setPassword("123456");
区别
DriverManager每次调用getConnection方法都会初始化一个新的连接,使用完成后会关闭真实连接,导致资源浪费。
DataSource使用了连接池 技术,会在初始化时创建⼀定数量的数据库连接,这些连接可以重复使用,关闭时并不是真正关闭连接,而是将连接归还给连接池,以供后续使用,有效地提高资源利用率和和性能
Connection
获得数据库连接
Statement
用于执行静态SQL语句 并返回执行结果,由于只能执行静态语句,所以这里会有一个问题,假设一个语句中需要动态的参数,比如where子句中的条件,那么只能通过字符串拼接的方式组装完成的SQL语句,比如:
java
String sql = "select student_id, sn, name, mail, class_id from student where name = '"+ name + "'";
SQL 注入
由于是静态sql 语句,那么可能会被别有用心的人利用这里面的漏洞,来查询到不应该查到的数据:
这是一个非法的参数,通过这个sql 注入,将所有的用户信息都暴露储出去了,这是十分危险的,所以我们一般不会使用Statement 来进行sql 查询,而是使用下面的 PreparedStatement。
PreparedStatement
预编译SQL语句对象,SQL语句被预编译并存储在PreparedStatement对象中,可以使用该对象多次执行SQL语句,同时可以解决SQL注入问题。
java
String sql = "select student_id, sn, name, mail, class_id from student where name = ?";
使用占位符?来填充未知。
后续将占位符替换为真实数据。
ResultSet
获得sql 查询的结果集。
ResultSet对象维护了一个指向当前数据行的游标,最初游标位于第一行之前,调用next方法将游标移动到下一行,当ResultSet中没有更多的数据行时返回false,所以可以在while循环中使用它来遍历结果集。
ResultSet接口提供了getter方法(getBoolean、getLong等),用于从当前行检索列值,可以使用列的索引号或列的名称来检索值。一般来说,使用列索引会更有效率,索引编号从1开始,按照从左到右的顺序读取。
executeQuery()
用于执行 select 操作
executeUpdate()
执⾏结果返回的是⼀个整形,通常⽤于insert,update,delete操作
关闭资源
最后我们要关闭我们开启的mysql 资源,最后开启的资源最先关闭。
代码演示
java
package org.example;
import java.sql.*;
import java.text.MessageFormat;
import java.util.Scanner;
public class Demo1_DriverManager {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.加载数据库厂商提供的驱动包
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获得数据库连接
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false", "root", "123456");
//3.创建statement 对象
statement = connection.createStatement();
//4. 定义SQL
System.out.println("请输入学生姓名:");
Scanner in = new Scanner(System.in);
//接收用户的输入
String name = in.nextLine();
String sql = "select student_id, sn, name, mail, class_id from student where name = '"+ name + "'";
//5.执行 sql 语句
resultSet = statement.executeQuery(sql);
//6. 对结果集进行遍历,获取数据
// 如果存在下一条记录,会返回true ,否则返回 false
while(resultSet.next()) {
//获得学生信息
long stuId = resultSet.getLong(1);
String stuSn = resultSet.getString(2);
String stuNam = resultSet.getString(3);
String stuMail = resultSet.getString(4);
long claId = resultSet.getLong(5);
//输出结果
System.out.println(MessageFormat.format("学生编号={0}, 学号={1}, 姓名={2}, 邮箱={3}, 班级编号={4}",stuId,
stuSn,stuNam,stuMail,claId));
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//资源关闭
if(resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
java
package org.example;
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;
import java.text.MessageFormat;
import java.util.Scanner;
public class Demo2_DataSource {
public static void main(String[] args) {
//创建MySQL 数据源对象
MysqlDataSource mysqlDataSource = new MysqlDataSource();
//设置数据库连接串
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8" +
"&allowPublicKeyRetrieval=true&useSSL=false");
//用户名
mysqlDataSource.setUser("root");
//密码
mysqlDataSource.setPassword("123456");
//定义JDBC 的数据源对象
DataSource dataSource = mysqlDataSource;
//定义连接对象
Connection connection = null;
//定义预处理SQL对象
PreparedStatement statement = null;
//定义结果集
ResultSet resultSet = null;
try{
//1. 通过数据源进行数据库的连接
connection = dataSource.getConnection();
// 2. 获取预处理SQL执行对象
//定义要执行的SQL
String sql = "select student_id, sn, name, mail, class_id from student where name = ?";
statement = connection.prepareStatement(sql);
//接收用户的输入
System.out.println("请输入学生姓名:");
Scanner in = new Scanner(System.in);
String name = in.nextLine();
//3. 用真实的数据替换占位符
statement.setString(1,name);
// 4. 执行SQL,获取结果集
resultSet = statement.executeQuery();
//遍历结果集
while(resultSet.next()) {
//获得结果集的每一列数据
long stuId = resultSet.getLong("student_id");
String stuSn = resultSet.getString("sn");
String stuNam = resultSet.getString("name");
String stuMail = resultSet.getString("mail");
long claId = resultSet.getLong("class_id");
//输出结果集
System.out.println(MessageFormat.format("学生编号={0}, 学号={1}, 姓名={2}, 邮箱={3}, 班级编号={4}",stuId,
stuSn,stuNam,stuMail,claId));
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//关闭资源
if(resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
在select 语句书写中记得把查询的列写上,就算你是全列查询,也最好写上,因为后续遍历的时候会用到,也方便后续代码的书写
MessageFormat.format 可以格式化我们输出的数据形式。