JDBC(Java DataBase Connectivity,java数据库连接)

是一种用于执行SQL语句的Java API,可以为多 种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序 Java 具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性。所需要的只是 Java应用程序与各种不同数据库之间进行对话的方法。 JDBC库包括通常与数据库使用相关的下面提到的每个任务的API。

  • 连接数据库。
  • 创建SQL或MySQL语句。
  • 在数据库中执行SQL或MySQL查询。
  • 查看和修改生成的记录。

JDBC体系结构

JDBC API支持用于数据库访问的两层和三层处理模型,通常,JDBC体系结构由两层组成:

  • JDBC API:这提供了应用程序到JDBC管理器连接。
  • JDBC驱动程序API:这支持JDBC管理器到驱动程序连接。 JDBC API使用驱动程序管理器和特定于数据库的驱动程序来提供与异构数据库的透明连接

JDBC核心组件

DriverManager: 此类管理数据库驱动程序列表。使用通信子协议将来自java应用程序的连接请求
与适当的数据库驱动程序匹配。
Driver:此接口处理与数据库服务器的通信,我们很少会直接与Driver对象进行交互。而是使用
DriverManager对象来管理这种类型的对象。
Connection:该界面具有用于联系数据库的所有方法。连接对象表示通信上下文,即,与数据库
的所有通信仅通过连接对象。
Statement:使用从此接口创建的对象将SQL语句提交到数据库。除了执行存储过程之外,一些派
生接口还接受参数。
ResultSet:在使用Statement对象执行SQL查询后,这些对象保存从数据库检索的数据。它作为一
个迭代器,允许我们移动其数据。
SQLException:此类处理数据库应用程序中发生的任何错误

使用步骤

  1. 导入包:需要包含包含数据库编程所需的JDBC类的包。大多数情况下,使用import java.sql.*足够
  2. 注册JDBC驱动程序:初始化驱动程序,打开与数据库的通信通道。
  3. 打开连接:需要使用DriverManager.getConnection()方法创建一个Connection对象,该对象表示与数据库的物理连接。
  4. 执行查询:需要使用类型为Statement的对象来构建和提交SQL语句到数据库。
  5. 从结果集中提取数据:需要使用相应的ResultSet.getXXX()方法从结果集中检索数据。
  6. 释放资源:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。

JDBC连接步骤

- 导入JDBC包:将Java语言的*import*语句添加到Java代码中导入所需的类。

- 注册JDBC驱动程序:JVM将所需的驱动程序实现动态加载到内存中,以便它可以满足JDBC 请求。

- 数据库URL配置:这是为了创建一个格式正确的地址,指向要连接到的数据库。

- 创建连接对象:最后,调用DriverManager对象的getConnection()方法来建立实际的数据库连 接。

jdbc为什么用反射创建驱动程序对象-CSDN博客

Class.forName(); 注册驱动程序最常见的方法是使用Java的Class.forName()方法,将驱动程序的类文件动态加载到内存 中,并将其自动注册

try {Class.forName("com.mysql.cj.jdbc.Driver");
}catch(ClassNotFoundException ex) {System.out.println("Error: unable to load driver class!");System.exit(1);
}

数据库URL配置

加载驱动程序后,可以使用DriverManager.getConnection()方法建立连接。三个重载的DriverManager.getConnection()方法

getConnection(String url)
getConnection(String url,Properties prop)
getConnection(String url,String user,String password)

 创建数据库连接对象

String URL = "jdbc:mysql://localhost:3306/yhp2?serverTimezone=UTC";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);//使用Property
String URL = "jdbc:mysql://localhost:3306/yhp2?serverTimezone=UTC";
Properties info = new Properties( );
info.put( "user", "username" );
info.put( "password", "password" );
Connection conn = DriverManager.getConnection(URL, info);//关闭数据库连接
//为确保连接关闭,可以在代码中提供一个“finally”块。一个finally块总是执行,不管是否发生异常。
要关闭上面打开的连接,调用close()
conn.close();

JDBC执行SQL语句

一旦获得了连接,可以与数据库进行交互。JDBC Statement和PreparedStatement接口定义了使能够发送SQL命令并从数据库接收数据的方法和属性,用于对数据库进行通用访问(状态通道)。

  • Statement在运行时使用静态SQL语句时很有用。Statement接口不能接受参数。
  • PreparedStatement当多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。

Statement

创建语句对象 在使用Statement对象执行SQL语句之前,需要使用Connection对象的createStatement()方法创建 一个

Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
catch (SQLException e) {
. . .
}
finally {
...
}

创建Statement对象后,使用它来执行一个SQL语句,有三个执行方法。

- boolean execute(String SQL):如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返
回false。使用此方法执行SQL DDL语句或需要使用真正的动态SQL时。
- int executeUpdate(String SQL):返回受SQL语句执行影响的行数。使用此方法执行预期会影响
多个行的SQL语句,例如INSERT,UPDATE或DELETE语句。
- ResultSet executeQuery(String SQL):返回一个ResultSet对象。当您希望获得结果集时,请使
用此方法,就像使用SELECT语句一样。

关闭Statement对象

类似关闭一个Connection对象以保存数据库资源,由于同样的原因,也应该关闭Statement对象。 调用close()方法即可。如果先关闭Connection对象,也会关闭Statement对 象。但是,应始终显式关闭Statement对象,以确保正确清理。

Statement stmt = null;
try {stmt = conn.createStatement( );. . .
}
catch (SQLException e) {. . .
}
finally {stmt.close();
}

SQL注入

通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执 行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎 执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。比如很多影视网站泄露VIP会员密码大多就是通过 WEB表单递交查询字符爆出的,这类表单特别容易受到SQL注入式攻击。

String username ="user";
String password=" '123' or 1=1 ";
String sql="select * from users where username= '"+username+"' and password=
"+password;
此时即使username与password均不存在于数据库中,依然可以登陆成功

PreparedStatement(预状态通道)

该PreparedStatement的接口扩展了Statement接口,它提供了一个通用的Statement对象有两个优点附加功能。 此语句可以动态地提供参数。

PreparedStatement pstmt = null;
ResultSet resultSet=null;
try {String SQL = "Update Employees SET age = ? WHERE id = ?";pstmt = conn.prepareStatement(SQL);pstmt.setInt(1,23);pstmt.setInt(2,1);resultSet = pstmt.executeQuery();. . .
}
catch (SQLException e) {. . .
}
finally {. . .
}

JDBC中的所有参数都由?符号表示,这被称为参数标记。在执行SQL语句之前,必须为每个参数提供值。setXXX()方法将值绑定到所述参数,其中XXX代表要绑定到输入参数的值的Java数据类型。若没有提供值,将收到一个SQLException。 每个参数标记由其顺序位置引用。第一个标记表示位置1,下一个位置2等等。该方法与Java数组索引不同(从0开始)。

PreparedStatement也需要关闭

statement VS PreparedStatement

  • statement属于状态通道,PreparedStatement属于预状态通道
  • 预状态通道会先编译sql语句,再去执行,比statement执行效率高
  • 预状态通道支持占位符?,给占位符赋值的时候,位置从1开始
  • 预状态通道可以防止sql注入,原因:预状态通道在处理值的时候以字符串的方式处理

ResultSet

java.sql.ResultSet中的接口表示 结果集数据库查询。 ResultSet对象维护指向结果集中当前行的游标。术语“结果集”是指包含在ResultSet对象中的行和列数 据。 如果没有指定任何ResultSet类型,将自动获得一个TYPE_FORWARD_ONLY。

try {Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
}catch(Exception ex) {....
}finally {....
}
------------------------
resultSet.getString(2)//列的索引(1开始)
resultSet.getString(2)//列名

JAVA操作两表关系

多表关系处理数据

  • 数据库通过外键建立两表关系
  • 实体类通过属性的方式建立两表关系

实体类要求:类名=表名,列名=属性名(外键列一般不生成属性)

数据库事务

事务开始于
- 连接到数据库上,并执行一条DML语句insert、update或delete
- 前一个事务结束后,又输入了另一条DML语句
事务结束于
- 执行commit或rollback语句。
- 执行一条DDL语句,例如create table语句,在这种情况下,会自动执行commit语句。
- 执行一条DDL语句,例如grant语句,在这种情况下,会自动执行commit。
- 断开与数据库的连接
- 执行了一条DML语句,该语句却失败了,在这种情况中,会为这个无效的DML语句执行rollback语
句。

JDBC中事务应用

如果JDBC连接处于自动提交模式,默认情况下,每个SQL语句在完成后都会提交到数据库。

事务能够控制是否和何时更改应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单 元,如果任何语句失败,则整个事务将失败。(比如加钱和减钱应该放在同一个事务中)

要启用手动事务支持,而不是JDBC驱动程序默认使用的自动提交模式,使用Connection对象的 setAutoCommit()方法。将boolean false传递给setAutoCommit(),关闭自动提交。传递true可以重新打开它。

conn.commit( );//提交更改
conn.rollback( );//回滚try{
//Assume a valid connection object connconn.setAutoCommit(false);Statement stmt = conn.createStatement();String SQL = "INSERT INTO Employees values (106, 20, 'Rita', 'Tez')";stmt.executeUpdate(SQL);
//Submit a malformed SQL statement that breaksString SQL = "INSERTED IN Employees VALUES (107, 22, 'Sita', 'Singh')";stmt.executeUpdate(SQL);
// If there is no error.conn.commit();}
catch(SQLException se){
// If there is any error.conn.rollback();
}

Savepoints

设置保存点时,可以在事务中定义逻辑回滚点。如果通过保存点发生错误,则可以使用回滚方法来撤消 所有更改或仅保存在保存点之后所做的更改。

Connection对象有两种新的方法来帮助管理保存点

- setSavepoint(String savepointName):定义新的保存点。它还返回一个Savepoint对象。

- releaseSavepoint(Savepoint savepointName):删除保存点。注意,它需要一个Savepoint 对象作为参数。此对象通常是由setSavepoint()方法生成的保存点。

try{
//Assume a valid connection object connconn.setAutoCommit(false);Statement stmt = conn.createStatement();String SQL = "INSERT INTO Employees VALUES (23,'person1')";stmt.executeUpdate(SQL);Savepoint savepoint1 = conn.setSavepoint("Savepoint1");int a=3/0;String SQL = "INSERTED IN Employees VALUES (34,'person2')";stmt.executeUpdate(SQL);conn.commit();
}catch(Exception e){try {conn.rollback(savepoint1);conn.commit()//此时会回退到保存点1之前,第一条新增语句会保存到数据库} catch (SQLException e1) {e1.printStackTrace();}
}

JDBC批处理

批量处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用提交它们。 当一次向数据库发送多个SQL语句时,可以减少连接数据库的开销,提高性能。

Statement批处理

使用语句对象的批处理的典型步骤
- 使用createStatement()方法创建Statement对象。
- 使用setAutoCommit()将auto-commit设置为false 。
- 使用addBatch()方法在创建的语句对象上添加SQL语句到批处理中。
- 在创建的语句对象上使用executeBatch()方法执行所有SQL语句。
- 最后,使用commit()方法提交所有更改。
Statement stmt = conn.createStatement();
conn.setAutoCommit(false);
String SQL = "INSERT INTO Employees (id, first, last, age) VALUES(200,'Zia',
'Ali', 30)";
stmt.addBatch(SQL);
String SQL = "INSERT INTO Employees (id, first, last, age) VALUES(201,'Raj',
'Kumar', 35)";
stmt.addBatch(SQL);
String SQL = "UPDATE Employees SET age = 35 WHERE id = 100";
stmt.addBatch(SQL);
int[] count = stmt.executeBatch();
conn.commit();

PreparedStatement批处理

1. 使用占位符创建SQL语句。
2. 使用prepareStatement() 方法创建PrepareStatement对象。
3. 使用setAutoCommit()将auto-commit设置为false 。
4. 使用addBatch()方法在创建的语句对象上添加SQL语句到批处理中。
5. 在创建的语句对象上使用executeBatch()方法执行所有SQL语句。
6. 最后,使用commit()方法提交所有更改。
String SQL = "INSERT INTO Employees (id, first, last, age) VALUES(?, ?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(SQL);
conn.setAutoCommit(false);
// Set the variables
pstmt.setInt( 1, 400 );
pstmt.setString( 2, "Pappu" );
pstmt.setString( 3, "Singh" );
pstmt.setInt( 4, 33 );
// Add it to the batch
pstmt.addBatch();
// Set the variables
pstmt.setInt( 1, 401 );
pstmt.setString( 2, "Pawan" );
pstmt.setString( 3, "Singh" );
pstmt.setInt( 4, 31 );
// Add it to the batch
pstmt.addBatch();
//add more batches
//Create an int[] to hold returned values
int[] count = stmt.executeBatch();
conn.commit();

反射处理结果集

假设要查询的表有非常多的列,那么遍历Resultset的时候需要调用bean的实例属性方法非常多次,很繁琐,鉴于bean的set/get方法后与列名一致,可以使用反射clz.getDeclaredMethods()获取所有对应的set方法,再调用invoke赋值

Method[] methods =cla.getDeclaredMethods();
while(rs.next()){Object s=cla.newInstance();//调取无参构造创建对象for (String columnname : columnnames) {String name="set"+columnname;//setstuidfor (Method method : methods) {if(method.getName().equalsIgnoreCase(name)){method.invoke(s,rs.getObject(columnname));//执行了对应的set方法break;}    }
}
}

定义工具类:重复操作可以封装到工具类中

//1.定义需要的工具类对象//2.加载驱动//3.获得连接//4.创建通道//5.给占位符赋值 list中保存的是给占位符所赋的值//6.增删改调取的方法//7.查询的时候调取的方法//8.关闭资源

properties文件保存数据库信息-特点:key-value存储方式

db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/database
user=root
password=1234
//工具类中读取属性文件
InputStream inputStream = 类名.class.getClassLoader()
.getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(inputStream);
dirverName = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("user");
password = properties.getProperty("password");//方式2
static{//参数只写属性文件名即可,不需要写后缀ResourceBundle bundle = ResourceBundle.getBundle("db");driver = bundle.getString("driver");url = bundle.getString("url");username = bundle.getString("user");password = bundle.getString("password");
}
使用ResourceBundle访问本地资源
在设计时,往往需要访问一些适合本地修改的配置信息,如果作为静态变量,那么每次修改都
需要重新编译一个class,.config保存此类信息并不适合,这时我们需要ResourceBundle。
通过ResourceBundle,需要访问位于/WEB-INF/classes目录下的一个后缀名为properties的文本
类型文件,从里面读取需要的值。

数据库连接池

连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数 据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连 接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数 以及每个连接的最大使用次数、最大空闲时间等等,也可以通过其自身的管理机制来监视数据库连接的 数量、使用情况等。

自定义连接池

连接池类应该包含特定的属性和方法(第三方连接池都是基于该思路)

  • 属性: 集合 (泛型为Connection)
  • 方法: 获取连接 回收连接
最小连接数:
是数据库一直保持的数据库连接数,所以如果应用程序对数据库连接的使用量不大,将有大量的数据库
资源被浪费。
初始化连接数:
连接池启动时创建的初始化数据库连接数量。
最大连接数:
是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入到等待队
列中。
最大等待时间:
当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0或者负
数使得无限等待(根据不同连接池配置)。

数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连 接。如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个 连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没有达到 maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在 连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。

Druid(德鲁伊)连接池

使用步骤1 导入jar包 2 编写工具类

public class DruidUtils {
//声明连接池对象
private static DruidDataSource ds;
static{
///实例化数据库连接池对象
ds=new DruidDataSource();
//实例化配置对象
Properties properties=new Properties();
try {
//加载配置文件内容
properties.load(DruidUtils.class.getResourceAsStream("dbcpconfig.properties"));
//设置驱动类全称
ds.setDriverClassName(properties.getProperty("driverClassName"));
//设置连接的数据库
ds.setUrl(properties.getProperty("url"));
//设置用户名
ds.setUsername(properties.getProperty("username"));
//设置密码
ds.setPassword(properties.getProperty("password"));
//设置最大连接数量
ds.setMaxActive(Integer.parseInt(properties.getProperty("maxActive")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//获取连接对象
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null
}
}

JDBC(Java数据库连接)相关推荐

  1. day04 JDBC java数据库连接

    day04 JDBC java数据库连接 yuxiaohu已关注 2017.12.03 16:12:19字数 139阅读 85 1 导包 mysql 提供的实现java接口的包路径 C:\Progra ...

  2. jdbc java数据库连接 3)Statement接口之执行DDL和DML语句的简化

    上一章的代码中,可以发现,jdbc执行DDL和DML有几个步骤都是一样的: 1)执行语句开始时,创建驱动注册对象.获取连接的数据库对象.创建Statement对象 1 // 创建驱动注册对象 2 Cl ...

  3. jdbc java数据库连接 5)CallableStatement 接口

    CallableStatement执行存储过程(也是预编译语言) 首先在sql中执行以下带有输入参数的代码: 1 DELIMITER $ 2 CREATE PROCEDURE pro_findById ...

  4. JDBC——Java数据库连接

    JDBC 一.概念 二.连接 1.得到 Connection 对象 ①.DataSource 的方式 ②. DriverManager 的方式 2.得到语句对象 3.带结果的 SQL 语句:selec ...

  5. jdbc java数据库连接 4)PreParedStatement接口 之 区别和例子

    Statement 和 PreparedStatement 的区别: 1)语句不同 PreparedStatement需要预编译以及需要参数 2)由于PreparedStatement有缓存区,所以效 ...

  6. Java数据库连接(JDBC)之一:JDBC详细连接过程

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  7. 01-JDBC概念--JDBC(Java Database Connectivity:Java数据库连接):使用jdbc实现Java与数据库MySQL连接

    JDBC自学教程–终篇总结: 地址:http://blog.csdn.net/baidu_37107022/article/details/72600018 1.JDBC(Java Database ...

  8. JDBC(Java Data Base Connectivity,java数据库连接)

    2019独角兽企业重金招聘Python工程师标准>>> JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成 ...

  9. JDBC(Java数据库连接) 学习笔记 第四天

    数据库连接池 8.1 JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet.beans)中建立数据库连接 进行sql操作 断开数据 ...

  10. 4.Java数据库连接_1.JDBC (Java DB Connection)简介

    //============================================================================ Mysql安装参考: http://blo ...

最新文章

  1. 5-510寝室课后习题4.35
  2. Zookeeper之javaAPI的使用
  3. Xamarin中Unsupported major.minor version 52.0问题解决
  4. python 支付宝个人账单_解析2018年度三大用户数据报告——网易云音乐、支付宝、微信...
  5. WPF内存泄露:CollectionViewSource.GetDefaultView导致Cache对象
  6. 40:数组中只出现一次的数字
  7. Kafka eagle 安装
  8. java读取propertiesshib,Java CommonUtils.constructServiceUrl方法代码示例
  9. 自定义应用程序配置文件(app.config)
  10. angular语言前端开发_2020年前端Angular招聘-前端Angular招聘求职信息-拉勾招聘
  11. IEEE COMMUNICATIONS LETTERS 写作Latex模板
  12. LCD显示屏的器件选择和驱动电路设计
  13. 视频教程-H3CNE认证网络工程师视频课程-H3C认证
  14. linux开机启动界面异常,Linux 界面不能启动的解决
  15. UI设计中线面结合图标设计总结
  16. vivo在CES上展示的屏下指纹识别,能打败苹果的Face ID吗?
  17. flutter 保存图片
  18. 【PyTorch】5 姓氏生成RNN实战——使用语言生成名称
  19. failed to push some refs to 'git@xxx.xxx.xxx.xxx:finger-shoot/shoot-admin.git'
  20. Ubuntu 22 04 LTS gcc 安装失败

热门文章

  1. Imagination发布PowerVR软件开发套件和工具包重要更新版本,含光线追踪代码示例...
  2. 跟我一起水疗的哥俩儿,其实挺猛的!
  3. 如何理解“修身齐家治国平天下”这句儒家经典
  4. 《大学》修身、齐家、治国、平天下
  5. Google IO 2022——CSS 状态
  6. 每年10万被动收入目标分解 | 进击
  7. 同步AOKP源码的方法
  8. 解决拉取远程分支后出现.xcodeproj Couldn't load project的问题
  9. MyBatis框架总结
  10. java邮箱exchange_Exchange服务器之java mail 使用:exchange邮箱