目录
前言
什么是JDBC编程
本质
使用JDBC编程的优势
JDBC流程
如何在IEDA上使用JDBC
JDBC编程
1.创建并初始化数据源
2.与数据库服务器建立连接
3.创建PreparedStatement对象编写sql语句
4.执行SQL语句并处理结果集
executeUpdate
executeQuery
5.释放资源
前言
在前面,我们都是在MYSQL上进行编写SQL命令来操作数据库的,那么接下来就来讲解一下如何在IDEA上来操作MYSQL数据库。无论使用哪种框架操作数据库,最底层的API实现都是JDBC,所以掌握好JDBC是至关重要的。
什么是JDBC编程
JDBC,即Java Database Connectivity,java数据库连接。是java用于与关系型数据库进行交互的API,定义了一套连接和操作数据库的规范(接口),允许Java程序连接到不同的数据库(如MySQL,Oracle,SQL Service 等)。
本质
- 定义了一套操作所有关系型数据库的API;
- 要由关系型数据库厂商来实现JDBC的实现类,实现这套接口(驱动包jar);
- 执行语句的代码是驱动包jar中的实现类。
使用JDBC编程的优势
- 可移植性:JDBC具有很好的移植性,在任何支持java的平台上都能使用JDBC进行操作数据库。
- 错误处理和调试:JDBC提供了详细的错误信息和异常处理机制,帮助开发者更好地诊断和解决数据库访问过程中出现的问题。
- 性能优化:支持批处理、结果集缓存等特性,可以提高数据访问的性能。可以使用 PreparedStatement 来重用 SQL 语句,减少解析时间,提高运行效率。
- 易于使用:JDBC 提供了简单易用的 API,使得开发者可以轻松地执行 SQL 查询、更新数据等操作,降低了数据库访问的复杂度。
JDBC流程
- 加载JDBC驱动:可以通过调用Class.forName()方法来加载特定的JDBC驱动,这是最常见的驱动方法。
Class.forName("com.mysql.cj.jdbc.Driver");
2.建立数据库连接:可以使用DriverManager.getConnection()来获取连接,通过指定数据库URL、用户名和密码来创建一个连接对象。
String url = "jdbc:mysql://localhost:3366/databaseName";String user = "root";String password = "root";Connection conn = DriverManager.getConnection(url, user, password);
3.创建操作对象:使用自己已经建立的数据库连接来创建Statement、PreparedStatement 或 CallableStatement 对象以执行 SQL 语句。
Statement statement=conn.createStatement();PreparedStatement preparedStatement=conn.prepareStatement(执行语句);
4.执行sql语句:
根据需要选择合适的方法执行 SQL 语句:
- executeQuery: 用于执行查询语句,返回 ResultSet。
- executeUpdate: 用于执行更新语句(如 INSERT、UPDATE、DELETE)。
- execute: 通用方法,可以执行任何类型的 SQL 语句。
ResultSet rs = stmt.executeQuery("SELECT * FROM table_name");int rowsAffected = stmt.executeUpdate("INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2')");
5.处理结果集:若我们使用的是executeQuery方法来查询,那么想要在java打印出结果,需要使用到ResultSet中的getString等方法来进行获取(对应什么类型就用什么方法,即如果是整型数据,那就用getInt())。
6.关闭连接:当处理完以上的步骤之后,需要关闭所打开的数据库资源。(在打开的时候是从外到内,那么关闭时就应该先关内,再关外)。
了解完什么是JDBC,那么如何在IDEA上使用呢?
如何在IEDA上使用JDBC
这里选择操作的数据库是MySQL的,所以我们首先需要去下载对于驱动包jar
可以去MAVEN官网进行下载。
1.点击进入MAVEN
2.在搜索栏输入mysql
3.按照自己的需求下载,这里从过去的版本中查看
这里由于我使用的是MySql5.7,所以我需要从5.0x中下载驱动包jar。
4.打开jar包所在的文件夹
打开之后,复制jar包,打开IDEA,并创建一个lib目录
5.创建完lib目录之后,点击lib目录,并点击ctrl+v,将jar放进lib目录中
当我们点击完就会看到,此时在lib目录下有着我们的jar包,但此时还不能看到jar中的各种类,我们需要继续进行操作。
到这里,jar中的各种方法我们就能在java中使用了。
JDBC编程
进行JDBC编程,有以下步骤:
- 创建并初始化一个数据源
- 与数据库服务器建立连接
- 创建statement对象编写SQL语句
- 执行SQL语句并处理结果集
- 释放资源
1.创建并初始化数据源
由于Database是一个接口,不能直接实例,但底层有MysqlDatabase类实现了接口,那么我们这里就可以new一个MysqlDatabase类。
public static void main(String[] args) {// 创建MySQL数据源对象DataSource dataSource=new MysqlDataSource();// 设置数据源的URL、用户名和密码((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");// 另一种创建和配置MySQL数据源的方法MysqlDataSource mysqlDataSource=new MysqlDataSource();// 直接在创建对象后设置URL、用户名和密码mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useURL=false");mysqlDataSource.setUser("root");mysqlDataSource.setPassword("123456");}
这里我们创建数据源有两种方式,但推荐第一种,要注意“高内聚低耦合”原则。 第一种若后序想要进行替换成其他数据库,耦合较低,对其他操作影响不大。但对于第二种,若想要修改成其他数据库,需要对其他操作都进行修改,耦合较高。
URL是唯一资源定位符,可以用来定位网络资源的位置,代表着网络中某个资源的绝对路径。
MySQL数据连接的URL参数格式如下:
jdbc:mysql://服务器地址:端口/数据库名?参数名=参数值
除了需要URL,我们还需要设置用户名和密码,用户名都可以,但密码必须是MySQL的登录密码
2.与数据库服务器建立连接
我们需要使用Connection接口,此处的接口需要选择第一个
并连接数据源
Connection connection=dataSource.getConnection();
当我们写出这行代码,会发现getConnection标红
我们可以鼠标放在标红处
这里说明在连接服务器的时候,不是一定能够连接的上的,所以需要抛出SQLException异常。
这种属于受查异常(即在编译阶段呢不能通过),所以必须显示处理(throws抛出,或者使用try-catch)。
public static void main(String[] args) throws SQLException {// 创建MySQL数据源对象DataSource dataSource=new MysqlDataSource();// 设置数据源的URL、用户名和密码((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123456");// 获取数据库连接Connection connection=dataSource.getConnection();}
3.创建PreparedStatement对象编写sql语句
PreparedStatement preparedStatement=connection.prepareStatement(要执行的语句);
我们可以预先编写一个语句
//创建语句String s="insert into student values(1,'张三')";//创建语句对象PreparedStatement preparedStatement=connection.prepareStatement(s);
s是要执行的语句,而通过preparedStatement(s),能够对语句进行预编译。
预编译的好处:让客户端先解析好语句,降低服务器的工作量。
如果sql语句过多,服务器处理时的压力就会越大,让客户端来对sql语句进行预编译,服务器的压力就越少。
4.执行SQL语句并处理结果集
executeQuery() 方法执行后返回单个结果集的,通常用于select语句
executeUpdate()方法返回值是一个整数,指示受影响的行数,通常用于update、insert、delete 语句。
executeUpdate
//返回影响行数int n=preparedStatement.executeUpdate();System.out.println(n);
当运行之后,可以看到n为1
假设我们现在要在控制台中输入,那么我们可以改成
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class Code {public static void main(String[] args) throws SQLException {Scanner scanner=new Scanner(System.in);System.out.println("请输入学号:");int id=scanner.nextInt();System.out.println("请输入姓名:");String name=scanner.next();// 创建MySQL数据源对象DataSource dataSource=new MysqlDataSource();// 设置数据源的URL、用户名和密码((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1517472636");// 获取数据库连接Connection connection=dataSource.getConnection();//创建语句String s="insert into student values("+id+",'"+name+"')";//创建语句对象PreparedStatement preparedStatement=connection.prepareStatement(s);//返回影响行数int n=preparedStatement.executeUpdate();System.out.println(n);//关闭资源preparedStatement.close();connection.close();}
}
但这种写法有缺点:
- 代码较乱,容易写错
- 可能会引起“sql注入攻击”,即当有人故意使坏,在输入的时候再加入语句drop databse 数据库名等操作,会产生一定能过的负面影响。
针对上述这种情况,我们可以使用占位符来进行替换。
即在s字符串中先用?来进行占位,在后序预编译时再进行替换。
//创建语句String s="insert into student values(?,?)";//创建语句对象PreparedStatement preparedStatement=connection.prepareStatement(s);//设置参数preparedStatement.setInt(1,id);preparedStatement.setString(2,name);
注意:索引时从1开始的。根据所要替换的类型来调用方法。
完整代码
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class Code2 {public static void main(String[] args) throws SQLException {Scanner scanner=new Scanner(System.in);System.out.println("请输入学号:");int id=scanner.nextInt();System.out.println("请输入姓名:");String name=scanner.next();// 创建MySQL数据源对象DataSource dataSource=new MysqlDataSource();// 设置数据源的URL、用户名和密码((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1517472636");// 获取数据库连接Connection connection=dataSource.getConnection();//创建语句String s="insert into student values(?,?)";//创建语句对象PreparedStatement preparedStatement=connection.prepareStatement(s);preparedStatement.setInt(1,id);preparedStatement.setString(2,name);//返回影响行数int n=preparedStatement.executeUpdate();System.out.println(n);//关闭资源preparedStatement.close();connection.close();}
}
通过这种方法,能够避免:“sql注入攻击”这种情况。
executeQuery
如果我们想要查看表中的数据,那么需要使用 executeQuery() 方法并用Resultset来接收结果集。
ResultSet表示查询结果的临时表,使用的时候可以当做“集合类”来使用,进行遍历。集合类遍历一般写作:
while(it.hasNext){......it.next();
}
我们可以看student表中现有哪些数据
那么我们在客户端中就需要输出这些数据,代码如下:
ResultSet resultSet=preparedStatement.executeQuery();while(resultSet.next()){System.out.println(resultSet.getInt("id")+" "+resultSet.getString("name"));}
在循环中,每次调用next光标就往下一行移动。
注意:光标不是下标,下标是能够随机访问的,但光标只能顺序遍历每一行。
完整代码
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class Code1 {public static void main(String[] args) throws SQLException {// 创建MySQL数据源对象DataSource dataSource=new MysqlDataSource();// 设置数据源的URL、用户名和密码((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("123");// 获取数据库连接Connection connection=dataSource.getConnection();String s="select * from student";//创建语句对象PreparedStatement preparedStatement=connection.prepareStatement(s);ResultSet resultSet=preparedStatement.executeQuery();while(resultSet.next()){System.out.println(resultSet.getInt("id")+" "+resultSet.getString("name"));}//关闭资源preparedStatement.close();connection.close();}
}
打印结果为
确实是表中的数据。
5.释放资源
//关闭资源preparedStatement.close();connection.close();
当我们呢不需要使用时,需要释放资源,防止占用资源。
以上就是本篇所有内容~
若有不足,欢迎指正~