JDBC的介绍和认识

学习笔记输出来源:拉勾教育Java就业急训营

修改时间:2021年1月21日
作者:pp_x
邮箱:[email protected]

JDBC

什么是JDBC

  • JDBC(Java Data Base Connectivity) 是 Java 访问数据库的标准规范。是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范.

JDBC原理

  • JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。
    在这里插入图片描述

JDBC使用

注册驱动

  • JDBC规范定义驱动接口: java.sql.Driver
  • MySql驱动包提供了实现类: com.mysql.jdbc.Driver
  • 注册方式
//forName将类初始化
Class.forName("com.mysql.jdbc.Driver");

问:为什么这样可以初始类

  • Driver类的源码
// Driver类是MySql提供的数据库驱动类, 实现了JDBC的Driver接口 java.sql.Driver
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    
    

    public Driver() throws SQLException {
    
    
    }
//静态代码块,Class类的 forName()方法将Driver类 加载到内存, static代码块会自动执行
    static {
    
    
        try {
    
    
        /* 
        DriverManager 驱动管理类 
        registerDriver(new Driver) 注册驱动的方法 
        注册数据库驱动 
        */
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
    
    
            throw new RuntimeException("Can't register driver!");
        }
    }
}

注意:JDBC3开始可以不用注册驱动直接使用,即以上语句可以省略

API使用

获得连接

  • Connection 接口,代表一个连接对象 ,具体的实现类由数据库的厂商实现

  • 使用 DriverManager类的静态方法,getConnection可以获取数据库的连接

  • Connection getConnection(String url, String user, String password):通过连接字符串和用户名,密码来获取数据库连接对象

      参数说明:
      user: 登录用户名
      password :登录密码
      url: mySql URL的格式 jdbc:mysql://localhost:3306/db4
    

在这里插入图片描述

  • 代码示例
public class JDBCDemo02 {
    
     
	public static void main(String[] args) throws Exception {
    
     
	//1.注册驱动 
	Class.forName("com.mysql.jdbc.Driver"); 
	//2.获取连接 url,用户名, 密码 
	String url = "jdbc:mysql://localhost:3306/db4"; 
	Connection con = DriverManager.getConnection(url, "root", "root"); 
	//com.mysql.jdbc.JDBC4Connection@2e3fc542 
	System.out.println(con); 
	} 
}

获取语句执行平台

  • 通过Connection 的 createStatement方法 获取sql语句执行对象
  • Statement createStatement():创建 SQL语句执行对象
  • Statement : 代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回所生成结果的对象。
Statement类 常用方法 说明
int executeUpdate(String sql); 执行insert update delete语句.返回int类型,代表受影响的行数
ResultSet executeQuery(String sql); 执行select语句, 返回ResultSet结果集对象
  • 代码示例
public class JDBCDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    

        //1、注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接数据库对象
        String url = "jdbc:mysql://localhost:3306/db4?characterEncoding=UTF-8";
        Connection connection = DriverManager.getConnection(url,"root","root");
        System.out.println(connection);
        //3、语句执行平台对象
        Statement statement = connection.createStatement();

        //3.1、通过statement对象的executeupdate方法执行一个SQL语句
        String sql = "create table test(id int,name varchar(20),age int);";
        int i = statement.executeUpdate(sql);//返回值表示受影响的行数
        System.out.println(i);

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

处理结果集

  • 查询操作专属
package com.lagou.jdbc01;

import java.sql.*;

/**
 * jdbc查询操作
 * @author pp_x
 */
public class JDBCDemo02 {
    
    
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
    
    
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db4","root","root");
        Statement statement = connection.createStatement();
        String sql = "select * from jdbc_user;";
        ResultSet resultSet = statement.executeQuery(sql);//返回一个结果集对象
        while (resultSet.next()){
    
    
            int anInt = resultSet.getInt(1);//查询id
            String string = resultSet.getString(2);//查询username
            String string1 = resultSet.getString(3);//查询password
            String string2 = resultSet.getString(4);//查询 birthday
            System.out.println(anInt+string+string1+string2);
        }

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

ResultSet接口

  • 作用::封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。
ResultSet接口方法 说明
boolean next() a、游标向下一行 b、返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false
xxx getXxx( String or int) 可以通过列名查询也可以通过列号查询,返回不同类型

释放资源

  • 需要释放的对象:ResultSet结果集,Statement 语句,Connection连接
  • 先开的后关,后开的先关。ResultSet == Statement ==> Connection
  • 放在finally代码块中

JDBC实现增删改查

JDBC工具类

  • 什么时候自己创建工具类
    • 如果一个功能经常要用到,我们建议把这个功能做成一个工具类,可以在不同的地方重用。
    • “获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。

sql注入

什么是sql注入

  • 我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了 原有SQL 真正的意义,以上问题称为 SQL 注入

预处理对象

  • PreparedStatement接口介绍
    • PreparedStatementStatement 接口的子接口,继承于父接口中所有的方法。它是一个预编的 SQL 语句对象
    • 预编译: 是指SQL 语句被预编译,并存储在 PreparedStatement对象中。然后可以使用此对象多次高效地执行该语句。
  • PreparedStatement特点
    • 因为有预先编译的功能,提高 SQL 的执行效率。
    • 可以有效地防止sql注入,安全性更高
  • 获取PreparedStatement对象
    • 通过Connection的对象创建PreparedStatement 对象
    • connection.prepareStatement(String sql) 可以使用?作为占用符
  • 常用方法
常用方法 说明
int executeUpdate(); 执行insert update delete语句.
ResultSet executeQuery(); 执行select语句. 返回结果集对象 Resulet
  • 通过重载的setXxx()来给占位符?赋值
    在这里插入图片描述

Statement 与 PreparedStatement的区别?

  • Statement用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句。
  • PrepareStatement是预编译的SQL语句对象,语句中可以包含动态参数“?”,在执行时可以为“?”动态设置参数值。
  • PrepareStatement可以减少编译次数提高数据库性能。

JDBC控制事务

相关API

方法 说明
void setAutoCommit(boolean autoCommit) true为开启自动提交,false为关闭自动提交
void commit() 提交事务
void rollback 关闭事务

步骤

  1. 获取连接
  2. 开启事务
  3. 获取到 PreparedStatement , 执行两次更新操作
  4. 正常情况下提交事务
  5. 出现异常回滚事务
  6. 最后关闭资源
  • 代码示例
package com.lagou.jdbc04;

import com.lagou.utils.JDBCUtils;

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

public class TestJDBCTransaction {
    
    

    //使用JDBC操作事务
    public static void main(String[] args) {
    
    

        Connection con = null;
        PreparedStatement ps = null;

        try {
    
    
            //1.获取连接
            con = JDBCUtils.getConnection();

            //2.开启事务
            con.setAutoCommit(false);  //手动提交事务

            //3.获取预处理对象 执行SQL (两次修改操作)
            //3.1 tom账户 - 500
            ps = con.prepareStatement("update account set money = money - ? where name = ?");
            ps.setDouble(1,500.0);
            ps.setString(2,"tom");
            ps.executeUpdate();

            //模拟 tom转账之后出现异常
            System.out.println(1 / 0);

            //3.2 jack账户 + 500
            ps = con.prepareStatement("update account set money = money + ? where name = ?");
            ps.setDouble(1,500.0);
            ps.setString(2,"jack");
            ps.executeUpdate();

            //4.提交事务 (正常情况)
            con.commit();
            System.out.println("转账成功! !");

        } catch (SQLException e) {
    
    
            e.printStackTrace();
            //5.出现异常就回滚事务
            try {
    
    
                con.rollback();
            } catch (SQLException ex) {
    
    
                ex.printStackTrace();
            }

        } finally {
    
    
            //6.释放资源
            JDBCUtils.close(con,ps);
        }

    }

}

猜你喜欢

转载自blog.csdn.net/weixin_46303867/article/details/112974586