JDBC
JDBC学习笔记
简介
JDBC(Java DataBase Connectivity)是Java编程语言中连接数据库的一种标准规范, 其提供了访问许多不同类型数据库的标准化方法,使得Java程序员能够很容易地使用数据库和执行SQL查询,从而方便地与任何数据库进行交互。
- 本质上JDBC就是用来操作关系型数据库的一套API。
JDBC API包含两个级别:
JDBC API:Java应用程序通过这个API与JDBC管理器通信。
JDBC 驱动程序API:这个API定义了Java应用程序和JDBC驱动程序之间的协议。
JDBC可以为所有主流数据库提供统一的访问方式,从而有助于加快Java开发者的工作效率。
下面是个使用java语言操作关系型数据库的一套API
导入jar
举例
public class Main { |
API详解
DriverManager
- 驱动管理类1.注册驱动2.获取数据库连接
- 与各种关系型数据库进行通信。
以下部分方法:
方法 | 解释 |
---|---|
getConnection() | 连接到指定的数据库,并返回一个连接对象 |
getDriver() | 返回一个具体的驱动 |
setLogWriter() | 设置当前应用程序的日志Writer对象 |
getLogWriter() | 获取当前应用程序的日志Writer对象 |
Connection
- 表示与特定的数据库进行连接。
- 一旦获得一个Connection对象,就可以使用它来执行SQL语句。
方法 | 解释 |
---|---|
createStatement() | 创建一个 Statement 对象,用于执行静态 SQL 语句并返回其生成的结果。 |
prepareStatement(String sql) | 创建一个 PreparedStatement 对象,用于将参数化的 SQL 语句发送到数据库。 |
setAutoCommit(boolean autoCommit) | 设置是否启用自动提交模式。如果启用,每个 SQL 语句默认作为事务处理。 |
commit() | 使自上次提交以来所做的所有更改成为永久性更改,并释放 Transaction 对象当前持有的所有锁。 |
rollback() | 撤销自上次提交以来所做的所有更改,并释放 Transaction 对象当前持有的所有锁。 |
close() | 关闭此 Connection 对象并释放与之关联的所有资源。 |
Statement
- 能够执行静态的SQL语句,并返回产生结果。
- 代表在数据库上执行的SQL语句的接口
方法名 | 解释 |
---|---|
executeQuery(String sql) | 执行给定的 SQL 语句,它返回一个 ResultSet 对象。 |
executeUpdate(String sql) | 执行给定的 SQL 语句,它可能会影响数据库中的任何数据。executeUpdate() 方法返回受影响的行数。 |
execute(String sql) | 执行给定的 SQL 语句,该语句可能会返回多个结果。execute() 方法返回一个 boolean 值,指示第一个结果是否是 ResultSet 类型。 |
addBatch(String sql) | 将给定的 SQL 语句添加到当前对象的批处理命令列表中。 |
clearBatch() | 从此 Statement 对象的当前命令列表中删除所有命令。 |
executeBatch() | 提交一批更新命令到数据库。executeBatch() 方法返回一个 int 数组,它表示批处理中每个命令影响的行数。 |
close() | 释放此 Statement 对象使用的所有资源。 |
ResultSet
- 执行查询后返回的对数据库的结果集表示。ResultSet是一个接口,它包含了一个表的所有行以及每个行的各个列的值
方法名 | 解释 |
---|---|
next() | 将结果集中的光标移到下一行。 |
getInt(int columnIndex) 和 getInt(String columnName) | 获取指定列的 int 类型的值。 |
getDouble(int columnIndex) 和 getDouble(String columnName) | 获取指定列的 double 类型的值。 |
getString(int columnIndex) 和 getString(String columnName) | 获取指定列的 String 类型的值。 |
getDate(int columnIndex) 和 getDate(String columnName) | 获取指定列的 java.sql.Date 类型的值。 |
getTime(int columnIndex) 和 getTime(String columnName) | 获取指定列的 java.sql.Time 类型的值。 |
getTimestamp(int columnIndex) 和 getTimestamp(String columnName) | 获取指定列的 java.sql.Timestamp 类型的值。 |
getObject(int columnIndex) 和 getObject(String columnName) | 获取指定列的 java.lang.Object 类型的值。 |
wasNull() | 如果上一次获取的值为空,返回 true。 |
close() | 释放资源,关闭 ResultSet 对象。 |
PreparedStatement
- 继承Statement接口,但能够提供高程序的性能和安全性,对SQL语句进行了预编译处理,并且可以通过参数化查询来防止SQL注入攻击。
方法名 | 解释 |
---|---|
setString(int parameterIndex, String x) | 给指定的参数设置 String 类型的值。 |
setInt(int parameterIndex, int x) | 给指定的参数设置 int 类型的值。 |
setDouble(int parameterIndex, double x) | 给指定的参数设置 double 类型的值。 |
setFloat(int parameterIndex, float x) | 给指定的参数设置 float 类型的值。 |
setLong(int parameterIndex, long x) | 给指定的参数设置 long 类型的值。 |
setDate( int parameterIndex, Date x ) | 给指定的参数设置 java.sql.Date 类型的值。 |
setTime(int parameterIndex, Time x) | 给指定的参数设置 java.sql.Time 类型的值。 |
setTimestamp(int parameterIndex, Timestamp x) | 给指定的参数设置 java.sql.Timestamp 类型的值。 |
setObject(int parameterIndex, Object x) | 给指定的参数设置 Object 类型的值。 |
setNull(int parameterIndex, int sqlType) | 给指定的参数设置 null 值。 |
executeQuery() | 执行带参数的查询并返回 ResultSet 对象。 |
executeUpdate() | 执行带参数的更新语句。 |
addBatch() | 添加一个批处理命令。 |
clearBatch() | 清除所有之前添加的批处理命令。 |
executeBatch() | 执行所有添加的批处理命令。 |
close() | 释放资源,关闭 PreparedStatement 对象。 |
SQL注入
- 常见的数据库漏洞,攻击者利用应用程序对输入数据的过滤和验证不严格,将恶意代码插入SQL语句中,获取到未授权的数据或者执行恶意操作。
- SQL注入是一种比较隐蔽的攻击方式,因为它可以绕过应用程序的认证和访问控制,进而直接利用存在漏洞的SQL语句进行数据库操作。
数据源
- 在实际开发,为了管理连接池和数据源,可以用一些第三方连接池框架,比如C3P0和Druid等
- DataSource作为一个轻量级的数据库连接池,可以大大提高系统的性能,扩展和维护性。使用DataSource时,需要先配置驱动类名,URL,用户名,密码,初始化连接数量,最大连接数量,超时时间等。当应用程序需要连接数据库时候,可以从数据源中获取连接来执行相应操作。
DataSource的获取与释放
- 通过JNDI获取DataSource对象时,通常需要进行初始化,创建一个InitialContext对象,将相关的参数信息放入Context中然后查找数据源。使用后,需要将连接释放会连接池。
//初始化Context对象。
Context ctx = new InitialConrext();、
//根据JNDI名称查找DataSource对象。
DataSource dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/mydb");
//从数据源中获取连接
Connection conn = dataSource.getConnection();
//使用连接进行数据操作
// ..........
//释放连接
conn.close();
数据源的配置方式
- DataSource 可以通过XML或Properties文件进行配置。对Spring框架等,也支持java代码的配置方式来获取数据源
线程安全性
- 为每个线程创建单独的Connection对象。可以使用ThreadLocal对象来保证每个线程都有自己的对象
- 连接池管理连接资源,能够对连接对象进行有效的监控和管理,从而避免了多个线程竞争同一个Connection对象的问题。允许线程取走,但是使用后归还连接池,供其他复用。
- 确保事务的独立性,每个线程会开启事物,提交或回滚事物,可以保证多个线程之间不会干扰彼此。
批处理
简介
- 将多个命令按照顺序集成在一个文件中,批量执行的技术。通过一系列脚本或命令来完成。
Statement处理
- 使用Statement对象进行批处理,通过addBatch()将多个SQL命令添加到一个批处理中去,并使用executeBatch()方法来执行批处理。
|
PreparedStatement处理
同上
String INSERT_SQL = "INSERT INTO user(name,age) values(?,?)"; |
Spring批处理实现大规模数据库操作
- 一般要创建Job,Step,ItemReader,ItemProcessor,ItemWriter
Job:批处理的最顶层组件,表示一个或多个并行 Step 的顺序运行。可以将其视为一个顶级容器,可包含多个 Step。
Step:是 Batch 处理的主要单位,表示一个任务步骤。可以对每一个步骤进行配置,比如设置读取文件、处理逻辑、验证等。
ItemReader:用于读取数据,通常从文件或数据库中读取数据。每次读取一条数据进行处理。
ItemProcessor:对 ItemReader 返回的数据进行进一步处理,可以对数据进行过滤、转换等操作,比如将一定格式的文本转化成 Java 对象。
ItemWriter:根据需要将读取到的数据写入到指定位置,如写入到数据库、写入到文件等。
配置Job和Step
需要创建job和step的配置类,这些将负责配置Batch的核心组件,数据源,事务和监听器,通过XML文件或Java Config 进行配置,实现Batch批处理
public class BatchConfiguration {
private JobBuilderFactory jobs;
private StepBuilderFactory steps;
public Step step1() {
return steps.get("step1")
.<String, String>chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
public Job job(Step step1) throws Exception {
return jobs.get("job")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
//定义具体的 Reader、Processor、Writer
}定义 ItemProcessor、ItemReader 和 ItemWriter
Batch 模块提供了大量优秀的处理器和读写器,这些对象可以快速地实现批处理任务。