MySql的初学习 -- 第十三章 -- JDBC、Sql注入、JDBC控制事务

本文介绍了JDBC的基本概念,包括JDBC的作用和安装步骤。详细讲解了如何使用JDBC执行SQL,如executeUpdate和executeQuery,以及资源的释放。提到了JDBC工具类的创建以简化操作,并探讨了SQL注入的问题及其预防方法——预处理对象。最后,讨论了JDBC如何控制事务,通过Connection对象的事务管理API确保数据一致性。
摘要由CSDN通过智能技术生成


博客说明

文章内容输出来源:拉勾教育Java就业急训营

什么是JDBC

JDBC就是一套操作关系数据库的规则(接口),数据库厂商需要实现这套接口,并提供数据库驱动的Jar包
使用这套接口,真正执行的是对应驱动包中的实现类

JDBC安装

  1. 将MySQL驱动包添加到jar包库文件夹中,Myjar文件夹,用于存放当前项目需要的所有jar包
  2. 在 idea中 配置jar包库的位置
    配置jar包库的位置配置jar包库的位置
  3. 配置jar包库
    配置jar包库
  4. 注册驱动
public class JDBCDemo01 {
    public static void main(String[] args) throws Exception {

        //1.注册驱动(可以省略,从jdbc3开始)
        Class.forName("com.mysql.jdbc.Driver");

        //2.获取连接 connection连接对象
        /**
        url的组成
        	jdbc:mysql:  -->  协议
        	localhost:3306  --> 主机IP:端口
        	db1 -->  数据库
        	
        	#可以不写
        	?characterEncoding=UTF-8(防止乱码)  -->  参数名 = 参数值
        */
        String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
        DriverManager.getConnection(url,"root","123456");
    }
}

使用JDBC运行SQL

Connection接口中的方法说明
Statement createStatement()创建 SQL语句执行对象
Statement类 常用方法说明
int executeUpdate(String sql);执行insert update delete语句.返回int类型,代表受影响的行 数
ResultSet executeQuery(String sql);执行select语句, 返回ResultSet结果集对象

使用executeUpdate

public class JDBCDemo01 {
    public static void main(String[] args) throws Exception {
        //1.注册驱动(可以省略,从jdbc3开始)
        Class.forName("com.mysql.jdbc.Driver");

        //2.获取连接 connection连接对象
        String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
        Connection con = DriverManager.getConnection(url, "root", "123456");

        //3.获取语句执行平台
        Statement statement = con.createStatement();

        //3.1 通过 statement 对象的 executeUpdate 方法创建一张表
        String sql = "create table test(id int,name varchar(20),age int);";
        int i = statement.executeUpdate(sql);
        System.out.println(i);

        //4.关闭流
        statement.close();
        con.close();
    }
}

使用executeQuery

public class JDBCDemo01 {
    public static void main(String[] args) throws Exception {
        //1.注册驱动(可以省略,从jdbc3开始)
        Class.forName("com.mysql.jdbc.Driver");

        //2.获取连接 connection连接对象
        String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
        Connection con = DriverManager.getConnection(url, "root", "123456");

        //3.获取语句执行平台
        Statement statement = con.createStatement();

        //3.1 执行查询操作,使用executeQuery()
        String sql = "select * from table1";
        ResultSet resultSet = statement.executeQuery(sql);

        //通过while循环获取resultSet中的数据
        while (resultSet.next()) {
            //获取id
            int id = resultSet.getInt("id");

            //获取姓名
            String name = resultSet.getString("name");

            System.out.println(id + "," + name);
        }

        //4.关闭流
        resultSet.close();
        statement.close();
        con.close();
    }
}

释放资源

  1. 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
  2. 释放原则:先开的后关,后开的先关。ResultSet ==> Statement ==> Connection
  3. 关闭可以放在 finally 块 中执行( try / catch / finally )
    👇 👇 👇 👇 👇 👇 👇 👇 👇 👇
public class JDBCDemo01 {
    public static void main(String[] args){
        Connection con = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            //1.注册驱动(可以省略,从jdbc3开始)
            Class.forName("com.mysql.jdbc.Driver");

            //2.获取连接 connection连接对象
            String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
            con = DriverManager.getConnection(url, "root", "123456");

            //3.获取语句执行平台
            statement = con.createStatement();

            //3.1 通过 statement 对象的 executeUpdate() 方法创建一张表
            //String sql = "create table test(id int,name varchar(20),age int);";
            //int i = statement.executeUpdate(sql);
            //System.out.println(i);

            //3.1 执行查询操作,使用executeQuery()
            String sql = "select * from employee";
            resultSet = statement.executeQuery(sql);

            //通过while循环获取resultSet中的数据
            while (resultSet.next()) {
                //获取id
                int id = resultSet.getInt("id");

                //获取姓名
                String name = resultSet.getString("name");

                System.out.println(id + "," + name);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            //4.关闭流
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            try {
                con.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

步骤总结

  1. 获取驱动(可以省略)
  2. 获取连接
  3. 获取Statement对象
  4. 处理结果集(只在查询时处理)
  5. 释放资源

JDBC工具类

因为前三部都是固定且复杂,因此可以创建一个JDBC工具类提高效率
复制就能用:URL那改一下自己的数据库名即可
👇👇👇👇👇

package com.jdbc;

import java.sql.*;

/**
 * JDBC工具类
 */
public class JDBCUtils {
    //1.将连接信息定义为  字符串常量
    public static final String DRIVERNAME = "com.mysql.jdbc.Driver";
    public static final String URL = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
    public static final String USER = "root";
    public static final String PASSWORD = "123456";

    //2.静态代码块
    static{
        try {
            //注册驱动
            Class.forName(DRIVERNAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接的 静态方法
     * @return
     */
    public static Connection getConnection(){
        //获取连接对象 并返回
        try {
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            return connection;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }
    }

    /**
     * 结束资源方法(增删改)
     * @param connection
     * @param statement
     */
    public static void CloseJDBC(Connection connection, Statement statement){
        if(connection != null && statement != null){
            try {
                statement.close();
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 结束资源方法(查)
     * @param connection
     * @param statement
     * @param resultSet
     */
    public static void CloseJDBC(Connection connection, Statement statement, ResultSet resultSet){
        if(connection != null && statement != null && resultSet != null){
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

使用JDBC工具类完成DML操作、DQL操作

package com.jdbc;

import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCDemo01 {

    /**
     * 通过JDBC工具类增加数据
     * @throws SQLException
     */
    @Test
    public void testInsert() throws SQLException {
        //通过JDBC工具类获取连接
        Connection con = JDBCUtils.getConnection();
        //获取statement对象
        Statement statement = con.createStatement();
        //Sql
        String sql = "insert into test value (2,'小明',8)";
        //添加数据进数据库
        int i = statement.executeUpdate(sql);
        System.out.println(i);
        //关闭连接
        JDBCUtils.CloseJDBC(con,statement);
    }

    /**
     * 通过JDBC工具类修改数据
     * @throws SQLException
     */
    @Test
    public void testUpdate() throws SQLException {
        //通过JDBC工具类获取连接
        Connection connection = JDBCUtils.getConnection();
        //获取statement对象
        Statement statement = connection.createStatement();
        //Sql
        String sql = "Update test set name = '小红' where id = 1";
        //添加数据进数据库
        int i = statement.executeUpdate(sql);
        System.out.println(i);
        //关闭连接
        JDBCUtils.CloseJDBC(connection,statement);
    }

    /**
     * 使用JDBC工具类删除数据
     * @throws SQLException
     */
    @Test
    public void testDelete() throws SQLException {
        //通过JDBC工具类获取连接
        Connection connection = JDBCUtils.getConnection();
        //获取statement对象
        Statement statement = connection.createStatement();
        //Sql
        String sql ="Delete from test where id = 5";
        //添加数据进数据库
        int i = statement.executeUpdate(sql);
        System.out.println(i);
        //关闭连接
        JDBCUtils.CloseJDBC(connection,statement);
    }

    /**
     * 使用JDBC工具类查询数据
     * @throws SQLException
     */
    @Test
    public void testSelect() throws SQLException {
        //通过JDBC工具类获取连接
        Connection connection = JDBCUtils.getConnection();
        //获取statement对象
        Statement statement = connection.createStatement();
        //Sql
        String sql = "Select * from test";
        //获取resultSet集
        ResultSet resultSet = statement.executeQuery(sql);
        //遍历输出数据
        while(resultSet.next()){
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            System.out.println("编号:" + id + ",姓名:" + name + ",年龄:" + age);
        }
        //关闭连接
        JDBCUtils.CloseJDBC(connection,statement,resultSet);
    }
}

Sql注入

用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了 原有 SQL 真正的意义,以上问题称为 SQL 注入 .
详细过程等我有空后补

预处理对象

为了防止Sql注入,可以使用预处理对象进行防护

预处理对象:PrepareStatement 是 Statement接口的子接口
使用预处理对象 他有预编译的功能,提高SQL的执行效率
使用预处理对象 通过占位符的方式,设置参数,可以有效防止SQL注入

/**
  * 使用PreparedStatement接口防止Sql注入
  * @param args
  * @throws SQLException
  */
public static void main(String[] args) throws SQLException {
        //通过JDBC工具类获取连接
        Connection connection = JDBCUtils.getConnection();
        //使用?占位符来设置参数
        String sql = "select * from test where id=? and pwd=?";
        //获取prepareStatement对象
        PreparedStatement ps = connection.prepareStatement(sql);

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入账号:");
        String id = scanner.nextLine();
        System.out.println("请输入密码:");
        String pwd = scanner.nextLine();

        //设置参数,使用setXXX(占位符的位置(整数),要设置的值)的方法设置占位符的参数
        ps.setString(1,id);//设置第一个?的值为id
        ps.setString(2,pwd);//设置第二个?的值为pwd

        //查询
        ResultSet resultSet = ps.executeQuery();

        if(resultSet.next()){
            System.out.println("成功:" + id);
        }else{
            System.out.println("失败:" + "Error");
        }

        //关闭连接
        JDBCUtils.CloseJDBC(connection,ps,resultSet);
    }

JDBC控制事务

事务相关API:使用 Connection中的方法实现事务管理

方法说明
void setAutoCommit(boolean autoCommit)参数是 true 或 false 如果设置为 false,表示关闭自动提交,相 当于开启事务
void commit()提交事务
void rollback()回滚事务
package com.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestJDBCTransaction {
    //使用JDBC操作事务
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement ps = null;
        try {
            //1.获取连接
            connection = JDBCUtils.getConnection();

            //2.开启事务
            connection.setAutoCommit(false);

            //3.获取预处理对象 执行SQL(两次操作)
            //3.1小明账户-500
            ps = connection.prepareStatement("Update test set money = money - ? where name = ?");
            ps.setInt(1,500);
            ps.setString(2,"小明");
            ps.executeUpdate();

            //手动添加异常,测试事务的回滚,不想发生异常请注销下面的代码
            System.out.println(1 / 0);

            //3.1小红账户+500
            ps = connection.prepareStatement("Update test set money = money + ? where name = ?");
            ps.setInt(1,500);
            ps.setString(2,"小红");
            ps.executeUpdate();

            //4.提交事务(正常情况)
            connection.commit();
            System.out.println("转账成功");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            //5.出现异常就回滚事务
            try {
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } finally {
            //6.释放资源
            JDBCUtils.CloseJDBC(connection,ps);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值