开发门户网站报价,做抖音风的网站,手机特殊网站,郑州比较大的网络公司我们在学习完了数据库的基本操作后#xff0c;希望和我们的Java程序建立连接#xff0c;那么我们今天就来一探究竟JDBC是如何让Java程序与数据库建立连接的 1. 什么是JDBC
JDBC#xff08;Java Data Base Connectivity, Java数据库连接#xff09; 是Java程序和数据库之间… 我们在学习完了数据库的基本操作后希望和我们的Java程序建立连接那么我们今天就来一探究竟JDBC是如何让Java程序与数据库建立连接的 1. 什么是JDBC
JDBCJava Data Base Connectivity, Java数据库连接 是Java程序和数据库之间的桥梁包含了⼀套Java定义的用于执⾏SQL语句的接口使开发者能够编写数据库的程序。JDBC 的主要作⽤是与数据库建⽴连接、发送SQL语句和处理数据库执行结果。
2. 为什么要使用JDBC
⾸先回顾⼀下使⽤客户端操作数据库的过程主要分为以下几步
a. 确定数据库服务器的地址端口号指定用户名密码 b.连接到数据库服务 c. 发送SQL语句 d. 得到返回结果并显示 e. 断开连接 同样如果使用程序操作数据库也会经历以上几步⼤家应该可以想到为实现上述步骤可以编写相应的代码实现数据库连接发送SQL语句处理结果并显示最后关闭连接。 但是不同的数据库服务器对于同⼀个操作不论是协议还是参数都各有不同如果让程序员自己去实现那就必须针对不同的数据库进行编码实现这个⼯作量和维护成本显然太大。 Java采取的做法是把以上操作步骤定义了相应的接⼝具体的实现交给数据库厂商去做Java程序员只需要按照需要调用接⼝中定义的方法即可这样不论使用什么数据库都对于Java程序没有任何影响即便是换⼀个数据库也只需要换⼀下相应厂商的实现依赖即可。 JDBC使⽤过程可以概括为加载数据库厂商的驱动包、建立连接、创建Statement、执行SQL、 处理结果释放资源和关闭连接。
3. 使用JDBC
3.1 获取MySQL厂商的驱动包依赖JAR包
由于数据库厂商的驱动包过多不好查询我们推荐一个网址里面有所有的数据库厂商提供的驱动包MAVEN 3.2 创建Maven⼯程 3.3 配置国内镜像 mirroridaliyunmaven/idmirrorOf*/mirrorOfname阿⾥云公共仓库/nameurlhttps://maven.aliyun.com/repository/public/url/mirrormirroridcentral/idmirrorOf*/mirrorOfnamealiyun central/nameurlhttps://maven.aliyun.com/repository/central/url/mirror3.4 加载数据库厂商的驱动包
//固定写法其中Driver是一个Java实现的类
Class.forName(com.mysql.cj.jdbc.Driver);3.5 建立连接
使用驱动管理类DriverManager 的静态方法获取数据库连接
Connection connection DriverManager.getConnection(jdbc:mysql://127.0.0.1:3306/yu? characterEncodingutf8 allowPublicKeyRetrievaltrueuseSSLfalse, root, 123456);MySQL数据库连接URL格式jdbc:mysql://127.0.0.1:3306/数据库名?characterEncodingutf8allowPublicKeyRetrievaltrueuseSSLfalse
其中 jdbc:mysql://- 固定写法 127.0.0.13306/ - IP端口号直接使用即可无需修改 yu为我本地数据库 - 根据自己要连接的数据库写即可 characterEncodingutf8 - 字符集编码 allowPublicKeyRetrievaltrueuseSSLfalse- 默认即可 root - 本地数据库名 123456 - 我的数据库连接密码
通过数据源DataSource 对象获取推荐在实际开发中应用这种方式
3.6 创建Statement
Statement是⽤于执⾏静态SQL语句并返回执行结果的对象 // 通过connection获取statement对象
Statement statement connection.createStatement();QQ20241125-232419 3.7 定义SQL语句
//可根据相关需求定义此处仅是示例
String sql select * from student;3.8 执行SQL
执行select查询时返回的是⼀个结果集⽤ResultSet接收
//接受查询结果
ResultSet resultSet statement.executeQuery(sql);接受完后我们可以对接受的结果集进行打印
//执行返回结果while (resultSet.next()) {long id resultSet.getLong(id);String name resultSet.getString(name);String sno resultSet.getString(sno);int age resultSet.getInt(age);short gender resultSet.getShort(gender);Date enrollDate resultSet.getDate(enroll_date);long classId resultSet.getLong(class_id);System.out.println(MessageFormat.format(学生编号{0}, 姓名{1}, 学号{2}, 年龄{3}, 性别{4}, 入学时间{5}, 班级编号{6}, id, name, sno, age, gender, enrollDate, classId));}执行insert,update,delete操作时返回的是受影响的⾏数⽤int类型接收int接受的值用于判断更新操作是否成功1表示成功0表示失败
3.9 处理结果释放资源和关闭连接
在整个数据库访问过程中创建的对象都需要释放包括ResultSetStatement和Connection后创建的先释放建议在try catch 语句后的finally代码块中写入以便程序无论最后是否执行成功都能保证释放资源和关闭连接
if(resultSet!null){resultSetnull;}if(statement!null){statement null;}if(connection!null){connection null;}4. JDBC常用接口和类
4.1 DriverManager 和DataSource
DataSource驱动管理类⽤于管理JDBC驱动程序可以从驱动程序中获取数据库连接始于JDK1.1。DataSource数据源是DriverManager的替代⽅案始于JDK1.4是获取数据库连接的首选方法推荐使用。
4.2 DriverManager 与DataSource的区别
DriverManager和DataSource都可以获取到数据库连接但它们之间存着着⼀些区别主要在于连接的管理方式和资源利用效率连接管理方式不同 ①DriverManager每次调用getConnection方法都会初始化⼀个新的连接上文Driver类中我们注意到过源码中就有new Driver()使用完成后会关闭真实连接导致资源浪费 ②DataSource使用了连接池的技术会在初始化时创建⼀定数量的数据库连接这些连接可以重复使用关闭时并不是真正关闭连接而是将连接归还给连接池以供后续使用有效地提高资源利用率和和性能
4.3 Connection 数据库连接
数据库连接(会话)对象在连接的上下文中执行SQL语句并返回结果
4.3.1 Statement对象
⽤于执⾏静态SQL语句并返回执⾏结果由于只能执⾏静态语句所以这⾥会有⼀个问题假设⼀个语句中需要动态的参数⽐如where⼦句中的条件那么只能通过字符串拼接的⽅式组装完成的SQL语句比如
String sql select * from student where name name and class_id classId;字符串拼接形式构造SQL语句时如果不处理参数中的特殊字符就会造成SQL注⼊这是⼀个非常严重的安全性问题。
4.3.2 SQL注入
4.3.3 PreparedStatement
预编译SQL语句对象SQL语句被预编译并存储在PreparedStatement对象中可以使用该对象多次执行SQL语句同时可以解决SQL注入问题。
示例通过Connection对象获取到PreparedStatement对象需要传⼊SQL模板动态参数用占位符表示 // 获取了个处理SQL的PrepareStatement对象
PreparedStatement preparedStatement connection.prepareStatement(select id,
name, sno, age, gender, enroll_date, class_id from student where name ? and
class_id ?);为动态参数设置真实值下标从1开始 // ⽤真实值去替换占位符
preparedStatement.setString(1, 宋江);
preparedStatement.setLong(2, 2);执行SQL语句
// select 操作
ResultSet resultSet statement.executeQuery();
// insert, update, delete操作
//増 删 改 返回的是受影响的行数
int result statement.executeUpdate();
//1 表示插入成功0表示错误4.3.4 CallableStatement
用于执行SQL存储过程的接⼝。
4.3.5 executeQuery()
执行结果返回的是⼀个结果集通常⽤于select操作
4.3.6 executeUpdate()
执行结果返回的是⼀个整形通常用于insert,update,delete操作
4.3.7 ResultSet结果集
是⼀个查询结果集的数据表通常由执行查询操作的语句生成。ResultSet对象维护了⼀个指向当前数据行的游标最初游标位于第⼀行之前调用next方法将游标移动到下⼀行当ResultSet中没有更多的数据行时返回false所以可以在while循环中使用它来遍历结果集。ResultSet接⼝提供了getter方法(getBoolean、getLong等)用于从当前行检索列值可以使用列的索引号或列的名称来检索值。⼀般来说使用列索引会更有效率索引编号从1开始按照从左到右的顺序读取。
5. 示例
查询名字为唐三藏的信息
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.*;
import java.text.MessageFormat;
import java.util.Scanner;
public class TestDataSource {public static void main(String[] args) {// 定义MYSQL数据源对象MysqlDataSource mysqlDataSource new MysqlDataSource();// 设置数据库连接串mysqlDataSource.setURL(jdbc:mysql://127.0.0.1:3306/yu?characterEncodingutf8allowPublicKeyRetrievaltrueuseSSLfalse);// 用户名mysqlDataSource.setUser(root);// 密码mysqlDataSource.setPassword(123456);// 定义JDBC的数据源对象DataSource dataSource mysqlDataSource;// 定义数据库连接对象Connection connection null;// 定义预处理SQL执行对象PreparedStatement statement null;// 定义结果集对象ResultSet resultSet null;try {// 1. 通过数据源对象获取数据库连接connection dataSource.getConnection();// 定义SQL语String sql select id, name, sno, age, gender, enroll_date, class_id from student where name ?;// 2. 预处理SQL执行对象statement connection.prepareStatement(sql);// 接收用户的输入System.out.println(请输入学生姓名:);Scanner scanner new Scanner(System.in);String inName scanner.next();// 3. 用真实的值替换占位符statement.setString(1, inName);// 4. 执行SQL 获取结果resultSet statement.executeQuery();// 5. 遍历结果集// 6. 遍历结果集获取数据行while (resultSet.next()) {// 获取ID列的值long id resultSet.getLong(1);// 获取name列的值String name resultSet.getString(2);String sno resultSet.getString(3);int age resultSet.getInt(4);byte gender resultSet.getByte(5);Date enrollDate resultSet.getDate(6);long classId resultSet.getLong(7);System.out.println(MessageFormat.format(学生编号{0}, 姓名{1}, 学号{2}, 年龄{3}, 性别{4}, 入学时间{5}, 班级编号{6}, id, name, sno, age, gender, enrollDate, classId));}} catch (SQLException e) {e.printStackTrace();} finally {// 释放结果集对象if (resultSet ! null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}// 释放Statementif (statement ! null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}// 关闭数据库连接if (connection ! null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}