当前位置: 首页 > news >正文

【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);}}
http://www.jsqmd.com/news/757032/

相关文章:

  • 2026 网络媒体发稿渠道权威测评TOP5:企业全域增长选型指南 - 博客湾
  • Browserbase Skills
  • FigmaCN中文汉化插件:让Figma界面秒变中文的终极解决方案
  • 体验 Taotoken 按 token 计费模式带来的精细化成本控制感受
  • 2026年无锡市封装打包胶带厂家直供热线,品质保证等你来询 - GrowthUME
  • 自感作为新自由主义的微观界面——岐金兰论“感受”如何成为治理术的最后疆域
  • 用Markdown构建结构化个人技能知识库:从原理到实践
  • 网盘直链下载助手终极教程:5分钟掌握浏览器下载网盘文件的完整方法
  • Windows Defender终极控制指南:开源工具defender-control完全解析
  • 跨平台B站客户端wiliwili:5个实用技巧让您在不同设备上畅享高清视频体验
  • OpenIM Server 企业级离线部署实战指南:从零构建安全内网即时通讯系统
  • 微信聊天记录永久保存的终极方案:WeChatMsg完整指南
  • stm32G030系列单片机的编程和下载方法
  • OpenAI API实战:从调用到部署的Python AI应用开发全指南
  • 2026年,这家封箱胶带工厂为何如此值得推荐? - GrowthUME
  • 嵌入式系统中Newlib库的优化与移植实践
  • 八大网盘直链解析工具的技术实现与应用实践
  • 如何快速配置Umi-OCR插件:新手完整指南
  • StreamFX终极指南:打造专业直播工作室的10个核心技巧
  • 合成数据增强提升LLM逻辑谬误识别能力
  • AI智能体技术栈自动探测与技能推荐系统设计与实现
  • 免费Claude代码接口项目解析:AI编程助手集成与实战指南
  • 观察使用Taotoken后月度大模型API账单的明细变化趋势
  • 厂房屋顶光伏白浪费电?这套储能方案帮你每月多省上万块
  • 终极照片隐私保护指南:用ExifToolGui彻底清理元数据
  • PhotoBench:个性化多模态图像检索技术解析
  • PHP 8.9错误处理新范式(RFC #927深度落地版):从全局异常捕获到上下文感知型错误抑制
  • 如何彻底清理Windows垃圾软件:Bulk Crap Uninstaller终极指南
  • 从零搭建一个Qt小工具:我是如何用事件过滤器解决界面卡顿问题的
  • 5步拯救你的微信记忆:WeChatExporter终极聊天记录导出指南