从零开启 JDBC 编程

前言

最近在总结MyBatis的时候了解到,MyBatis的底层使用的就是JDBC,仔细想想JDBC是我很久之前学过的东西了,现在难免有些遗忘,所以打算重新拿出来写一下,毕竟理解了JDBC的工作原理和原始API的使用,对理解框架也会有很大的帮助。

<---------------- 正文开始 ---------------->

真正在公司中操作数据库,99%是通过代码来操作的,很少会手动在客户端里输入sql语句。各种数据库:MySQL,Oracle,SQL Sever…… 在开发的时候,就会提供一组编程接口(API),这些数据库提供的API不同,给程序员的学习带来了很大压力,于是Java官方定义了自己的数据库接口规范—— JDBC。

一、导入驱动依赖

数据库厂商提供一个程序来完成API的转换,对原生API封装,在提供成JDBC形状。java程序员想要进行数据库开发就需要在你的项目中导入对应 数据库的驱动包 才能编写代码。关于驱动包的获取,可以在Maven中央仓库中获取:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.49

PS:注意驱动包的版本,大版本要和数据库服务器匹配,比如我当前的数据库服务器版本是MySQL5.7,那么驱动版本需要是 5.x。

我们以一个Maven项目为例,只需要在 pom.xml 中导入以下依赖即可:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version>
</dependency>

二、建立数据库连接

1、创建并初始化数据源

在JDBC编程中,数据源(DataSource)是一个提供数据库连接的对象,它通常包含了数据库的URL、用户名和密码等信息。

//1.创建并初始化数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");

PS:jdbc:mysql://数据库服务器IP地址:数据库服务器端口号/数据库名?characterEncoding=utf8&useSSL=false。这是数据库的连接字符串,可以认为是固定格式写死的。

2、和数据库服务器建立连接

//2.和数据库服务器建立连接
Connection connection = dataSource.getConnection();

三、创建Statement或PrepareStatement对象

StatementPrepareStatement都是通过建立的 connection 连接获取到的,用于执行SQL的接口:

Statement statement = connection.createStatement();
String sql = "SELECT * FROM mytable WHERE column = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
  1. Statement对象用于执行静态的SQL语句,即在编写代码时已经确定了SQL语句的内容。这种方式是存在SQL注入风险的,因为使用Statement对象执行的SQL语句一般都是经过拼接而成的,如果传过来的参数存在SQL关键字就可能拼接出一条恶意的SQL。

  2. PrepareStatement对象它通过预编译SQL语句,可以防止SQL注入攻击(前提是不使用拼接SQL)。PrepareStatement对象的SQL语句中可以包含占位符(例如?),在执行时需要为这些占位符指定具体的数值。这种方式可以有效地防止恶意输入对SQL语句的破坏。在实际开发中,推荐使用。

四、执行SQL语句

Statement对象执行SQL语句:

ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable");

PrepareStatement对象执行SQL语句:

// 设置参数
preparedStatement.setString(1, "somevalue");
ResultSet resultSet = preparedStatement.executeQuery();

五、处理结果

对于不同的SQL语句,执行后返回的结果是不一样的,但总体分为两大类:

  1. 增删改语句:返回 int 类型的受影响的行数。
  2. 查询语句:返回 ResultSet 类型的结果集。

对于 int 类型的受影响的行数这个都好理解,这里重点介绍一下 ResultSet 结果集。

while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");double salary = resultSet.getDouble("salary");// 处理获取到的数据// ...
}
  1. next() 是 ResultSet 接口提供的方法之一,用于在结果集中移动到下一行数据。它的作用是将指针从当前行移动到下一行,并返回一个布尔值,表示是否存在下一行数据。需要注意的是,第一次调用
    .next() 方法将把指针移动到结果集的第一行(如果存在)。因此,在处理结果集之前,通常会先调用 .next()
    方法一次,以确保指针指向第一行数据。

  2. 使用 ResultSet 对象提供的方法,您可以遍历获取查询结果集中的数据。常用的获取数据的方法包括getInt()、getString()、getDouble()等。

六、关闭连接

如果不主动关闭连接,这些资源将一直被占用,连接池中的连接数量会不断增加,而不会被回收,会导致内存泄漏的问题。

关闭连接的顺序是很重要的。应按照从小到大的顺序关闭资源,即按照申请资源的逆顺序进行:先关闭 ResultSet,再关闭 Statement 或 PreparedStatement,最后关闭 Connection.

// jdbc连接处理代码
// ...// 关闭连接
// 1.如果在代码中使用了 ResultSet 对象,需要先关闭它。
resultSet.close();
// 2.关闭相应的 PreparedStatement 对象。
preparedStatement.close();
// 3.关闭与数据库的连接
connection.close();

为了确保资源的正确释放,避免遗忘,可以使用 try-with-resources 语句块来自动关闭资源:

try (Connection connection = DriverManager.getConnection(url, username, password);PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery()
) {// 处理查询结果// ...
} catch (SQLException e) {// 处理异常// ...
}

七、使用示例

正文部分到这里基本就结束了,下面给出使用JDBC进行 的示例供大家参考和进一步理解:

1、Insert-添加

public class JDBCinsert {public static void main(String[] args) throws SQLException {Scanner scanner = new Scanner(System.in);//1.创建并初始化数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("myname");((MysqlDataSource)dataSource).setPassword("mypassword");//2.建立连接Connection connection = dataSource.getConnection();//3.构造SQL语句String sql = "insert into student values(?,?)";//4.SQL预编译PreparedStatement statement = connection.prepareStatement(sql);System.out.print("请输入更新数据条目:");int n = scanner.nextInt();while (n!=0) {//5.用户输入System.out.print("请输入学生姓名:");scanner.nextLine();String name = scanner.nextLine();System.out.print("请输入学生id:");int id = scanner.nextInt();statement.setInt(1,id);statement.setString(2,name);//6.执行sqlint ret = statement.executeUpdate();System.out.println("affected:"+ret);//打印拼接后结果System.out.println(statement);n--;}//7.关闭资源statement.close();connection.close();}
}

2、delete-删除

public class JDBCdelete {public static void main(String[] args) throws SQLException {Scanner scanner = new Scanner(System.in);//1.创建并初始化数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("myname");((MysqlDataSource)dataSource).setPassword("mypassword");//2.和数据库服务器建立连接Connection connection = dataSource.getConnection();//3.构造SQL语句String sql = "delete from student where id = ?";//4.让客户端对SQL进行预编译PreparedStatement statement = connection.prepareStatement(sql);int id = scanner.nextInt();statement.setInt(1,id);System.out.println(statement);//5.执行SQL语句int ret = statement.executeUpdate();System.out.println("affected:"+ret);//6.关闭资源statement.close();connection.close();}
}

3、select-查询

public class JDBCselect {public static void main(String[] args) throws SQLException {//1.创建并初始化数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydata?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("Ls03313517");//2.和数据库服务器建立连接Connection connection = dataSource.getConnection();//3.构造SQL语句String sql = "select * from student";//4.让客户端对sql预编译PreparedStatement statement = connection.prepareStatement(sql);//5.执行SQL语句ResultSet resultSet = statement.executeQuery();//6.获取结果集合while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println("学号:"+id+" 姓名:"+name);}//7.关闭资源resultSet.close();statement.close();connection.close();}
}

4、update-修改

public class JDBCupdate {public static void main(String[] args) throws SQLException {Scanner scanner = new Scanner(System.in);//1.创建并初始化数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("myname");((MysqlDataSource)dataSource).setPassword("mypassword");//2.和数据库服务器建立连接Connection connection = dataSource.getConnection();//3.构造SQL语句String sql = "update student set name = ? where id = ?";//4.让客户端对SQL语句进行预编译PreparedStatement statement = connection.prepareStatement(sql);System.out.print("请输入需要修改条目对应id:");int id = scanner.nextInt();scanner.nextLine();System.out.print("请输入更新name:");String name = scanner.nextLine();statement.setInt(2,id);statement.setString(1,name);//打印构造完成的SQL语句System.out.println(statement);//5.执行SQL语句int ret = statement.executeUpdate();System.out.println("affected:"+ret);//6.释放资源statement.close();connection.close();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/683857.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

具有集中目录服务器的 P2P 工作方式

P2P 工作方式概述 在 P2P 工作方式下&#xff0c;所有的音频/视频文件都是在普通的互联网用户之间传输。 具有集中目录服务器的 P2P 工作方式 Napster 最早使用 P2P 技术&#xff0c;提供免费下载 MP3 音乐。 Napster 将所有音乐文件的索引信息都集中存放在 Napster 目录服务…

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1, 因为在此系统上禁止运行脚本

ng : 无法加载文件 C:\Program Files\nodejs\node_global\ng.ps1&#xff0c;因为在此系统上禁止运行脚本 今天在VSCode中运行ng serve --port 8081运行基于Angular的项目时&#xff0c;报错了&#xff0c;错误如下图所示&#xff1a; 解决方法&#xff1a; 按照下图的5步即…

算法沉淀——哈希算法(leetcode真题剖析)

算法沉淀——哈希算法 01.两数之和02.判定是否互为字符重排03.存在重复元素04.存在重复元素 II05.字母异位词分组 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;映射为固定长度的输出的算法。这个输出通常称为哈希…

七、Mybatis缓存

缓存就是内存中的数据&#xff0c;常常来自对数据库查询结果的保存&#xff0c;使用缓存、可以避免频繁的与数据库进行交互&#xff0c;进而提高响应速度一级缓存是sqlSession级别的缓存&#xff0c;在操作数据库时需要构造sqlsession对象&#xff0c;在对象中有一个数据结构&a…

【智能家居入门3】(MQTT服务器、MQTT协议、微信小程序、STM32)

前面已经写了三篇博客关于智能家居的&#xff0c;服务器全都是使用ONENET中国移动&#xff0c;他最大的优点就是作为数据收发的中转站是免费的。本篇使用专门适配MQTT协议的MQTT服务器&#xff0c;有公用的&#xff0c;也可以自己搭建&#xff08;应该要钱&#xff09;&#xf…

数矩形个数

给定平面整数网格上的点&#xff0c;计算长方形的个数&#xff0c;例如 输入&#xff1a;[(0, 0), (0, 1), (1, 0), (1, 1)] &#xff0c;输出&#xff1a;1​ 输入&#xff1a;[(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]&#xff0c;输出&#xff1a;3 ​ 思路一 每…

【Java程序员面试专栏 分布式中间件】ElasticSearch 核心面试指引

关于ElasticSearch 部分的核心知识进行一网打尽,包括ElasticSearch 的基本概念,基本架构,工作流程,存储机制等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 基础概念 从数据分类入手,考察全文索引的基本概念 现实世界中数据有哪…

量子算法入门——2.线性代数与复数

参考资料&#xff1a; 【【零基础入门量子计算-第03讲】线性代数初步与复数】 来自b站up&#xff1a;溴锑锑跃迁 建议关注他的更多高质量文章&#xff1a;CSDN&#xff1a;【溴锑锑跃迁】 0. 前言 强烈建议搭配b站原视频进行观看&#xff0c;这只是我当时看的笔记&#xff0c…

Vue路由的传参

Vue传参方式可以划分为params传参&#xff08;参数隐藏在路径中&#xff09;和query传参&#xff08;参数在&#xff1f;后&#xff09;俩种方式 1. 使用 router-link 标签跳转路由 要注意 to 和 :to 的不同&#xff1a; to 不带参数 &#xff0c; :to 带参数 &#xff0…

【机器学习笔记】4 朴素贝叶斯

贝叶斯方法 贝叶斯分类 贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。 朴素贝叶斯分类是这一类算法中最简单的较为常见的算法。 先验概率 根据以往经验和分析得到的概率。我们用&#x1d443;(&#x1d44c;)来代…

FL Studio 21.2.3.4004 All Plugins Edition Win/Mac音乐软件

FL Studio 21.2.3.4004 All Plugins Edition 是一款功能强大的音乐制作软件&#xff0c;提供了丰富的音频处理工具和插件&#xff0c;适用于专业音乐制作人和爱好者。该软件具有直观的用户界面&#xff0c;支持多轨道录音、混音和编辑&#xff0c;以及各种音频效果和虚拟乐器。…

【pandas 不同文件读取和存储】

文章目录 一、Pandas 文件读取和存储概览二、读取不同类型的文件1. CSV文件的读取与存储代码及解释&#xff1a; 2. Excel文件的读取与存储代码及解释&#xff1a; 3. JSON文件的读取与存储代码及解释&#xff1a; 4. SQL数据库的读取与存储代码及解释&#xff1a; 5. 其他格式…

华清远见嵌入式学习——春节作业——2.15日

作业要求&#xff1a; 编写led驱动&#xff0c;通过应用程序控制三盏灯亮灭 作业答案&#xff1a; 作业效果&#xff1a; mychrdev.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #incl…

springboot声明(创建)RabbitMQ交换机和队列

在之前我们都是基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时&#xff0c;队列和交换机是程序员定义的&#xff0c;将来项目上线&#xff0c;又要交给运维去创建。那么程序员就需要把程序中运行的所有队列和交换机都写下来&#xff0c;交给运维。在这个过程中是很容…

基于GPT-4一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

医卫答案在哪搜?九个公众号和软件推荐清单! #笔记#笔记#微信

在这个信息爆炸的时代&#xff0c;合理利用学习工具可以帮助我们过滤和获取有用的知识。 1.粉鹿搜题 这是一个公众号 题库包括四六级答案、各学校往期课后答案、期末考试题等&#xff0c;使用比较简单。 下方附上一些测试的试题及答案 1、最有可能担任债券发行受托人的个人…

ES实战--文档间的关系

文档常见关系 1.对象类型 2.嵌套文档 3.文档间的父子关系 4.反规范化 5.应用端的链接 嵌套映射和对象映射看上去差不多,不过其type不是object而是nested 查询和过滤器区别 1.查询是计算得分的,查询返回按照相关性得分排列的结果 2,过滤器不计算得分,运行更快,且易缓存 Nested查…

SSM框架,Spring-ioc的学习(下)

拓展&#xff1a;在xml文件中读取外部配置文件 例&#xff1a;若要导入外部配置文件jdbc.properties <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"<http://www.springframework.org/schema/beans>"xmlns:xsi"&l…

装饰工程|装饰工程管理系统-项目立项子系统的设计与实现|基于Springboot的装饰工程管理系统设计与实现(源码+数据库+文档)

装饰工程管理系统-项目立项子系统目录 目录 基于Springboot的装饰工程管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员功能实现 &#xff08;2&#xff09;合同报价管理 &#xff08;3&#xff09;装饰材料总计划管理 &#xff08;4&#xff0…

Java与JavaScript的区别与联系

Java是目前编程领域使用非常广泛的编程语言&#xff0c;相较于JavaScript&#xff0c;Java更被人们熟知。很多Java程序员想学门脚本语言&#xff0c;一看JavaScript和Java这么像&#xff0c;很有亲切感&#xff0c;那干脆就学它了&#xff0c;这也间接的帮助了JavaScript的发展…