JDBC是JAVA DATABASE CONNECTIVITY 是由Sun公司提供的一套帮助Java对接数据库的接口,Sun公司给出对JDBC连接的约束,由各大数据库厂商来实现对接口的实现。用来规范对数据库的连接需求,同时完成对SQL语句的执行的一整套完整的流程。
JDBC核心参数
就拿mysql举例
mysql -hlocalhost -uroot -ppassword
我们需要的元素是,首先是要链接哪个数据库
其次是数据库的地址和端口号,在JDBC中要求的url规范为
jdbc:mysql://localhost:3306/db_name?parameter=value
最后就是账号和密码,都为String类型的字符串
数据库连接核心实例
// 1. 准备必要数据库连接参数
String jdbcUrl = "jdbc:mysql://localhost:3306/gp_01?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "123456";
/*
2. 加载驱动、
Class.forName
1. 可以获取指定类型的 Class 对象
☆2. 如果对应类型当前 Java 程序尚未加载,可以加载指定类型
驱动加载使用的就是 第二个 Class.forName 功能
在jdk1.8之后就不需要再加载驱动,但还是推荐在使用的时候不要丢弃
*/
Class.forName("com.mysql.jdbc.Driver");
// 3. 获取数据库连接对象
Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
// 4. 关闭资源
connection.close();
JDBC常用的API
class java.sql.DriverManger
Java JDBC 驱动管理类,主要负责驱动注册和数据库连接对象获取
常用方法:
public static void registerDriver(java.sql.Driver driver);
注册符合 JDBC 规范要求的 Driver 对象,增强当前 Java 程序,可以操作数据库
public static java.sql.Connection getConnection(String jdbcUrl, String username,
String password)
根据提供的 JdbcUrl JDBC 数据库连接规范 URL,对应的数据库用户名和密码获取到数据库
java.sql.Connection 连接对象
interface java.sql.Connection
Java JDBC 数据库连接对象接口,主要用于获取数据库连接相关的信息,获取数据库 SQL 搬运工对象
常用方法:
public java.sql.Statement createStatement();
通过该数据库连接对象,获取对应当前数据库的 SQL 语句搬运工对象
public java.sql.PreparedStatement prepareStatement(String sql);
通过该数据库连接对象,根据参数 SQL 语句,获取对应当前数据库的 SQL 语句预处理搬运工对象。
interface java.sql.Statment
常用方法:
public int executeUpdate(String sql);
执行 SQL 语句更新操作,主要可以执行的 SQL 语句类型为 insert,update,delete 操作,返回值是
int 类型,返回值是当前 SQL 语句执行,对应数据表受到影响的行数。
Query OK, 1 row affected(5ms)
public java.sql.Resultset executeQuery(String sql);
执行 SQL 语句查询操作,主要可以执行的 SQL 语句类型为 select 操作,返回值为
java.sql.ResultSet 数据库查询结果集对象。
interface java.sql.PreparedStatment extends java.sql.Statment
常用方法:
public void setXXX(int index, XXX value);
可以给予 SQL 语句参数赋值操作,第一个参数是 SQL 语句参数下标位置(从 1 开始),给予当前 SQL 语句
的实际参数。类型支持任意类型(int, double, float, long, Object, String ...)
public int executeUpdate();
执行 SQL 语句更新操作,主要可以执行的 SQL 语句类型为 insert,update,delete 操作,返回值是
int 类型,返回值是当前 SQL 语句执行,对应数据表受到影响的行数。
Query OK, 1 row affected(5ms)
public java.sql.Resultset executeQuery();
执行 SQL 语句查询操作,主要可以执行的 SQL 语句类型为 select 操作,返回值为
java.sql.ResultSet 数据库查询结果集对象。
Java JDBC 规范 数据库搬运工对象,在项目中主要处理的 SQL
interface java.sql.ResultSet
Java JDBC 规范,数据库查询结果集对象。可以认为是 select 查询 SQL 语句最终结果表格对应的 Java 类型。
常用方法:
XXX getXXX(String columnName);
根据列名/字段名,获取数据库当前数据行对应的数据信息,类型可以是任意类型,但是要求和数据库存储类型
一致。支持(int, String, Long...)
XXX getXXX(int columnIndex);
根据列下标,获取数据库当前数据行对应的数据信息,类型可以是任意类型,但是要求和数据库存储类型一致。
支持(int, String, Long...)
【注意】列下标从 1 开始
boolean next();
1. 判断当前数据库查询结果集对象是否还有数据行可以解析,如果可以返回 true,否则返回 false
2. 提取当前数据行进行解析操作,同时指向下一行数据
JDBC封装
可以根据sql语句的不同可以分为两类处理方式
一个是查询excuteQuery,一个是更新excuteUpdate
数据库连接工具
数据库连接工具需要具备数据库连接功能
数据库获取对象操作,数据库资源相关操作
关闭数据库资源操作
public class JdbcUtils {
/**
* 用于存储 JDBC 协议的 URL 连接
*/
private static String jdbcUrl;
/**
* 当前数据库连接操作对应的用户名
*/
private static String username;
/**
* 当前数据库连接操作对应的密码
*/
private static String password;
/*
利用静态代码块在类文件加载阶段的必须执行的特征,完成自动化配置加载,驱动加载操作
*/
static {
// 1. 找到 src 目录下 或者后期 Maven 项目 resource 资源目录下的配置文件 jdbc.properties
InputStream input = JdbcUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
// 2. 实例化 Properties 对象,底层数据存储结构为 Map 键值对结构
Properties properties = new Properties();
try {
// 3. Properties 对象加载对应配置文件字节输入流对象,完成配置文件自动解析
properties.load(input);
// 4. 数据库连接必要的参数提供
jdbcUrl = properties.getProperty("jdbcUrl");
username = properties.getProperty("username");
password = properties.getProperty("password");
// 5. 加载驱动
Class.forName(properties.getProperty("driverClass"));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
// 6. 关闭文件资源
try {
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 获取数据库连接对象方法
*
* @return java.sql.Connection 数据库连接对象
*/
public static Connection getConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcUrl, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/**
* 关闭资源方法
*
* @param connection java.sql.Connection 数据库连接对象资源
* @param statement java.sql.Statement 数据库 SQL 语句搬运工资源
*/
public static void close(Connection connection, Statement statement) {
close(statement, connection);
}
/**
* 关闭资源方法
*
* @param connection java.sql.Connection 数据库连接对象资源
* @param statement java.sql.Statement 数据库 SQL 语句搬运工资源
* @param resultSet java.sql.ResultSet 数据库查询结果集对象
*/
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
close(resultSet, statement, connection);
}
/**
* 内部私有化方法,统一处理数据库相关资源
*
* @param resources AutoCloseable 不定长参数,统一关闭对应资源
*/
private static void close(AutoCloseable... resources) {
if (resources != null && resources.length > 0) {
Arrays.stream(resources).forEach(source -> {
try {
if (source != null) {
source.close();
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
}
结果集处理接口
除了要对连接工具和数据处理工具之外,还需要有对查询到结果集的处理
自定义ResultSetHandler
@FunctionalInterface
public interface ResultSetHandler<T> {
/**
* 结果集处理规范方法,用于处理 java.sql.ResultSet 查询结果集
*
* @param res java.sql.ResultSet 查询结果集对象
* @return 泛型约束,由实现类决定最终的返回数据
*/
T handle(ResultSet res);
}
public class MapHandler implements ResultSetHandler<Map<String, Object>> {
@Override
public Map<String, Object> handle(ResultSet res) throws SQLException {
Map<String, Object> map = null;
// 1. 获取结果集元数据对象
ResultSetMetaData metaData = res.getMetaData();
// 2. 获取字段个数
int columnCount = metaData.getColumnCount();
if (res.next()) {
// 3. 实例化 Map 双边队列,键值对个数为 columnCount
map = new HashMap<String, Object>(columnCount);
for (int i = 1; i <= columnCount; i++) {
// 4. 从元数据中获取对应的字段名称,并且从结果集中获取对应的字段数据,存储到 Map 中
map.put(metaData.getColumnName(i), res.getObject(i));
}
}
return map;
}
}
总结:封装后的JDBC使用
try {
// 获取数据库连接对象
connection = jdbcUtils.getConnection()
// 获取 SQL 语句搬运工对象
statement = connection.createStatement();
// 准备 SQL 语句
String sql = "select * from student where id = 1";
// 执行 SQL 语句,得到 ResultSet 结果集对象【重点】
resultSet = statement.executeQuery(sql);
resulySet = ResultSetHandler.resultSetHandler(resultSet);
}
} catch (ClassNotFoundException | SQLException e) {
throw new RuntimeException(e);
} finally {
close(connection,statement,resultSet);
}
如有不足,私信或者评论指正,肥肠感激。🙋