JDBC基础

JDBC

JDBC, 全称为Java DataBase Connectivity standard, 它是一个面向对象的应用程序接口(API), 通过它可访问各类关系数据库。JDBC也是java核心类库的一部分

执行流程

实践

依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.29</version>
        </dependency>

PreparedStatement

  • PreparedStatement通过把用户非法输入的单引号用\反斜杠做了转义,防止sql注入
  • PreparedStatement需要set的方法,把?做替换
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //1、注册mysql驱动
        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/zg_test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai";

        String username = "root";

        String password = "123456";

        //通过DriverManager获取Connection
        Connection connection = DriverManager.getConnection(url, username, password);

        String name = "test";

        int age = 1;

        //把用户非法输入的单引号用\反斜杠做了转义
        PreparedStatement preparedStatement = connection.prepareStatement("select * from user where name = ? and age = ?");
        //防止sql注入


        preparedStatement.setString(1, name);
        preparedStatement.setInt(2, age);

        //执行sql获取数据
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i);
                String data = resultSet.getString(i);
                System.out.print(columnName + " : " + data + "\t");
            }
            System.out.println();
        }
        resultSet.close();

        preparedStatement.close();

        connection.close();
    }

Statement(StatementImpl)

Statement statement = connection.createStatement();
用以上方式获取的Statement不可以防止sql注入
在执行sql时候也没有使用占位符。


    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/zg_test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai";

        String username = "root";

        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        Statement statement = connection.createStatement();

        String name = "test";

        String age = "1";


        ResultSet resultSet = statement.executeQuery(String.format("select  * from user where name = '%s' and age = %s", name, age));

        while (resultSet.next()) {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i);
                String data = resultSet.getString(i);
                System.out.print(columnName + " : " + data + "\t");
            }
            System.out.println();
        }
        resultSet.close();

        statement.close();

        connection.close();


    }

事务

在Connection里设置connection.setAutoCommit(false);
并且可以配置隔离级别connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://localhost:3306/zg_test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai";

        String username = "root";

        String password = "123456";

        Connection connection = DriverManager.getConnection(url, username, password);

        //开启手动事务的关键是connection.setAutoCommit(false);
        //jdbc默认事务是开启的,并且是自动提交
        connection.setAutoCommit(false);

        connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);//设置隔离级别

        PreparedStatement preparedStatement = connection.prepareStatement("insert into user(id,name,age) values (?,?,?)");
        //防止sql注入
        User user = new User();
        user.setId(100);
        user.setAge(12);
        user.setName("jack1");

        preparedStatement.setInt(1, user.getId());
        preparedStatement.setString(2, user.getName());
        preparedStatement.setInt(3, user.getAge());
        //执行插入操作
        try {
            preparedStatement.executeUpdate();
            int x = 1 / 0;//制造异常
            connection.commit();//提交事务
        } catch (Exception e) {
            connection.rollback();//事务回滚
        } finally {
            preparedStatement.close();
            connection.close();
        }


    }

Connection的隔离级别定义,这里的注释也比较重要。

    /**
     * A constant indicating that transactions are not supported.
     */
    int TRANSACTION_NONE             = 0;

    /**
     * A constant indicating that
     * dirty reads, non-repeatable reads and phantom reads can occur.
     * This level allows a row changed by one transaction to be read
     * by another transaction before any changes in that row have been
     * committed (a "dirty read").  If any of the changes are rolled back,
     * the second transaction will have retrieved an invalid row.
     */
    int TRANSACTION_READ_UNCOMMITTED = 1;

    /**
     * A constant indicating that
     * dirty reads are prevented; non-repeatable reads and phantom
     * reads can occur.  This level only prohibits a transaction
     * from reading a row with uncommitted changes in it.
     */
    int TRANSACTION_READ_COMMITTED   = 2;

    /**
     * A constant indicating that
     * dirty reads and non-repeatable reads are prevented; phantom
     * reads can occur.  This level prohibits a transaction from
     * reading a row with uncommitted changes in it, and it also
     * prohibits the situation where one transaction reads a row,
     * a second transaction alters the row, and the first transaction
     * rereads the row, getting different values the second time
     * (a "non-repeatable read").
     */
    int TRANSACTION_REPEATABLE_READ  = 4;

    /**
     * A constant indicating that
     * dirty reads, non-repeatable reads and phantom reads are prevented.
     * This level includes the prohibitions in
     * <code>TRANSACTION_REPEATABLE_READ</code> and further prohibits the
     * situation where one transaction reads all rows that satisfy
     * a <code>WHERE</code> condition, a second transaction inserts a row that
     * satisfies that <code>WHERE</code> condition, and the first transaction
     * rereads for the same condition, retrieving the additional
     * "phantom" row in the second read.
     */
    int TRANSACTION_SERIALIZABLE     = 8;
posted @ 2020-10-31 15:15  刃牙  阅读(79)  评论(0编辑  收藏  举报