jdbc复习

1.JDBC是什么?

2.JDBC的本质是什么?

3.为什么要面向接口编程?

解耦和:提高程序的扩展力,降低程序耦合度。

思考: 为什么要制定一套JDBC接口呢?
因为每一个数据库的底层实现原理都不一样.
每一个数据库产品都有自己独特的实现原理.

  • 解压的.jar包下的.class文件就是对SUN公司制定的接口java.sql包下那一套接口的实现类.
    记住一个程序如果只有接口,没有接口的实现类,这个程序是无法运行的!

驱动就是对JDBC接口的实现。

JDBC的本质到底是什么?

  • 一套接口.

4.JDBC的使用步骤

第一步:注册驱动 (作用: 告诉java程序即将连接的是哪个品牌的数据库)

第二步:获取连接 (作用: 表示JVM进程和数据库进程这两个进程间的通道打开了)

第三步:获取数据库操作对象 (作用: 通过数据库操作对象来操作数据库,编写sql语句)

第四步:编写语句 (用来编写DQL DML…等语句)

第五步:处理查询结果集 (只有第四步是DQL语句,才会有这一步)

第六步:释放资源 (使用完资源之后一定要关闭资源.java和数据库属于进程间的通信!)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
//jdbc的使用步骤
public class JdbcTestConnection {
    public static void main(String[] args) throws Exception {
        //0.导入jar包
        //1.注册驱动(底层调用下面的代码,在jdk5以后也可以不写)
        Class.forName("com.mysql.jdbc.Driver");
        //两种写法一样
        //DriverManager.registerDriver(new Driver());
        //2.获取连接
        String url = "jdbc:mysql://localhost:3306/test";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url,username, password);
        //3.编写sql语句
        String sql = "select * from user";
        //4.获取执行sql语句的对象statement
        Statement statement = connection.createStatement();
        //5.执行sql语句
        statement.executeQuery(sql);
        //6.处理结果集,关闭资源
        statement.close();
        connection.close();
    }
}

5.常用api详解

1.DriverManager类常用api详解

1.注册驱动

public static void registerDriver(Driver driver) throws SQLException

DriverManager注册给定驱动程序。

:::color4
Class.forName(“com.mysql.jdbc.Driver”);点开Driver

:::

底层调用的DriverManager.registerDriver(new Driver());

注册驱动

1.Driver接口的包名: java.sql.Driver

Driver接口的实现类包名: com.mysql.jdbc.Driver(在.jar包中的一个实现类,要求必须配置到classpath环境变量中)

2.涉及到的类

	java.sql.DriverManager  (一个管理类)

	通过这个类的registerConnect(Driver 对象)来注册驱动!		

java.sql.Driver是一个接口,com.mysql.jdbc.Driver是它的一个实现类。

2.获取连接

public static Connection getConnection(String url) throws SQLException :试图建立到给定数据库 URL 的连接。

  1. 如果是本机的localhost和默认的端口号,url可以简写成:jdbc:mysql:///数据库名称?键值对参数
  2. 运行出现警告:

可以在url后面加上useSSL=false

2.Connection接口

作用1:获取执行sql的对象

//Connection的api详解 : 获取执行sql的对象
public class ConnectionApiTest1 {
    public static void main(String[] args) throws SQLException {

        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
        //1.获取执行的sql对象
            //1.获取普通的对象
        Statement statement = connection.createStatement();
            //2.获取可以防止sql注入的对象(后面详解)
    }
}

作用2:可以管理事务

核心方法:

  1. connection.setAutoCommit(false);//设置自动提交事务为false
  2. connection.commit();//提交事务
  3. connection.rollback();//回滚事务
//Connection的api详解 : 管理事务
public class ConnectionApiTest2 {
    public static void main(String[] args) throws SQLException {

        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
        Statement statement = connection.createStatement();
        //jdbc事务管理
        String sql1 = "update user set name = '张三' where id = 1";
        String sql2 = "update user set name = '李四' where id = 2";


        //保证两个sql语句都执行成功,或者都执行失败
        try {
            //开始事务,设置事务不自动提交
            connection.setAutoCommit(false);

            int i1 = statement.executeUpdate(sql1);
            System.out.println(i1);

            //制造异常
            int k = 1/0;

            int i2 = statement.executeUpdate(sql2);
            System.out.println(i2);

            //提交事务
            connection.commit();
        }catch (Exception e) {
            //回滚事务
            connection.rollback();
        }
    }
}

3.Statement接口

statement用来执行sql语句

//statement 对象
public class StatementTest {
    public static void main(String[] args) throws SQLException {
        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
        Statement statement = connection.createStatement();
        //执行DML,返回受影响的行数
        String sql1 = "update user set name = 'aaa' where id = 1";
        int i1 = statement.executeUpdate(sql1);
        if (i1 > 0){
            System.out.println("更新成功");
        }else {
            System.out.println("更新失败");
        }

        //执行DDL,执行成功返回的可能是零
        String sql2 = "create database test2";
        int i2 = statement.executeUpdate(sql2);
        //不能使用上面的方式判断是不是成功,一般不报异常就是成功了
        //String sql2 = "drop database test2";
        //执行删除,返回的是0,但是删除成功了
    }
}

注意:不能根据DDL语句返回值大于零判断是不是操作成功了。

4.ResuleSet返回结果

封装了DQL语句的查询结果

//ResultSet返回结果
public class ResultSet {
    public static void main(String[] args) throws SQLException {
        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
        Statement statement = connection.createStatement();
        
        //执行DQL语句
        String sql3 = "select * from user";
        java.sql.ResultSet resultSet = statement.executeQuery(sql3);
        while (resultSet.next()){
            //分别获取第一列、第二列和第三列的值
            int id = resultSet.getInt(1);
            String name = resultSet.getString(2);
            String email = resultSet.getString(3);
            System.out.println(id + " " + name + " " + email);
        }
    }
}

5.PreparedStatement

1.什么是sql注入?

是通过操作输入来修改预先定义好的sql语句,用以达到对服务器进行攻击的方法。例如输入一个 ’ or ‘1’ = ‘1,导致’123’='‘or’1’='1’改变了判定条件。

//sql注入演示
public class PreparedStatementTest {
    public static void main(String[] args) throws SQLException {
        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");
        Statement statement = connection.createStatement();

        String name = "fdsfsadf";
        String email = "' or '1' = '1";
        //定义sql语句
        String sql = "select * from user where name = '" + name + "' and email = '" + email + "'";

        //打印sql语句
        System.out.println(sql);

        ResultSet resultSet = statement.executeQuery(sql);
        if (resultSet.next()){
            System.out.println("验证成功!");
        }else {
            System.out.println("验证失败!");
        }


        statement.close();
        connection.close();
        resultSet.close();
    }
}

//输出
select * from user where name = 'fdsfsadf' and email = ' ' or '1' = '1'
验证成功!

2.解决办法

使用PreparedStatement把参数用?代替,作为占位符,底层是将sql语句用转义符进行转义。

比如:select * from user where name = 'fdsfsadf' and email = ' ' or '1' = '1'

转义后就是 select * from user where name = 'fdsfsadf' and email = ' \' or \'1\' = \'1'

将用户输入的内容作为一个文本。

import java.sql.*;
import java.sql.ResultSet;

//sql注入解决办法
public class PreparedStatementSolve {
    public static void main(String[] args) throws SQLException {
        Connection connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456");

        String name = "fdsfsadf";
        String email = " ' or '1' = '1";
        //1.定义sql语句
        String sql = "select * from user where name = ?  and email = ?";

        //2.获取执行sql语句的对象(在这一步就进行预编译了)
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        //3.设置参数,从1开始
        preparedStatement.setString(1, name);
        preparedStatement.setString(2, email);
        //4.执行sql语句,不用传递sql语句了
        ResultSet resultSet = preparedStatement.executeQuery();
        if (resultSet.next()) {
            System.out.println("验证成功!");
        } else {
            System.out.println("验证失败!");
        }
        preparedStatement.close();
        connection.close();
        resultSet.close();
    }
}

输出结果 :验证失败!

3.PreparedStatement原理

首先明确一般的sql执行过程(使用Statement)

检查sql语法->编译->执行,前两部分耗时一般较长。

当创建一个 PreparedStatement 对象,并为它传入sql语句时,SQL 语句就会进行预编译。后续执行时,只需要传递参数值,而不需要重新编译 SQL 语句,只需要预编译一次。

开启预编译:在url后面加上 useServerPrepStmts=true,默认是关闭的。

4.优点

  1. 可以预编译sql,性能更高。
  2. 可以防止sql注入,将敏感字符进行转义

6.数据库连接池

1.概念

避免连接遗漏:某个用户占用connection资源但是处于空闲状态,导致新的用户没有connection可用,数据库连接池就会对该connection进行回收,避免连接遗漏。

2使用步骤

  1. 导入jar包
  2. 定义配置文件
  3. 加载配置文件
  4. 获取连接池对象
  5. 获取数据库连接
//druid的使用步骤
public class DruidTest {
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件,在src目录下创建druid.properties文件
        //3.加载配置文件(E:/review-code/jdbc-learning/src/druid.properties)绝对路径
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-learning/src/druid.properties"));
        //4.获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5.获取数据库连接
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        //进行sql操作

        //注意报错:找不到路径,通过下面的代码去更改路径
        System.out.println(System.getProperty("user.dir"));//E:\review-code
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值