之前我们使用JDBC操作过Oracle数据库(参见Oracle数据库的JDBC查询实例),这次我们来操作一下Mysql,使用Statement对象的子类PreparedStatement:
1、在pom.xml中引入mysql依赖jar包:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency>
2、再调用JDBC的API跟Mysql数据库交互:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class Test { private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; // 数据库驱动的具体实现类 // 数据库链接 private static final String DB_URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=UTC"; private static final String USER = "root"; // 数据库用户名 private static final String PASSWORD = "Wlf12345!"; // 数据库密码 public static void main(String[] args) { String sql = "select NAME from test_wlf where id = ?"; Connection conn = null; PreparedStatement ps = null; try { Class.forName(JDBC_DRIVER); // 0、注册mysql数据库驱动程序,由具体实现类的静态方法调用DriverManager.registerDriver conn = DriverManager.getConnection(DB_URL, USER, PASSWORD); // 1、获取数据库链接对象 ps = conn.prepareStatement(sql); // 2、获取PreparedStatement对象 ps.setInt(1, 2); // 给第一个?问号(参数下标,这里只有一个参数)填值,我们取id为2的name值 ResultSet rs = ps.executeQuery(); // 3、执行SQL while (rs.next()) { String paramName = rs.getString("NAME"); System.out.println("NAME: " + paramName); } rs.close(); } catch (SQLException se) { se.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (ps != null) { conn.close(); } } catch (SQLException se) { } try { if (conn != null) { conn.close(); } } catch (SQLException se) { se.printStackTrace(); } } }
运行结果:
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. NAME: lulu
我们的数据库表里数据如下:
E:BaiduNetdiskDownload>mysql -uroot -pWlf12345! mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 9 Server version: 5.7.26-log MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql> use test; Database changed mysql> desc test_wlf; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(25) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.02 sec) mysql> select * from t_test_wlf; ERROR 1146 (42S02): Table 'test.t_test_wlf' doesn't exist mysql> select * from test_wlf; +------+------+ | id | name | +------+------+ | 1 | wulf | | 2 | lulu | +------+------+ 2 rows in set (0.00 sec)
我们拿Mysql的代码跟之前Oracle比较一番,除了数据库驱动类、数据库链接URL这些之外,就是使用了PreparedStatement。PreparedStatement 接口扩展了 Statement,添加了为语句中包含的参数标记设置值的功能。参数标记(由SQL字符串中的“?”表示)用于指定语句的输入值,这些值可能在运行时发生变化。
PreparedStatement 接口定义 setter 方法,这些方法用于替换预编译 SQL 字符串中每个参数标记的值。如上面例子中setInt方法,第一个参数始终是一个 int,等于要设置的参数标记的序号位置,从1开始(第一个参数标记是id)。第二个参数指定要分配的参数的具体值(id=2)。
如果对JDBC的数据库驱动注册过程感兴趣,比如我们配置的com.mysql.jdbc.Driver是个什么东东,Class.forName(JDBC_DRIVER)有什么用?这些问题可以参见JDBC的驱动注册浅析