news 2026/5/5 12:10:26

【MySQL】JDBC编程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【MySQL】JDBC编程

文章目录

  • 一、什么是 JDBC?
    • JDBC 的核心作用
    • JDBC 工作流程
  • 二、开发环境准备(Maven 项目)
    • 1. 配置 Maven 阿里云镜像
    • 2. 引入 MySQL 驱动依赖
  • 三、JDBC 核心 API
    • 1. DriverManager(传统连接)
      • Driver类(驱动类)
    • 2. DataSource(连接池)
    • DriverManager VS DataSource
    • 3. Connection(连接对象)
    • 4. Statement(执行对象)
    • 5. ResultSet(结果集)
  • 四、SQL 注入
    • 什么是 SQL 注入?
    • 解决方案
  • 五、完整代码
    • 基础版
    • DataSourse , Preparement 优化
    • 把建立连接和关闭资源封装成对象

一、什么是 JDBC?

JDBC(Java Data Base Connectivity)是 Java 提供的一套数据库操作接口标准,用来统一连接数据库、发送 SQL、处理结果。

特点:

  • 面向接口编程,不关心底层数据库类型
  • 切换数据库只需要换驱动包
  • 是所有 ORM 框架(MyBatis、Hibernate)的底层基础

JDBC 的核心作用

  1. 建立数据库连接
  2. 发送 SQL 语句
  3. 接收并处理执行结果
  4. 关闭资源

JDBC 工作流程

正常来说,访问数据库的重要步骤如下,JDBC也提供了这些接口:

  1. 确定数据库服务器的地址和端口号(数据源)
  2. 建立连接,确定用户名,密码(数据库连接)
  3. 发送要执行的SQL(执行对象)
  4. 接收返回结果(结果集)
  5. 关闭连接(释放资源,关闭连接)

数据库厂商提供了JDBC具体的实现类,Java程序员只需要利用接口来写程序。

加载驱动 → 建立连接 → 创建 Statement → 执行 SQL → 处理结果 → 释放资源

二、开发环境准备(Maven 项目)

Maven类似于应用商店,在maven仓库中维护了所有Java工程所用到的依赖。maven仓库是国外的,可以用阿里的镜像。

1. 配置 Maven 阿里云镜像

加速依赖下载,在settings.xml<mirrors>中加入:

<mirror><id>aliyunmaven</id><mirrorOf>*</mirrorOf><name>阿里云公共仓库</name><url>https://maven.aliyun.com/repository/public</url></mirror>

2. 引入 MySQL 驱动依赖

pom.xml

<dependencies><!-- MySQL 8.x 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies>

三、JDBC 核心 API

1. DriverManager(传统连接)

Class.forName("com.mysql.cj.jdbc.Driver");Connectionconnection=DriverManager.getConnection(url,user,password);

Driver类(驱动类)

2. DataSource(连接池)

DataSource通过一个连接池去管理很多个连接,当需要执行sql时拿出一个空的连接,用完返还给连接池。是更高效、支持连接复用,企业开发标准用法

MysqlDataSourcedataSource=newMysqlDataSource();dataSource.setURL(url);dataSource.setUser(user);dataSource.setPassword(password);

DriverManager VS DataSource

  • DriverManagergetConnection每次获取的是一个物理连接,每执行一次都会打开一个会话窗口,新建连接,用完销毁,性能低
  • Datasourse一个连接可以执行很多SQL,直到关闭数据源。连接可复用,关闭只是归还,性能极高

3. Connection(连接对象)

代表一次数据库会话,用于创建 Statement。

4. Statement(执行对象)

  • Statement:静态 SQL,存在 SQL 注入风险
  • PreparedStatement预编译 SQL,解决sql注入问题
  • CallableStatement:执行存储过程

5. ResultSet(结果集)

封装select查询结果,用next()遍历,getXXX(列名/下标)取值。


四、SQL 注入

什么是 SQL 注入?

用户输入恶意字符串,破坏原有 SQL 逻辑,实现越权查询/删改数据。

示例:

select*fromstudentwherename=''or/**/1=1;#' and class_id=1

直接查出所有数据:

解决方案

PreparedStatement + 占位符 ?

Statement执行静态的sql语句,PreparedStatement可以预处理sql执行对象。参数会被安全转义,从根本杜绝注入。


五、完整代码

功能:根据 name 查询学生

基础版

packageorg.daisy;importjava.sql.*;importjava.text.MessageFormat;importjava.util.Scanner;publicclassdemo01_DriverManager{staticScannerin=newScanner(System.in);publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException{//1. 加载数据库厂商提供的驱动// "com.mysql.cj.jdbc.Driver" 通过完全限定名加载指定的类到JVMClass.forName("com.mysql.cj.jdbc.Driver");//2. 建立连接Connectionconnection=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8"+"&allowPublicKeyRetrieval=true&useSSL=false","root","pullmecloser00");//3. 创建statement对象//sql语句通过connection发送Statementstatement=connection.createStatement();//4. 定义sql语句System.out.println("input name:");Stringname=in.nextLine();Stringsql="select studentID,sn,name,mail,classID from student where name ='"+name+"';";//5. 执行sql语句,获取结果集ResultSetresultSet=statement.executeQuery(sql);//6. 遍历结果集// resultSet.next() 如果有下一条数据就返回truewhile(resultSet.next()){//获取学生ID,sql中的int对应Java中的intintstuId=resultSet.getInt(1);StringstuSn=resultSet.getString(2);StringstuName=resultSet.getString(3);StringstuMail=resultSet.getString(4);StringstuClassId=resultSet.getString(5);System.out.println(MessageFormat.format("学生编号 = {0},学号 = {1},学生姓名 = {2},邮箱 = {3},班级 = {4}",stuId,stuSn,stuName,stuMail,stuClassId));}//7. 释放资源,关闭连接resultSet.close();statement.close();connection.close();}}

DataSourse , Preparement 优化

packageorg.daisy;importcom.mysql.cj.jdbc.MysqlDataSource;importjavax.sql.*;importjava.text.MessageFormat;importjava.util.Scanner;publicclassdemo02_DataSource{staticScannerin=newScanner(System.in);publicstaticvoidmain(String[]args)throwsSQLException{// 定义mysql数据源对象MysqlDataSourcemysqlDataSource=newMysqlDataSource();//设置数据库连接串,用户名,密码mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8"+"&allowPublicKeyRetrieval=true&useSSL=false");mysqlDataSource.setUser("root");mysqlDataSource.setPassword("pullmecloser00");//定义jdbc数据源对象DataSourcedataSource=mysqlDataSource;//1. 通过数据源获取数据库连接Connectionconnection=dataSource.getConnection();//2. 获取预处理sql执行对象//定义要执行的sql语句Stringsql="select studentID,sn,name,mail,classID from student where name = ?";//sql执行对象PreparedStatementpreparedStatement=connection.prepareStatement(sql);//用户输入查询信息System.out.println("input name:");Stringname=in.nextLine();//3. 用真实值来替换占位符//序号1对应第一个占位符preparedStatement.setString(1,name);//4. 执行sql,获取结果//结果集对象ResultSetresultSet=preparedStatement.executeQuery();//遍历结果while(resultSet.next()){//获取学生ID,sql中的int对应Java中的intintstuId=resultSet.getInt(1);StringstuSn=resultSet.getString(2);StringstuName=resultSet.getString(3);StringstuMail=resultSet.getString(4);StringstuClassId=resultSet.getString(5);System.out.println(MessageFormat.format("学生编号 = {0},学号 = {1},学生姓名 = {2},邮箱 = {3},班级 = {4}",stuId,stuSn,stuName,stuMail,stuClassId));}//5. 关闭资源,释放连接resultSet.close();preparedStatement.close();connection.close();}}

把建立连接和关闭资源封装成对象

  • DBUtil
packageorg.daisy.DBUtil;importcom.mysql.cj.jdbc.MysqlDataSource;importjavax.sql.DataSource;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassDBUtil{/** * 构造方法私有化,禁止其他类创建DBUtil对象,是单例模式的一个重要特征 */privateDBUtil(){}//数据源privatestaticDataSourcedataSource=null;//连接串,用户名,密码privatestaticStringURL="jdbc:mysql://127.0.0.1:3306/test20260422?characterEncoding=utf8"+"&allowPublicKeyRetrieval=true&useSSL=false";privatestaticStringuser="root";privatestaticStringpassword="pullmecloser00";//类加载到JVM时,执行数据源的初始化static{MysqlDataSourcemysqlDataSource=newMysqlDataSource();mysqlDataSource.setURL(URL);mysqlDataSource.setUser(user);mysqlDataSource.setPassword(password);dataSource=mysqlDataSource;}/** * 获取数据库连接 * @return * @throws SQLException */publicstaticConnectiongetConnection()throwsSQLException{returndataSource.getConnection();}/** * 释放资源,关闭连接 * @param resultSet * @param statement * @param connection * @throws SQLException */publicstaticvoidclose(ResultSetresultSet,Statementstatement,Connectionconnection)throwsSQLException{if(resultSet!=null)resultSet.close();if(statement!=null)statement.close();if(connection!=null)connection.close();}}
  • Insert
packageorg.daisy;importorg.daisy.DBUtil.DBUtil;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.util.Scanner;publicclassdemo03_Insert{staticScannerin=newScanner(System.in);publicstaticvoidmain(String[]args)throwsSQLException{//1. 获取数据库连接Connectionconnection=DBUtil.getConnection();//2. 定义sqlStringsql="insert student (sn,name,mail,classID) values (?,?,?,?)";//3. 定义预处理对象PreparedStatementstatement=connection.prepareStatement(sql);//4. 用真实数据填充占位符System.out.println("input sn:");Stringsn=in.nextLine();System.out.println("input name:");Stringname=in.nextLine();System.out.println("input mail:");Stringmail=in.nextLine();System.out.println("input classId:");StringclassId=in.nextLine();statement.setString(1,sn);statement.setString(2,name);statement.setString(3,mail);statement.setString(4,classId);//5. 执行并判断 executeUpdate返回结果是受影响的行数introw=statement.executeUpdate();if(row==1)System.out.println("insert successfully");elseSystem.out.println("insert fail");//6. 关闭资源DBUtil.close(null,statement,connection);}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 12:09:27

从TexWorks到TeXstudio:我的LaTeX编辑器升级体验与效率翻倍配置分享

从TexWorks到TeXstudio&#xff1a;我的LaTeX编辑器升级体验与效率翻倍配置分享 第一次用LaTeX写论文时&#xff0c;我像个拿着瑞士军刀却只会用开瓶器的原始人。学校实验室的师兄丢给我一个压缩包&#xff0c;里面是TeX Live和那个叫TexWorks的编辑器。打开后我愣住了——左边…

作者头像 李华
网站建设 2026/5/5 12:07:27

弦振动模拟:物理建模与数值实现技术解析

1. 弦振动模拟的基础原理与数值实现 弦振动模拟是物理建模合成&#xff08;Physical Modeling Synthesis&#xff09;领域的核心技术之一&#xff0c;其数学基础来源于一维波动方程的数值求解。对于长度为L的均匀弦&#xff0c;其横向位移u(x,t)满足经典的达朗贝尔波动方程&…

作者头像 李华
网站建设 2026/5/5 12:06:26

电商场景下小型语言模型(SLM)的优化与实践

1. 项目背景与核心挑战电商场景下的语言模型应用正面临一个关键转折点。过去三年间&#xff0c;我参与过7个不同规模的电商智能客服系统部署&#xff0c;发现大型语言模型&#xff08;LLM&#xff09;在实际业务中面临三大痛点&#xff1a;响应延迟高&#xff08;平均超过2秒&a…

作者头像 李华
网站建设 2026/5/5 12:06:26

英飞凌TC275实战:从零配置CAN FD驱动,让你的电机控制数据飞起来

英飞凌TC275实战&#xff1a;从零配置CAN FD驱动&#xff0c;让你的电机控制数据飞起来 在工业自动化与机器人控制领域&#xff0c;实时数据传输的可靠性与速度直接决定了系统性能上限。传统CAN总线受限于8字节数据帧和1Mbps波特率&#xff0c;在面对现代高精度电机控制时已显捉…

作者头像 李华
网站建设 2026/5/5 11:50:55

第8篇:类和对象——面向对象编程 原生中文编程

第8篇&#xff1a;类和对象——面向对象编程**作者&#xff1a;**中文编程倡导者—— 李金雨 联系方式&#xff1a; wbtm2718qq.com **目标读者&#xff1a;**编程入门&#xff08;零基础&#xff09; 核心理念&#xff1a; 使用华为仓颉原生中文编程&#xff0c;体验真正的国产…

作者头像 李华