前言
最近在总结MyBatis的时候了解到,MyBatis的底层使用的就是JDBC,仔细想想JDBC是我很久之前学过的东西了,现在难免有些遗忘,所以打算重新拿出来写一下,毕竟理解了JDBC的工作原理和原始API的使用,对理解框架也会有很大的帮助。
<---------------- 正文开始 ---------------->
真正在公司中操作数据库,99%是通过代码来操作的,很少会手动在客户端里输入sql语句。各种数据库:MySQL,Oracle,SQL Sever…… 在开发的时候,就会提供一组编程接口(API),这些数据库提供的API不同,给程序员的学习带来了很大压力,于是Java官方定义了自己的数据库接口规范—— JDBC。
一、导入驱动依赖
数据库厂商提供一个程序来完成API的转换,对原生API封装,在提供成JDBC形状。java程序员想要进行数据库开发就需要在你的项目中导入对应 数据库的驱动包 才能编写代码。关于驱动包的获取,可以在Maven中央仓库中获取:https://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.49
PS:注意驱动包的版本,大版本要和数据库服务器匹配,比如我当前的数据库服务器版本是MySQL5.7,那么驱动版本需要是 5.x。
我们以一个Maven项目为例,只需要在 pom.xml 中导入以下依赖即可:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency>
二、建立数据库连接
1、创建并初始化数据源
在JDBC编程中,数据源(DataSource)是一个提供数据库连接的对象,它通常包含了数据库的URL、用户名和密码等信息。
//1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("123456");
二、建立数据库连接
1、创建并初始化数据源
在JDBC编程中,数据源(DataSource)是一个提供数据库连接的对象,它通常包含了数据库的URL、用户名和密码等信息。
//1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("123456");
PS:jdbc:mysql://数据库服务器IP地址:数据库服务器端口号/数据库名?characterEncoding=utf8&useSSL=false
。这是数据库的连接字符串,可以认为是固定格式写死的。
2、和数据库服务器建立连接
//2.和数据库服务器建立连接 Connection connection = dataSource.getConnection();
三、创建Statement或PrepareStatement对象
Statement
和PrepareStatement
都是通过建立的 connection 连接获取到的,用于执行SQL的接口:
Statement statement = connection.createStatement();
String sql = "SELECT * FROM mytable WHERE column = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql);
Statement对象用于执行静态的SQL语句,即在编写代码时已经确定了SQL语句的内容。这种方式是存在SQL注入风险的,因为使用Statement对象执行的SQL语句一般都是经过拼接而成的,如果传过来的参数存在SQL关键字就可能拼接出一条恶意的SQL。
PrepareStatement对象它通过预编译SQL语句,可以防止SQL注入攻击(前提是不使用拼接SQL)。PrepareStatement对象的SQL语句中可以包含占位符(例如?),在执行时需要为这些占位符指定具体的数值。这种方式可以有效地防止恶意输入对SQL语句的破坏。在实际开发中,推荐使用。
四、执行SQL语句
Statement对象执行SQL语句:
ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable");
PrepareStatement对象执行SQL语句:
// 设置参数 preparedStatement.setString(1, "somevalue"); ResultSet resultSet = preparedStatement.executeQuery();
五、处理结果
对于不同的SQL语句,执行后返回的结果是不一样的,但总体分为两大类:
- 增删改语句:返回
int
类型的受影响的行数。- 查询语句:返回
ResultSet
类型的结果集。
对于 int 类型的受影响的行数这个都好理解,这里重点介绍一下 ResultSet
结果集。
while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); double salary = resultSet.getDouble("salary"); // 处理获取到的数据 // ... }
next() 是 ResultSet 接口提供的方法之一,用于在结果集中移动到下一行数据。它的作用是将指针从当前行移动到下一行,并返回一个布尔值,表示是否存在下一行数据。需要注意的是,第一次调用
.next() 方法将把指针移动到结果集的第一行(如果存在)。因此,在处理结果集之前,通常会先调用 .next()
方法一次,以确保指针指向第一行数据。
使用 ResultSet 对象提供的方法,您可以遍历获取查询结果集中的数据。常用的获取数据的方法包括getInt()、getString()、getDouble()等。
六、关闭连接
如果不主动关闭连接,这些资源将一直被占用,连接池中的连接数量会不断增加,而不会被回收,会导致内存泄漏的问题。
关闭连接的顺序是很重要的。应按照从小到大的顺序关闭资源,即按照申请资源的逆顺序进行:先关闭 ResultSet,再关闭 Statement 或 PreparedStatement,最后关闭 Connection.
// jdbc连接处理代码 // ... // 关闭连接 // 1.如果在代码中使用了 ResultSet 对象,需要先关闭它。 resultSet.close(); // 2.关闭相应的 PreparedStatement 对象。 preparedStatement.close(); // 3.关闭与数据库的连接 connection.close();
为了确保资源的正确释放,避免遗忘,可以使用 try-with-resources
语句块来自动关闭资源:
try ( Connection connection = DriverManager.getConnection(url, username, password); PreparedStatement statement = connection.prepareStatement(sql); ResultSet resultSet = statement.executeQuery() ) { // 处理查询结果 // ... } catch (SQLException e) { // 处理异常 // ... }
七、使用示例
正文部分到这里基本就结束了,下面给出使用JDBC进行 增
、删
、查
、改
的示例供大家参考和进一步理解:
1、Insert-添加
public class JDBCinsert { public static void main(String[] args) throws SQLException { Scanner scanner = new Scanner(System.in); //1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("myname"); ((MysqlDataSource)dataSource).setPassword("mypassword"); //2.建立连接 Connection connection = dataSource.getConnection(); //3.构造SQL语句 String sql = "insert into student values(?,?)"; //4.SQL预编译 PreparedStatement statement = connection.prepareStatement(sql); System.out.print("请输入更新数据条目:"); int n = scanner.nextInt(); while (n!=0) { //5.用户输入 System.out.print("请输入学生姓名:"); scanner.nextLine(); String name = scanner.nextLine(); System.out.print("请输入学生id:"); int id = scanner.nextInt(); statement.setInt(1,id); statement.setString(2,name); //6.执行sql int ret = statement.executeUpdate(); System.out.println("affected:"+ret); //打印拼接后结果 System.out.println(statement); n--; } //7.关闭资源 statement.close(); connection.close(); } }
2、delete-删除
public class JDBCdelete { public static void main(String[] args) throws SQLException { Scanner scanner = new Scanner(System.in); //1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("myname"); ((MysqlDataSource)dataSource).setPassword("mypassword"); //2.和数据库服务器建立连接 Connection connection = dataSource.getConnection(); //3.构造SQL语句 String sql = "delete from student where id = ?"; //4.让客户端对SQL进行预编译 PreparedStatement statement = connection.prepareStatement(sql); int id = scanner.nextInt(); statement.setInt(1,id); System.out.println(statement); //5.执行SQL语句 int ret = statement.executeUpdate(); System.out.println("affected:"+ret); //6.关闭资源 statement.close(); connection.close(); } }
3、select-查询
public class JDBCselect { public static void main(String[] args) throws SQLException { //1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydata?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword("Ls03313517"); //2.和数据库服务器建立连接 Connection connection = dataSource.getConnection(); //3.构造SQL语句 String sql = "select * from student"; //4.让客户端对sql预编译 PreparedStatement statement = connection.prepareStatement(sql); //5.执行SQL语句 ResultSet resultSet = statement.executeQuery(); //6.获取结果集合 while (resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println("学号:"+id+" 姓名:"+name); } //7.关闭资源 resultSet.close(); statement.close(); connection.close(); } }
4、update-修改
public class JDBCupdate { public static void main(String[] args) throws SQLException { Scanner scanner = new Scanner(System.in); //1.创建并初始化数据源 DataSource dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/mydatabase?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("myname"); ((MysqlDataSource)dataSource).setPassword("mypassword"); //2.和数据库服务器建立连接 Connection connection = dataSource.getConnection(); //3.构造SQL语句 String sql = "update student set name = ? where id = ?"; //4.让客户端对SQL语句进行预编译 PreparedStatement statement = connection.prepareStatement(sql); System.out.print("请输入需要修改条目对应id:"); int id = scanner.nextInt(); scanner.nextLine(); System.out.print("请输入更新name:"); String name = scanner.nextLine(); statement.setInt(2,id); statement.setString(1,name); //打印构造完成的SQL语句 System.out.println(statement); //5.执行SQL语句 int ret = statement.executeUpdate(); System.out.println("affected:"+ret); //6.释放资源 statement.close(); connection.close(); } }