JDBC

    技术2022-07-11  135

    JDBC(Java DataBase Connectivity)

    JDBC 简介

    Java 数据库连接技术。即用 Java 程序操作数据库的一套接口。是独立与 特定数据库(MySQL、SQLServer) 的管理系统,也就是无论使用的是什么类型的数据库都可以用 JDBC 去连接。

    让 JDBC 去翻译底层数据库的各种指令,我们只需要使用 JDBC 的接口即可。大大提高了开发效率和维护成本,像极了 Java 跨平台的功能。

    JDBC 体系接口

    面向应用的 API,供程序员调用面向数据库的 API,供厂商开发数据库的驱动程序。

    JDBC API

    提供者:Java 官方

    内容:供开发者调用的接口

    java.sql 和 javax.sql

    DriverManager 类Connection接口 ,由 DriverManager类获得此对象Statement接口 由 Connection 对象获得此对象ResultSet接口 由 Statement 对象的 executeQuery() 方法返回此对象

    DriverManager

    提供者:Java 官方

    作用:管理不同的 JDBC 驱动

    JDBC 驱动

    提供者:各大数据库厂商

    作用:负责连接不同的数据库

    JDBC 的使用

    1.加载数据库驱动,Java 程序和数据库之间的桥梁。

    因为数据库驱动由数据库厂商提供,所以不属于 Java 中的资源。需要导入这个外部驱动资源。在 JavaWeb 工程中就导入web/lib文件夹下,在 Java 工程中就新建一个与 src 同级的 lib 文件夹并导入。

    Class.forName("com.mysql.cj.jdbc.Driver")获取运行时类(加载到内存中的类),加载驱动,即将驱动加载到虚拟机内存中。

    之前连接数据库都是直接用 UI 界面连接,在 Java 代码中都需要去实现 URL,User,Password 这些参数。

    Java 代码中连接数据库所需要的 URL

    2.获取 Connection,Java 程序与数据库的一次连接。

    // 获取连接 String url = "jdbc:mysql://localhost:3306/study"; // 最后一个斜杠表示要访问 study 数据库 url += "?useUnicode=true&characterEncoding=UTF-8"; // 处理中文乱码 String user = "root", // 数据库用户名 password = "password"; // 数据库密码 try { Connection connection = DriverManager.getConnection(url, user, password); // 相当于 UI 界面真的连接 System.out.println(connection); // 若连接成功则可以正确输出 connection 对象 } catch (SQLException e) { e.printStackTrace(); }

    输出

    若密码错误,则输出:

    3.创建 Statement 对象,由 Connection 产生 ,执行 SQL 语句。

    如果是对数据库进行增、删、改操作,则使用 Statement 对象的executeUpdate(sql) 方法,返回 int 型,表示修改了数据库几行的元组。如果是查询数据库,则使用 Statement 对象的 executeQuery(sql) 方法,返回 ResultSet 对象。

    这里我想访问 study 数据库,student 表中的信息。

    代码如下:

    String sql = "INSERT INTO Student(S_no, Class_no, S_name, Ssex, S_birthday) VALUES('001103', 'js2222', 'JavaTest', '男', '1999-09-10');"; Statement statement = connection.createStatement(); int result = statement.executeUpdate(sql); // 执行 sql 语句,result 表示影响了数据库几行

    4.如果需要接收返回值,创建 ResultSet 对象,保存Statement 执行之后查询到的结果。

    ResultSet 对象的 next() 方法可以用来判断查询是否为空集

    String sqlQuery = "SELECT * FROM student;"; ResultSet resultSet = statement.executeQuery(sqlQuery); while (resultSet.next()) { // next 将 resultSet 内部的一个指针加 1(指针初始位置为第0行,也就指向表的属性行),指向下一行,返回是否存在下一行的 Boolean String S_no = resultSet.getString(1); // 可以使用列属性的序号来取属性值 String Class_no = resultSet.getString("Class_no"); // 可以使用数据库表中的 属性名 来取 属性值 String S_name = resultSet.getString(3); String Ssex = resultSet.getString("Ssex"); Date S_birthday = resultSet.getDate("S_birthday"); System.out.println(S_no + "-" + Class_no + "-" + S_name + "-" + Ssex + "-" + S_birthday); }

    PreparedStatement

    Statement 的子类,提供了 SQL 占位符的功能。实际开发中都是使用 PreparedStatement 。

    使用 Statement 进行开发有两个问题:

    需要频繁拼接 String 字符串,出错率较高。

    存在 SQL 注入的风险。

    SQL 注入:利用某些系统没有对用户输入的信息进行充分的检测,在用户输入的数据中注入非法的 SQL 语句,从而利用系统的 SQL 引擎完成恶意行为的做法。

    preparedStatement 的用法

    与 Statement 的用法不同,preparedStatement 在利用 Connection 对象创建自身时就写入 sql 语句当作参数,而调用 此 sql 语句的方法中不需要再写 sql 语句当作参数。

    // 在 sql 语句中添加占位符 ?,减少出错概率 String sqlQueryZ = "SELECT * FROM student WHERE Class_no = ? AND Ssex = ?"; // 有2个问号占位符 PreparedStatement preparedStatement = connection.prepareStatement(sqlQueryZ); // 属性是什么类型就调用什么 set类型 的方法 preparedStatement.setString(1, "js0001"); // 表示替换第1个问号占位符的值 preparedStatement.setString(2, "男"); // 表示替换第2个问号占位符的值 ResultSet resultSetP = preparedStatement.executeQuery(); if (resultSetP.next()) { System.out.println("查询成功"); } else { System.out.println("查询失败"); } System.out.println(sqlQueryZ); // sqlQueryZ equals "SELECT * FROM student WHERE Class_no = 'js0001' AND Ssex = '男'"

    5.断开连接

    一定要记得断开连接!!

    resultSet.close(); preparedStatement.close(); statement.close(); connection.close();

    注意事项

    若想要插入mySQL 数据的大小超过了 数据库中对应类型的数据范围,则后端会报异常。对于后端的 Double 类数据,数据库中存储的数据类型应该是 DOUBLE !!使用 decimal 也会插入成功,但是会损失精度,这 一点 不容易察觉。
    Processed: 0.010, SQL: 9