超级详细的JDBC和数据库连接池讲解

文章目录

  • JDBC简介
    • 概念
    • 本质
    • 好处
  • JDBC快速入门
  • JDBC中API详解
    • DriverManager
      • 驱动管理类作用
      • 注册驱动
      • 获取连接
    • Connection
      • 数据库连接对象作用
      • 获取执行SQL的对象
      • 事务管理
    • Statement
      • 作用
      • 执行SQL语句
    • ResultSet
      • 原理
      • 使用步骤
    • PreparedStatement
      • SQL注入
      • 获取对象
      • 操作步骤
    • 原理
      • 好处
  • JDBC工具类
  • 三层开发业务的案例分析
    • 图解
    • 三层结构模型
    • 分层的好处
  • 数据库连接池
    • 简介
    • 实现
    • Druid连接池
      • 常用的配置参数
      • 基本使用
      • 使用步骤

JDBC简介

概念

就是使用Java语言操作关系型数据库的一套API
全称:Java DataBase Connectivity Java数据库连接

本质

是一套操作所有关系型数据库的规则,即接口
Snipaste_2024-04-13_18-22-29.png

好处

  1. 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
  2. 可随时替换底层数据库,访问数据库的Java代码基本不变

JDBC快速入门

操作步骤

1. 创建工程,导入驱动jar包
在当前模块下创建lib文件夹,将jar包放到lib文件夹下,
2. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
3. 获取连接
Connection conn = DriverManager.getConnection(url,user,password);
4. 定义SQL语句
String sql = "select ...";
5. 获取执行SQL对象
Statement stmt = conn.createStatement();
6. 执行SQL
boolean result = stmt.executeQuery(sql);
7. 处理返回结果
System.out.println(result);
8. 释放资源
stmt.close();
conn.close();

JDBC中API详解

DriverManager

驱动管理类作用

  1. 注册驱动
  2. 获取数据库连接

注册驱动

Class.forName(“com.mysql.jdbc.Driver”);
Driver类源码
Snipaste_2024-04-13_18-50-23.png
此处也可写成DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 用前面代码创建Driver类,创建时静态代码块又会创建Driver类,使其创建了俩次,所有用最上面class那个代码

获取连接

static Connection getConnection(String url,String user,String password)

  1. url:连接路径

Snipaste_2024-04-13_18-57-50.png

  1. user:用户名
  2. password:密码

连接路径详解
Snipaste_2024-04-13_18-58-59.png

Connection

数据库连接对象作用

  1. 获取执行SQL的对象
  2. 管理事务

获取执行SQL的对象

  • 普通执行SQL对象

Statement createStatement()

  • 预编译SQL的执行SQL对象:防止SQL注入

PrepareStatement prepareStatement(sql)

事务管理

开启事务:SetAutoCommit(boolean autoCommit):
true为自动提交事务,false为手动提交事务(开启事务)
提交事务:commit()
回滚事务:rollback()

Statement

作用

执行SQL语句

执行SQL语句

  • int executeUpdate(sql):执行DML,DDL语句
    • 返回值:DDL执行成功返回0
    • DML语句影响的行数
  • ResultSet executeQuery(sql):执行DQL语句
    • 返回值:ResultSet结果集对象

ResultSet

原理

  1. ResultSet内部有一个指针,刚开始记录开始位置
  2. 调用next方法,ResultSet内部指针会移动到下一行数据,存在返回true,不存在返回false
  3. 我们可以通过ResultSet得到一行数据getXxx得到某列数据

Snipaste_2024-04-13_19-24-53.png

使用步骤

  1. 游标向下移动一行,并判断改行是否有数据:next()
  2. 获取数据:getXxx(参数)
while(rs.next()){re.getXxx(参数);
}

PreparedStatement

SQL注入

用户在页面提交数据的时候人为的添加一些特殊字符,使得sql语句的结构发生了变化,最终可以在没有用户名或者密码的情况下进行登录

获取对象

PreparedStatement是Statement的子接口,可以防止sql注入问题
PreparedStatement prepareStatement(String sql)
注意:sql提前创造好的,sql语句中需要参数,使用?占位
select * from user where username = ?and password = ?;

操作步骤

1.PreparedStatement pstmt = conn.prepareStatement(sql);2.pstmt.setXxx(int index,要放入的值);
第一个参数:int index:表示sql语句中问号出现的位置,从1开始计数
第二个参数:给问号的位置传入的值3.执行,不需要再传递sql了
pstmt.executeQuery();  执行select
pstmt.executeUpdate();  执行insert,update,delete

原理

  1. 在获取PreparedStatement对象时,将SQL语句发送给mysql服务器进行检查,编译
  2. 执行时就不用再进行这些步骤了,速度更快
  3. 如果sql模板一样,则只需进行一次检查,编译

Snipaste_2024-04-13_20-11-44.png

好处

  1. 预编译SQL,性能更高
  2. 防止SQL注入:将敏感字符进行转义

JDBC工具类

通过学习上述代码,我们发现在执行增删改查的时候,除了sql语句和执行sql语句的对象不同外,其他都相同,所以我们可以将其重复的抽成一个抽象类
下面是我所写的代码:

public class JdbcUtil {private static final String DRIVER = "com.mysql.jdbc.Driver";private static final String URL = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false";private static final String USER = "root";private static final String PASSWORD = "123456";//注册驱动,仅执行一次,所以可以放到static代码块中static {try {Class.forName(DRIVER);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}public static Connection getConnection() throws SQLException {return DriverManager.getConnection(URL, USER, PASSWORD);}public static void getClose(Connection conn, Statement stmt) {getClose(conn,stmt,null);}public static void getClose(Connection conn, Statement stmt, ResultSet rs) {try {if (conn != null) {conn.close();}} catch (SQLException e) {throw new RuntimeException(e);}try {if (stmt != null) {stmt.close();}} catch (SQLException e) {throw new RuntimeException(e);}try {if (rs != null) {rs.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}
public class Demo {@Testpublic void testUitl(){Connection conn = null;PreparedStatement pstmt = null;ResultSet rs = null;try {conn = JdbcUtil.getConnection();conn.setAutoCommit(false);String sql = "update user set password = ? where username = ?";pstmt = conn.prepareStatement(sql);pstmt.setString(1,"666");pstmt.setString(2,"wangwu");int count = pstmt.executeUpdate();if (count > 0){System.out.println("更改成功");conn.commit();}else {conn.rollback();}} catch (SQLException e) {throw new RuntimeException(e);}finally {JdbcUtil.getClose(conn,pstmt,rs);}}
}

三层开发业务的案例分析

图解

Snipaste_2024-04-13_21-11-45.png

三层结构模型

  1. web层:接收客户端发送的数据 -> 把接收的数据封装成对象 -> 调用service层方法(并传递对象) -> 根据service层方法执行结果,给客户反馈
  2. service层:处理业务逻辑(会调用dao层中的方法)
  3. dao层:和数据库交互(底层利用jdbc技术)

分层的好处

  1. 解耦:降低代码的依赖关系
  2. 可维护性:哪一层出现问题,直接维护哪一层
  3. 可扩展性:哪一层需要添加代码,直接添加即可
  4. 可重用性:一个方法可以被其他层重复调用

数据库连接池

简介

数据库连接池是个容器,负责分配,管理数据库连接(Connection),它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
好处

  • 资源重用
  • 提升系统响应速度
  • 避免数据库连接遗漏

实现

  • 标准接口:DataSource
    • 获取连接 Connection getConnection
  • 常见的数据库连接池
    • DBCP
    • C3P0
    • Druid
  • Druid

Snipaste_2024-04-13_21-45-04.png

Druid连接池

常用的配置参数

Snipaste_2024-04-13_21-46-05.png

基本使用

核心类:DruidDataSourceFactory
public static DataSource createDataSource(Properties p);
创建一个properties配置文件,然后书写数据库连接参数(参考配置参数)

使用步骤

  1. 导入jar包
  2. 定义配置参数,定义参数
  3. 加载配置文件(创建properties对象)
  4. 获取数据库连接池对象(使用核心类构建连接池)
  5. 获取连接
  6. 执行sql语句
  7. 关闭资源,归还连接

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

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

相关文章

napi系列学习进阶篇——NAPI 导出类对象

简介 js调用napi的数据,对于简单的数据类型,只需要napi返回对应类型的napi_value数据即可 (详情参照napi数据类型类型与同步调用)。但是对于一些复杂的数据类型(如我们常用C的类对象),是不能直接返回一个napi_value数据的。这时我们需要对这…

力扣2923、2924.找到冠军I、II---(简单题、中等题、Java、拓扑排序)

目录 一、找到冠军I 思路描述: 代码: 二、找到冠军II 思路描述: 代码: 一、找到冠军I 一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足…

C++常考面试题(第二篇)

【题目 16】拷贝构造函数的格式和作用,自动调用拷贝构造函数的几种情形? 格式:没有返回值 函数名和类名相同 参数:const person& 类型引用 作用:逐个给成员变量进行赋值三种情形下会调用拷贝构造函数 (1) 当用一…

c++之stack_queue与反向迭代器的实现

目录 1. 简单介绍stack与queue的使用 1.1 stack的介绍与使用 stack的介绍 stack的使用 相关题目 1.2 queue的介绍与使用 queue的介绍 queue的使用 相关题目 2.stack与queue的模拟实现 容器适配器 2.1 stack的模拟实现 2.2 queue的模拟实现 2.3 priority_queu…

嵌入式STM32F407CET6移植OpenHarmony系统方法

第一:【实验目的】 1、STM32F407CET6开发版移植鸿蒙系统的方式 第二:【实验原理】 涉及到原理图添加原理图--普通STM32F407原理图第三:【实验步骤】 一、下载LiteOs源码,复制到到虚拟机中并解压 https://gitee.com/LiteOS/LiteOS

WebLogic-XMLDecoder(CVE-2017-10271)反序列化漏洞分析及复现

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…

SS3D翻译

SS3D networka missingannotated instance mining module 缺失注释实例挖掘模块Score-based filteringIoU-guided suppressionFinal-step instance bank processing a reliable background mining module 可靠背景挖掘模块point cloud filling data augmentation 点云填充数据增…

(学习日记)2024.04.16:UCOSIII第四十四节:内存管理

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

HackTheBox-Machines--MonitorsTwo

文章目录 0x01 信息收集0x02 CVE-2022-46169 漏洞利用0x03 权限提升0x04 提升到root权限 MonitorsTwo 测试过程 0x01 信息收集 a.端口扫描: 发现22、80端口    b.信息收集: 1.2.22 Cacti信息收集 nmap -sC -sV 10.129.186.1321.访问 10.129.186.132,为 1.2.22 Ca…

底层文件操作的各种函数(二)------printf,fprintf,sprintf,scanf,fscanf,sscanf的对比以及文件缓冲区

偷得几日清闲,又因一瞬之间对蹉跎时间的愧疚,由此而来到CSDN这个高手云集和新手求学的平台来也写上那么一篇博客。虽然自己的博客那么久不温不热,但坚持写作,巩固自己就好。今天要讲的是续接上一篇文章的补充与继续吧。上期文章&a…

免费升级至HTTPS协议教程

一、前言 HTTPS协议以其安全性和数据加密特性,逐渐取代HTTP成为互联网通信的主流协议。本文将为您简洁明了地介绍如何免费升级至HTTPS协议。 二、获取免费SSL证书 选择证书提供商:如JoySSL等提供免费SSL证书的服务。 免费申请地址https://www.joyssl.…

太阳光光照试验耐久性老化试验使用太阳光模拟器系统

上海科迎法电气科技有限公司生产的太阳光模拟器系统主要应用于太阳能研究、材料研究、光伏组件测试、空间环境模拟器、植物生长研究、光热模拟等领域,主要表现特征为: 1. 太阳能研究:可用于模拟不同光照条件下太阳能电池的性能测试和研究&am…