JDBC(Java Database Connectivity)是 Java 连接数据库的标准接口,它提供了一种与数据库交互的统一方式,使得 Java 程序能够通过标准 API 访问和操作各种关系型数据库。
第0步:导bao
第1步:注册驱动(仅需一次)
第2步:建立链接(Connection)
第3步:创建语句传输对象(Statement)
第4步:运行sql语句
第5步:处理运行结果(ResultSet)
第6步:释放资源
其中,如果是添加,删除,更新操作,可以没有第五步,查询肯定有第五步。
下载相应版本的jar包(下载地址:Maven Repository: MySQL (mvnrepository.com))
![]()
创建Java项目 ——> 在项目下创建lib文件夹——> 将jar包复制到lib文件夹下——> 右键——> Build Path ——> Add to Build Path
创建java类 JDBC_00 (类名随意)
- // 1. 注册驱动
- Class.forName("com.mysql.cj.jdbc.Driver");
- // 2. 创建链接对象
- // 如果出现乱码等问题 可以在url后添加设置编码方式
- // url : jdbc:mysql://IP:端口/数据库?useUnicode=true&characterEncoding=utf-8
- Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "root");
- // 3. 创建语句传输对象
- Statement statement = conn.createStatement();
- String sql = "select * from student";
- // 4. 执行sql语句获取结果集
- ResultSet rs = statement.executeQuery(sql);
- // 5. 处理结果集数据
- while (rs.next()) {
- // 根据列名获取数据
- int id = rs.getInt("id");
- // 根据列的索引获取数据,不建议使用,
- // int id = rs.getInt(1);
- String name = rs.getString("name");
- int tid = rs.getInt("teacher_id");
- double score = rs.getDouble("score");
- System.out.println(id + "--" + name + "--" + tid + "--" + score);
- }
- // 6. 关闭资源
- rs.close();
- statement.close();
- conn.close();
添加try...catch...finally异常处理
- public class JDBC_00 {
- public static void main(String[] args) {
- Connection conn = null;
- Statement statement = null;
- ResultSet rs = null;
- try {
- // 1. 注册驱动
- Class.forName("com.mysql.cj.jdbc.Driver");
- // 2. 创建链接对象
- // 如果出现乱码等问题 可以在url后添加东西
- // url : jdbc:mysql://IP:端口/数据库?useUnicode=true&characterEncoding=utf-8
- conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "abc280619SS");
- // 3. 创建语句传输对象
- statement = conn.createStatement();
- String sql = "select * from student";
- // 4. 执行sql语句获取结果集
- rs = statement.executeQuery(sql);
- // 5. 处理结果集数据
- while (rs.next()) {
- // 根据列名获取数据
- int id = rs.getInt("id");
- // 根据列的索引获取数据,不建议使用,
- // int id = rs.getInt(1);
- String name = rs.getString("name");
- int tid = rs.getInt("teacher_id");
- double score = rs.getDouble("score");
- System.out.println(id + "--" + name + "--" + tid + "--" + score);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- try {
- // 6. 关闭资源,先打开的后关闭
- rs.close();
- statement.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- }
-
- }
- }
Data Manipulation Language : 数据操作语言
涉及的关键字有 : delete,update,insert
和查询的操作几乎一样,就是把第4步和第5步更改一下
- public class JDBC_02 {
- public static void main(String[] args) {
- Connection conn = null;
- Statement statement = null;
- try {
- // 加载驱动
- Class.forName("com.mysql.cj.jdbc.Driver");
- // 创建链接对象
- conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02", "root", "abc280619SS");
- // 创建语句传输对象
- statement = conn.createStatement();
- // 编写sql语句
- // 添加
- String sql = "insert into teacher(id,`name`) values(3,'宋老师')";
- // 修改
- sql = "update teacher set `name` = '赵老师' where id = 3";
- // 删除
- sql = "delete from teacher where id = 3";
- // 执行sql语句,增删改使用executeUpdate()方法,查询使用executeQuery()方法
- int count = statement.executeUpdate(sql);
- System.out.println("成功,影响了"+ count + "行。" );
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- // 关闭资源
- try {
- statement.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
添加或删除的时候,尽量使用PrepareStatement,而不是Statement
Statement和PrepareStatement的区别:
Statement 用于执行静态SQL语句,在执行的时候,必须指定一个事先准备好的SQL语句,并且相对不安全,会有SQL注入风险。
PrepareStatement 是预编译的SQL语句对象,SQL语句被预编译i并保存在对象中,被封装的SQL语句中,可以使用动态包含的参数?,在执行的时候可以为?传递参数。
使用PrepareStatement对象执行SQL语句的时候,sql被数据库进行预编译和预解析,然后被放到缓冲区中,每当执行一个PrepareStatement对象时,他就会被解析一次,但不会被再次编译,可以重复使用,减少编译次数,提高数据库性能。并且能够避免SQL注入,相对安全(把’ 单引号 使用 \ 转义,避免SQL注入 )。
SQL注入:
SQL注入(SQL Injection)是一种常见的网络安全攻击技术,通过在应用程序中插入恶意的SQL查询语句,来利用程序缺陷或漏洞,从而对数据库进行非法操作或获取敏感信息。
SQL注入攻击通常发生在需要用户输入数据并将其嵌入到 SQL 查询语句中的地方,比如登录表单、搜索框、参数化查询等。攻击者利用这些地方未对用户输入进行有效验证和过滤,直接将恶意的SQL代码注入到查询中,从而执行恶意操作。
-
- /*
- * PrepareStament
- */
- public class JDBC_05 {
- public static void main(String[] args) {
- Scanner scanner = new Scanner(System.in);
- System.out.println("请输入用户名:");
- String username = scanner.nextLine();
- System.out.println("请输入密码:");
- String password = scanner.nextLine();
- // login(username, password);
- // updatePwd(username, password);
- loginUser(username, password);
-
- }
-
- // 用户登录方法
- public static boolean login(String username,String password) {
- Connection conn = null;
- PreparedStatement statement = null;
- ResultSet rs = null;
- try {
- // 加载驱动
- conn = DBUtil.getConnection();
- // 编写sql语句
- String sql = "select count(*) from user where name = ? and password = ?";
- // 创建输出对象
- statement = conn.prepareStatement(sql);
- // 给问号赋值
- statement.setString(1, username);
- statement.setString(2, password);
- // 创建结果集,执行sql语句
- rs = statement.executeQuery();
- rs.next();
- // 返回结果
- int count = rs.getInt(1);
- if (count == 0) {
- System.out.println("登录失败");
- return false;
- }else {
- System.out.println("登录成功");
- return true;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 关闭资源
- DBUtil.close(rs);
- DBUtil.close(statement);
- DBUtil.close(conn);
- }
- return false;
- }
- // 修改密码的方法
- public static void updatePwd(String username,String password) {
- Connection conn = null;
- PreparedStatement statement = null;
- try {
- // 加载驱动
- conn = DBUtil.getConnection();
- // 编写sql语句
- String sql = "update user set password = ? where name = ?";
- // 创建输出对象
- statement = conn.prepareStatement(sql);
- // 给问号赋值
- statement.setString(1, password);
- statement.setString(2, username);
- // 执行sql语句
- int count = statement.executeUpdate();
- System.out.println("修改了"+count+"条数据");
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 关闭资源
- DBUtil.close(statement);
- DBUtil.close(conn);
- }
- }
-
-
- // 使用statement的登录方法,容易发生sql注入问题
- // 由于Statement在执行sql语句之前进行了字符串的拼接,所以如果username输入类似'or 1=1 or'格式
- // 即使用户不存在也能实现登录
- public static boolean loginUser(String username,String password) {
- Connection conn = null;
- Statement statement = null;
- ResultSet rs = null;
- try {
- // 加载驱动
- conn = DBUtil.getConnection();
- // 创建输出对象
- statement = conn.createStatement();
- // 编写sql语句
- String sql = "select count(*) from user where name = '"+username+"' and password = '"+password+"'";
- // 创建结果集,执行sql语句
- rs = statement.executeQuery(sql);
- rs.next();
- // 返回结果
- int count = rs.getInt(1);
- if (count == 0) {
- System.out.println("登录失败");
- return false;
- }else {
- System.out.println("登录成功");
- return true;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 关闭资源
- DBUtil.close(rs);
- DBUtil.close(statement);
- DBUtil.close(conn);
- }
- return false;
- }
- }
以上代码中创建链接和关闭资源操作都是相同的,因此可以把这一部分逻辑抽离出来,形成独立的类和方法,在实际应用中直接调用相应的类和方法即可。
创建JDBCUtil类,提供获取链接的方法和释放资源的方法
- public class DBUtil {
-
- // 封装方法加载驱动创建链接
- public static Connection getConnection() throws ClassNotFoundException, SQLException{
- Class.forName("com.mysql.cj.jdbc.Driver");
- Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "abc280619SS");
- return conn;
- }
- // 封装方法关闭资源
- public static void close(AutoCloseable obj) {
- if (obj != null) {
- try {
- obj.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
在一次任务中执行多条语句
- public class JDBC_Batch {
- public static void main(String[] args) {
- // testStatement();
- testPrepareStatement();
- }
-
- // 使用Statement添加多条数据
- public static void testStatement() {
- Connection conn = null;
- Statement statement = null;
- try {
- conn = DBUtil.getConnection();
- statement = conn.createStatement();
-
- statement.addBatch("insert into user(name,password,nickname) values('test1',111,'用户1')");
- statement.addBatch("insert into user(name,password,nickname) values('test2',222,'用户2')");
- statement.addBatch("insert into user(name,password,nickname) values('test3',333,'用户3')");
- statement.executeBatch();
- System.out.println("添加成功");
-
- } catch (ClassNotFoundException | SQLException e) {
- e.printStackTrace();
- } finally {
- DBUtil.close(statement);
- DBUtil.close(conn);
- }
-
- }
-
-
- // 使用PrepareStatement添加多条数据
- public static void testPrepareStatement() {
- Connection conn = null;
- PreparedStatement preparedStatement = null;
- try {
- conn = DBUtil.getConnection();
- preparedStatement = conn.prepareStatement("insert into user(name,password,nickname) values(?,?,?)");
- preparedStatement.setString(1, "test1");
- preparedStatement.setInt(2, 111);
- preparedStatement.setString(3, "用户1");
- preparedStatement.addBatch();
-
- preparedStatement.setString(1, "test2");
- preparedStatement.setInt(2, 222);
- preparedStatement.setString(3, "用户2");
- preparedStatement.addBatch();
-
- preparedStatement.setString(1, "test3");
- preparedStatement.setInt(2, 333);
- preparedStatement.setString(3, "用户3");
- preparedStatement.addBatch();
- preparedStatement.executeBatch();
- System.out.println("添加成功");
-
- } catch (ClassNotFoundException | SQLException e) {
- e.printStackTrace();
- } finally {
- DBUtil.close(preparedStatement);
- DBUtil.close(conn);
- }
-
- }
- }