JDBC
- 执行SQL语句的Java API;
- 连接数据库,创建SQL或MySQL语句,在数据库中执行SQL或MySQL查询,查看和修改生成的记录
体系结构
- 两层:
- JDBC API:应用程序(Java Application)到管理器JDBC Driver Manager
- JDBC驱动程序API:JDBC Driver Manager到驱动程序
核心组件
- DriverManager、Driver、Connection、Statement、ResultSet、SQLException
使用步骤
-
构建JDBC应用程序涉及以下六个步骤:
-
导入包:需要包含包含数据库编程所需的JDBC类的包。大多数情况下,使用import java.sql.*就足够
了。 -
注册JDBC驱动程序:要求您初始化驱动程序,以便您可以打开与数据库的通信通道。
//加载驱动 Class.forName("驱动名称");//将驱动程序的类文件动态加载到内存中,并将其自动注册
-
打开连接:需要使用
DriverManager.getConnection()
方法创建一个Connection对象,该对象表
示与数据库的物理连接。//数据库URL配置 //三个重载方法 - getConnection(String url) - getConnection(String url,Properties prop) - getConnection(String url,String user,String password)
RDBMS DBC驱动程序名称 网址格式 MYSQL8 com.mysql.cj.jdbc.Driver jdbc:mysql://hostname:3306/databaseName?serverTimezone=UTC MySQL com.mysql.jdbc.Driver jdbc:mysql://hostname:3306/databaseName ORACLE oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@hostname:port Number:databaseName DB2 COM.ibm.db2.jdbc.net.DB2Driver jdbc:db2:hostname:port Number / databaseName SYBASE com.sybase.jdbc.SybDriver jdbc:sybase:Tds:hostname:port Number / databaseName
-
执行查询:需要使用类型为Statement的对象来构建和提交SQL语句到数据库。
//定义SQL,创建状态通道(进行SQL语句发送) 需要使用Connection对象的createStatement()方法创建一个Statement对象 //执行一个SQL语句 - boolean execute(String SQL):如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返 回false。使用此方法执行SQL DDL语句或需要使用真正的动态SQL时。 - int executeUpdate(String SQL):返回受SQL语句执行影响的行数。使用此方法执行预期会影响 多个行的SQL语句,例如INSERT,UPDATE或DELETE语句。返回值为受影响的行数,>0则执行成功 - ResultSet executeQuery(String SQL):返回一个ResultSet对象。当您希望获得结果集时,请使 用此方法,就像使用SELECT语句一样。 //返回一个结果集对象
-
从结果集中提取数据:需要使用相应的
ResultSet.getXXX()
方法从结果集中检索数据。ResultSet.getXXX("列名");//XXX表示数据类型
-
释放资源:需要明确地关闭所有数据库资源,而不依赖于JVM的垃圾收集。
if(resultSet != null){resultSet.close();} //statement,connection同样
-
SQL注入
String username ="admin";
String password=" 'abc' or 1=1 ";
String sql="select * from users where username= '"+username+"' and password=
"+password;
//也能成功登入-安全漏洞
PreparedStatement(预状态通道)
-
供了一个通用的Statement对象有两个优点附加功能:
-
动态地提供参数
变量替换的位置用问号
//3.定义SQL,创建状态通道(进行SQL语句发送) String sql = "select * from users where username=? and password=?"; PreparedStatenment pps = connection.preparedStatenment(sql); //给占位符赋值 (下标,内容) 下标从1开始 pps.setXXX(1,uname); pps.setXXX(2,upass);
-
-
对比statement和PreparedStatement:
(1)statement属于状态通道,PreparedStatement属于预状态通道
(2)预状态通道会先编译sql语句,再去执行,比statement执行效率高
(3)预状态通道支持占位符?,给占位符赋值的时候,位置从1开始
(4)预状态通道可以防止sql注入,原因:预状态通道在处理值的时候以字符串的方式处理
多表操作
两表关系:
- 外键
- 实体类通过属性的方式,实体类要求:类名=表名,列名=属性名
一对多
老师学生
- 在一方创建存储多方数据的集合;
多对一
学生老师
在多方创建一个存储一方的对象
一对一
老婆老公
多对多
科目学生
数据库事务
-
一组要么同时执行成功,要么同时执行失败的SQL语句。是数据库操作的一个执行单元。
-
事务开始于:
-
连接到数据库上,并执行一条DML语句insert、update或delete
-
前一个事务结束后,又输入了另一条DML语句
-
-
事务结束于:
- 执行commit或rollback语句。
- 执行一条DDL语句,例如create table语句,在这种情况下,会自动执行commit语句。
- 执行一条DDL语句,例如grant语句,在这种情况下,会自动执行commit。
- 断开与数据库的连接
- 执行了一条DML语句,该语句却失败了,在这种情况中,会为这个无效的DML语句执行rollback语
句。
-
四大特点:ACID
-
事务应用:
如果JDBC连接处于自动提交模式,默认情况下,则每个SQL语句在完成后都会提交到数据库;
要启用手动事务支持,请使用Connection对象的
setAutoCommit()
方法。如果将boolean false传递给setAutoCommit()
,则关闭自动提交。我们可以传递一个布尔值true来重新打开它。
保存点
- **Savepoints接口:**为您提供了额外的事务控制
- 设置保存点时,可以在事务中定义逻辑回滚点。如果通过保存点发生错误,则可以使用回滚方法来撤消
所有更改或仅保存在保存点之后所做的更改。
-
Connection对象有两种新的方法来帮助您管理保存点:
-
setSavepoint(String savepointName)
:定义新的保存点。它还返回一个Savepoint对象 -
releaseSavepoint(Savepoint savepointName)
:删除保存点。请注意,它需要一个Savepoint对象作为参数。此对象通常是由
setSavepoint()
方法生成的保存点。
-
批处理
- 一次向数据库发送多个SQL语句时,可以减少连接数据库的开销,从而提高性能。
- 手动提交
###Statement
典型步骤序列:
- 使用createStatement()方法创建Statement对象 如:stmt。
- 使用setAutoCommit()将auto-commit设置为false 。
- 使用addBatch()方法在创建的语句对象上添加您喜欢的SQL语句到批处理中。stmt.addBatch(SQL)
- 在创建的语句对象上使用executeBatch()方法执行所有SQL语句。 int[] count = stmt.executeBatch();
- 最后,使用commit()方法提交所有更改。
PreparedStatement
反射处理结果集
工具类的定义
DBUtil
用protected修饰方法,在DaoImpl中继承extends DBUtil;
连接池
-
数据连接池原理:
在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。
使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。
同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等,也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
自定义连接池
-
-
java规范实现
一个规范(接口),规范的写法,我们需要实现DataSource接口;
弊端:没有提供回收链接方法
DBCP连接池
- DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池,DBCP可以直接的在应用程序中
使用,Tomcat的数据源使用的就是DBCP - 使用:
- 导入相应jar包
- 硬编码使用DBCP(在代码中添加配置)
- 软编码使用DBCP(项目中添加配置文件,这样就不需要每次代码中添加配合)
C3P0连接池
- 一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象
- 和DBCP相比:有自动回收空闲连接功能,不需要手动设置。
- 实现方式:
- 手动设置 ComboPooledDataSource
- 加载配置文件方式
Druid(德鲁伊)连接池
-
阿里出品,淘宝和支付宝专用数据库连接池;
-
不仅仅是一个数据库连接池,它还包含一个ProxyDriver(代理驱动),一系列内置的JDBC组件库,一个SQL Parser(sql解析器)。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。
-
目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。
-
特点:
- 亚秒级查询,多租户的设计,是面向用户分析应用的理想方式
- 实时数据注入
- 可扩展的PB级存储
- 多环境部署
-
不仅仅是一个数据库连接池,它还包含一个ProxyDriver(代理驱动),一系列内置的JDBC组件库,一个SQL Parser(sql解析器)。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。
-
目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。
-
特点:
- 亚秒级查询,多租户的设计,是面向用户分析应用的理想方式
- 实时数据注入
- 可扩展的PB级存储
- 多环境部署
- 丰富的社区