数据库圣经-----最终章JDBC

数据库圣经-----最终章JDBC

1.什么是JDBC

JDBC(Java Data Base Connectivity,Java数据库连接)是Java程序和数据库之间的桥梁,包含了⼀套Java定义的用于执行SQL语句的接口,使开发者能够编写数据库的程序。JDBC的主要作用是: 与数据库建立连接、发送SQL语句和处理数据库执行结果。

1、JDBC的应用场景

如果JAVA要访问不同的数据库,那么就需要根据数据库的协议进行代码的开发, 为了解决不同数据的使用场景,JAVA中只定义了用于连接和操作数据的接口--JDBC具体的实现由数据库厂商来完成

2、JDBC工作原理

JDBC工作原理简洁地概括为:加载驱动、建立连接、创建Statement、执行SQL、处理结果和关闭资源。

2.为什么要使用JDBC• 首先回顾⼀下使用客户端操作数据库的过程,主要分为以下几步:

数据源:确认数据库的服务器的地址和端口号 数据库连接:连接到数据库服务,不同的数据库以哪种协议建立连接执行对象:发送SQL语句,以什么样的形式发送,这里注意考虑编码的格式(协议)结果集:接受返回结果并显示(结果集,受影响行数) 以哪种协议解析的结果释放资源关闭连接:关闭连接对于JAVA程序员来说,肯定要处理不同数据库之间对数据的编解码,但只需要调用JDBC定义的方法就可完成数据库的具体操作:

• 同样如果使用程序操作数据库也会经历以上几步,⼤家应该可以想到,为实现上述步骤,可以编写相应的代码实现数据库连接,发送SQL语句,处理结果并显示,最后关闭连接。

• 但是不同的数据库对于同⼀个操作不论是协议还是参数都各有不同,如果让程序员自己去实现,那就必须针对不同的数据库进行编码实现,这个工作量和维护成本显然太大。

• Java采取的做法是把以上操作步骤定义了相应的接口,具体的实现交给数据库厂商去做,Java程序员只需要按照需要调用接口中定义的方法即可,这样不论使用什么数据库,都对于Java程序没有任何影响,即便是换⼀个数据库,也只需要换⼀下相应厂商的实现依赖。

简单来说,JDBC 是Java平台的一个接口,通过这五步骤,脱离数据库操作数据库,数据库厂商提供了具体的实现类,下面就是一些不同的实现

Java的就是第三个,Connector/J

• JDBC使用过程可以概括为:加载数据库厂商的驱动包、建立连接、创建Statement、执行SQL、 处理结果释放资源和关闭连接。

3.使用JDBC1.在设置里检查自己的maven 是idea 内置的maven还是镜像的

maven 类似与应用商店,Java把用到的依赖放到maven 这个‘应用商店’里,maven 维护了Java工程需要用的依赖,这个默认仓库是国外的,需要把他修改成国内的。

1.修改maven 的配置,找到idea 的安装路径点击进去plugins ,里面找到maven

点击进去,再点击meavn3,到达这个路径

点击 conf ,找到settings.xml,这个就是我们修改的配置文件

打开,找到mirror 这个节点

把这个替换了,修改之前最好就是备份一下要不然就用不了了

代码语言:javascript复制

aliyunmaven

*

阿里云公共仓库

https://maven.aliyun.com/repository/public

central

*

aliyun central

https://maven.aliyun.com/repository/central

spring

*

aliyun spring

https://maven.aliyun.com/repository/spring

创建idea项目,然后双击点击src ,创建一个新的模块

advanced setting :

这是 Maven 项目中的坐标配置项,用于唯一标识项目或依赖:

GroupId:组织 / 公司的唯一标识,通常是域名倒写(如 org.example),用来区分不同组织的项目。ArtifactId:项目或模块的具体名称,在同一个 GroupId 下唯一,代表项目本身或其中的某个模块。2.创建一个maven 工程3 获取MySQL驱动包(jar)• 在Maven仓库https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.33搜索MySQL,找到最新版的驱动包

在Maven仓库mvnrepository.com搜索MySQL,找到最新版的驱动包

第一个是最新的jar包,第二个是历史版本的jar包 ,去找我们的版本

代码语言:javascript复制

mysql

mysql-connector-java

8.0.33

4.修改pom.xml文件在pom.xml文件,在节点中安装依赖

代码语言:javascript复制

mysql

mysql-connector-java

8.0.33

完事后点击右上角的刷新

如果说这里的出现了8.0.33也就是刚才在pom.xml 中添加的依赖,也说明已经加载到工程中了

5. 建立数据库连接1.• 使用驱动管理类 DriverManager 的静态方法获取数据库连接代码语言:javascript复制// 加载数据库厂商提供的驱动

Class.forName("com.mysql.cj.jdbc.Driver");

// 获取数据库连接

Connection connection =

DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jobs_info_db?characterEncoding" +

"=utf8&allowPublicKeyRetrieval=true&useSSL=false",

"root",

"123456");1.注册数据库厂家提供的驱动,通过完全限定名加载指定的类到JVM下,如下Surround with try/catch:用 try/catch 包围这是点击forName的使用规范

2.数据库的连接1.导入 代码片段,复制URL代码语言:javascript复制connection = java.sql.DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc?characterEncoding=utf8" +

"&allowPublicKeyRetrieval=true&useSSL=false", "root", "123456");jdbc:mysql://:固定协议前缀,标识这是 MySQL 数据库的 JDBC 连接。127.0.0.1:数据库服务器的 IP 地址,127.0.0.1 表示本地服务器(也可写 localhost)。3306:MySQL 数据库的默认端口号,若未修改过数据库端口,保持此值即可。java01:要连接的具体数据库名称,需提前在 MySQL 中创建该数据库。? 后的参数:连接的附加配置,用于解决编码、安全等问题 characterEncoding=utf8:指定字符编码为 UTF-8,避免中文数据存储或查询时出现乱码。allowPublicKeyRetrieval=true:允许客户端从服务器获取公钥(MySQL 8.0+ 版本连接时的常见配置,解决公钥检索相关的连接问题)。useSSL=false:关闭 SSL 加密连接(开发环境常用,生产环境可根据安全需求开启)。注意:这里DriverManager 应该是Java.sql 的

还报错,这里还要在抛一个异常,就不会报错了

2.在补上输入账号和密码3.创建Statement对象,用来执行sql 的语句

代码语言:javascript复制 // 通过connection获取statement对象

Statement statement = connection.createStatement();4.定义并执行sql语句代码语言:javascript复制String sql = "select student_id, sn, name, mail, class_id from student where name = '" + name + "'";但是name 我们没有定义,我们就要自己输入读取完再查找,这个名字的信息(sql 的;可加可不加)

代码语言:javascript复制System.out.println("请输入学生姓名:");

Scanner scanner = new Scanner(System.in);

// 接收用户的输入

String name = scanner.next();

String sql = "select student_id, sn, name, mail, class_id from student where name = '" + name + "'";5.执行语句代码语言:javascript复制// 5. 执行SQL,获取查询结果

statement.executeQuery(sql);

//执行语句

statement.executeUpdate(sql);

//执行insert, delete , update语句 sstatement.executeQuery(sql);专门用于执行 查询语句(如 SELECT),执行后会返回一个 ResultSet 对象,用于封装查询结果集(可以通过遍历 ResultSet 来获取每一条数据)

statement.executeUpdate(sql);专门用于执行数据操作语句(DML) 或数据定义语句(DDL):

执行 DML(增删改)时,返回受影响的行数(如插入 3 条数据返回 3)。执行 DDL(如创建表、删除表)时,返回 0(因为 DDL 不涉及行数影响)实际开发中:

executeQuery()(专门执行查询,直接返回 ResultSet)

executeUpdate()(专门执行增删改 / DDL)

6.获取查询结果

代码语言:javascript复制ResultSet resultSet = statement.executeQuery(sql);7.对结果集进行遍历

代码语言:javascript复制while (resultSet.next()) {

}代码语言:javascript复制 while (resultSet.next()) {

// 获取学生Id

long stuId = resultSet.getLong(1);

//bigint 就是long 都是8字节

String stuSn = resultSet.getString(2);

String stuName = resultSet.getString(3);

String stuMail = resultSet.getString(4);

long classId = resultSet.getLong(5);

System.out.println(MessageFormat.format("学生编号={0}, 学号={1}, 学生姓名={2}, 邮箱={3}, 班级编号={4}", stuId, stuSn,stuName, stuMail, classId));

}5.关闭连接因为作用域的原因,我们把前面的resultSet Connection和Statement 都从try提出来

预编译语句(如 PreparedStatement)是防止 SQL 注入的重要手段,它能将 SQL 语句的结构和数据分开处理,避免恶意输入被解析为 SQL 命令执行。而未使用预编译时,攻击者可能通过构造特殊输入(如你提到的去除空格、插入注释符等)来篡改 SQL 语句的逻辑,从而非法获取、修改或删除数据库信息。

每次获取的都是getConnection 都是一次物理连接,也就是每次执行语句都会打开这个界面,但是我们正常的登录mysql 是打开一次命令行,然后执行语句 DataSource一次连接可以执行多次,直到这个连接被关闭,也就是关闭这个数据源

2.• 通过数据源 DataSource 对象获取,推荐在实际开发中应用这种方式一个连接可以执行多次SQL,直到关闭数据源

通过一个连接池去管理很多个连接,当需要SQL执行的时候,从连接池里拿一个空间连接出来,用完后返还给连接池。

代码语言:javascript复制//设置数据源的连接串、⽤⼾名和密码

MysqlDataSource mysqlDataSource = new MysqlDataSource();

mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/jobs_info_db?

characterEncoding" +

"=utf8&allowPublicKeyRetrieval=true&useSSL=false");

mysqlDataSource.setUser("root");

mysqlDataSource.setPassword("123456");

// 把mysqlDataSource 转换为JDBC的dataSource DataSource dataSource = mysqlDataSource;MySQL数据库连接URL格式: jdbc:mysql:// 服务器地址 : 端口 / 数据库 ? 参数名 = 值 [& 参数名 = 值...]

数据源(DataSource) 是一个抽象概念,本质上是管理数据库连接的 “中间件” 或 “接口”,它封装了数据库的连接信息

与第一种有一点不一样但是思路是一样的

1.创建一个数据源对象代码语言:javascript复制/ 定义MySQL数据源对象

MysqlDataSource mysqlDataSource = new MysqlDataSource();

// 设置数据库连接

mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/jdbc?characterEncoding=utf8&allowPublicKeyRetrieval" +

"=true&useSSL=false");2.设置URl,root,密码代码语言:javascript复制// 设置数据库连接串

mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/jdbc?characterEncoding=utf8&allowPublicKeyRetrieval" +

"=true&useSSL=false");

// 用户名

mysqlDataSource.setUser("root");

// 密码

mysqlDataSource.setPassword("123456");

// 定义JDBC的数据源对象

DataSource dataSource = mysqlDataSource;3.定义JDBC 的数据源对象代码语言:javascript复制 // 定义JDBC的数据源对象

DataSource dataSource = mysqlDataSource;4.跟第一种方法一样,把他们提出来代码语言:javascript复制 // 定义连接对象

Connection connection = null;

// 定义预处理SQL执行对象

PreparedStatement statement = null;

// 定义结果集对象

ResultSet resultSet = null;5.通过数据源获取数据库连接代码语言:javascript复制 // 1. 通过数据源获取数据库连接

connection = dataSource.getConnection();6.获取预处理SQL执行对象代码语言:javascript复制// 2. 获取预处理SQL执行对象

// 定义要执行的SQL

String sql = "select student_id, sn, name, mail, class_id from student where name = ?";

statement = connection.prepareStatement(sql);7.接收用户的输入,并将前面用占位符的name 的内容获取代码语言:javascript复制 // 接收用户的输入

System.out.println("请输入学生姓名:");

Scanner scanner = new Scanner(System.in);

String name = scanner.next();

// 3. 用真实值替换占位符

statement.setString(1, name);8.获取结果集代码语言:javascript复制// 4. 执行SQL,获取结果集

resultSet = statement.executeQuery();9.循环遍历代码语言:javascript复制 while (resultSet.next()) {

// 获取学生Id

long stuId = resultSet.getLong("student_id");

String stuSn = resultSet.getString(2);

String stuName = resultSet.getString(3);

String stuMail = resultSet.getString(4);

long classId = resultSet.getLong(5);

System.out.println(MessageFormat.format("学生编号={0}, 学号={1}, 学生姓名={2}, 邮箱={3}, 班级编号={4}", stuId, stuSn,

stuName, stuMail, classId));

}10.释放资源跟第一种方法一样代码语言:javascript复制catch (SQLException e) {

e.printStackTrace();

} finally {

// 依次释放资源,关闭连接

if (resultSet != null) {

try {

resultSet.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (statement != null) {

try {

statement.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (connection != null) {

try {

connection.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}3.优化第二种1.设置成静态的无法改变的成员变量代码语言:javascript复制 // 数据源

private static DataSource dataSource = null;

// 数据库连接串

private static final String URL = "jdbc:mysql://127.0.0.1:3306/java113?characterEncoding=utf8" +

"&allowPublicKeyRetrieval=true&useSSL=false";

// 用户名

private static final String USER = "root";

// 密码

private static final String PASSWORD = "123456";通过静态代码块初始化数据源:在类加载时就完成MysqlDataSource的配置(设置 URL、用户名、密码),并赋值给dataSource变量,确保全局只有一个数据源实例,避免重复初始化。2.执行数据源的初始化代码语言:javascript复制// 当类加载到JVM的时候,执行数据源的初始化

static {

MysqlDataSource mysqlDataSource = new MysqlDataSource();

mysqlDataSource.setURL(URL);

mysqlDataSource.setUser(USER);

mysqlDataSource.setPassword(PASSWORD);

dataSource = mysqlDataSource;

}将构造方法private DBUtil()私有化,防止外部通过new创建DBUtil实例。因为工具类的方法通常是静态的(如getConnection()、close()),不需要实例化对象即可调用,私有化构造方法能避免不必要的对象创建,节省资源。3.获取数据库的连接代码语言:javascript复制 /**

* 获取数据库连接

* @return

* @throws SQLException

*/

public static Connection getConnection () throws SQLException {

return dataSource.getConnection();

}封装getConnection()方法,通过数据源dataSource.getConnection()获取连接,对外隐藏连接获取的细节(如 URL、用户名密码的配置)。调用者无需关心连接的具体参数,直接调用方法即可拿到连接,降低使用成本。如果不在方法上声明 throws SQLException,就必须在方法内部用 try-catch 捕获异常。4.释放资源,关闭连接代码语言:javascript复制 /**

* 释放资源,关闭连接

* @param resultSet

* @param statement

* @param connection

*/

public static void close(ResultSet resultSet, Statement statement, Connection connection) {

if (resultSet != null) {

try {

resultSet.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (statement != null) {

try {

statement.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (connection != null) {

try {

connection.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}提供close()方法,统一处理ResultSet、Statement、Connection三种资源的关闭。这三个对象是数据库操作中最常见的资源,若不及时关闭会导致连接泄露、数据库连接耗尽等问题。关闭逻辑按 “先打开后关闭” 的顺序(ResultSet → Statement → Connection),每个资源关闭前先判断是否为null,避免空指针异常,确保资源释放的安全性。4.插入信息1.获取数据库连接代码语言:javascript复制 Connection connection = null;

PreparedStatement statement = null;

// 插入操作需不需要定义结果集对象? -- 不用,因为insert返回的是受影响的行数2.定义SQL 和预处理代码语言:javascript复制// 1. 获取数据库连接

connection = DBUtil.getConnection();

// 2. 定义SQL

String sql = "insert into student (sn, name, mail, class_id) values (?,?,?,?)";

// 3. 定义SQL预处理对象

statement = connection.prepareStatement(sql);3.接收用户参数代码语言:javascript复制 // 4. 接收用户参数

System.out.println("请输入学号:");

Scanner scanner = new Scanner(System.in);

String sn = scanner.next();

System.out.println("请输入姓名:");

String name = scanner.next();

System.out.println("请输入邮箱:");

String mail = scanner.next();

System.out.println("请输入班级编号:");

Long classId = Long.valueOf(scanner.next());4.用真实数据替换占位符代码语言:javascript复制 // 5. 用真实数据填充占位符

statement.setString(1, sn);

statement.setString(2, name);

statement.setString(3, mail);

statement.setLong(4, classId);

// 6. 执行SQL获取结果

int row = statement.executeUpdate();

// 7. 判断结果

if (row == 1) {

System.out.println("插入成功");

} else {

System.out.println("插入失败");

}row 这个变量代表的是 SQL 语句执行后影响的行数

SQL 插入语句的话一定会产生语句的影响,看语句的判读只要大于1,那就产生变化

5.关闭资源代码语言:javascript复制finally {

// 释放资源,关闭连接

DBUtil.close(null, statement, connection);

}调用的方法去关闭资源。

代码语言:javascript复制public class Demo03_Insert {

public static void main(String[] args) {

Connection connection = null;

PreparedStatement statement = null;

// 插入操作需不需要定义结果集对象? -- 不用,因为insert返回的是受影响的行数

try {

// 1. 获取数据库连接

connection = DBUtil.getConnection();

// 2. 定义SQL

String sql = "insert into student (sn, name, mail, class_id) values (?,?,?,?)";

// 3. 定义SQL预处理对象

statement = connection.prepareStatement(sql);

// 4. 接收用户参数

System.out.println("请输入学号:");

Scanner scanner = new Scanner(System.in);

String sn = scanner.next();

System.out.println("请输入姓名:");

String name = scanner.next();

System.out.println("请输入邮箱:");

String mail = scanner.next();

System.out.println("请输入班级编号:");

Long classId = Long.valueOf(scanner.next());

// 5. 用真实数据填充占位符

statement.setString(1, sn);

statement.setString(2, name);

statement.setString(3, mail);

statement.setLong(4, classId);

// 6. 执行SQL获取结果

int row = statement.executeUpdate();

// 7. 判断结果

if (row == 1) {

System.out.println("插入成功");

} else {

System.out.println("插入失败");

}

} catch (SQLException e) {

e.printStackTrace();

} finally {

// 释放资源,关闭连接

DBUtil.close(null, statement, connection);

}

}

}

相关推荐

抖音评论有哪些方式
365bet滚球网

抖音评论有哪些方式

📅 07-11 👁️ 1430
肩托 小提琴
365bet滚球网

肩托 小提琴

📅 07-05 👁️ 4271
官方普法|选种、购种、维权最全攻略
365bet体育在线主页

官方普法|选种、购种、维权最全攻略

📅 08-25 👁️ 6677
御主装备
365bet滚球网

御主装备

📅 07-15 👁️ 7916
如何将一个PHP变量分配给JavaScript
365bet线路检测

如何将一个PHP变量分配给JavaScript

📅 06-29 👁️ 9053
wow木桩在哪里 wow怎么打木桩
365bet体育在线主页

wow木桩在哪里 wow怎么打木桩

📅 07-17 👁️ 779
新浪微博认证要多久?微博认证失败怎么处理
365bet滚球网

新浪微博认证要多久?微博认证失败怎么处理

📅 07-25 👁️ 7669
为什么这么多人学吉他?学吉他的好处你知道吗?
365bet体育在线主页

为什么这么多人学吉他?学吉他的好处你知道吗?

📅 09-06 👁️ 9866