JDBC 学习笔记(一)

一、jdbc 介绍

1. 什么是 JDBC ?

JDBC全称为:Java DataBase Connectivity ,java数据库连接。 是java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

使用java程序操作数据库时,需要使用数据库给我们提供的驱动程序。不同的数据库厂商提供的驱动也是不同的。

2. JDBC的本质是什么?

JDBC是SUN公司制定的一套接口(interface)

java.sql.*; (这个软件包下有很多接口。)

接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。

为什么要面向接口编程?
解耦合:降低程序的耦合度,提高程序的扩展力。
多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)
建议:
Animal a = new Cat();
Animal a = new Dog();
// 喂养的方法
public void feed(Animal a){} // 面向父类型编程。
不建议:
Dog d = new Dog();
Cat c = new Cat();

思考:为什么SUN制定一套JDBC接口呢?
因为每一个数据库的底层实现原理都不一样。
Oracle数据库有自己的原理。
MySQL数据库也有自己的原理。
MS SqlServer数据库也有自己的原理。 …
每一个数据库产品都有自己独特的实现原理。

JDBC的本质到底是什么? 一套接口。

二、jdbc API 常用类与接口

jdbc的API(类和接口)在java.sql 以及 javax.sql的两个包下,前期导入包的时候特别注意,我们当前使用的都是在javax.sql包下的类和接口。

jdbc核心关系图
jdbc核心关系图

常用接口 / 类描述
java.sql.DriverManager数据库驱动管理类。
java.sql.Connection建立数据库连接的一个接口。
java.sql.Statement向数据库发送sql信息,并且得到数据库返回的信息,父接口。
java.sql.PreparedStatement向数据库发送预编译的sql信息,子接口。
java.sql.CallableStatement向数据库发送存储过程的sql信息,子接口。
java.sql.ResultSet结果集,Statement执行完sql查询之后,会返回结果,结果给了ResultSet。

上述描述的大部分都是接口的类型,是不能直接使用的,需要使用实现类完成。MySQL数据库的驱动中,已经帮助我们声明好了jdbc接口的实现类,只需要将MySQL的驱动拷贝到项目中即可。

三、JDBC的环境搭建

  1. 在项目或模块下先创建一个lib目录
  2. 在lib目录下添加mysql的驱动jar包。 Jar就是java程序压缩后产生的文件,jdk就属于jar包的一类。
  3. 右击驱动jar包,将jar添加到项目路径下

四、JDBC编程六步(需要背会)

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

第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭通道。)

第三步:获取数据库操作对象(专门执行sql语句的对象)

第四步:执行SQL语句(DQL DML....)

第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。)

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

JDBC编程六步

代码实现

import java.sql.*;
public class HelloJDBC {
    public static void main(String[] args) throws Exception {
        // 通过驱动管理类加载驱动
        DriverManager.registerDriver( new Driver() );
        
        // 建立数据库链接
        /*
            jdbc:jdbc协议
            mysql//:jdbc的子协议,表示MySQL协议
            localhost:表示服务器主机域名 ip地址
            3306:服务器主机数据库端口
            DataBaseName: 链接的数据仓库名称
            characterEncoding=utf8:指定传输数据的字符格式---> 选填
            useSSL=false:加密方式,false表示不加密 ---> MySQL8.0必填
            serverTimezone=UTC:设置时区 UTC国际标准时间 ---> MySQL8.0必填
            
            简写格式: jdbc:mysql:///数据库名?useSSL=false&serverTimezone=UTC";
                简写格式要求必须是链接本机数据库,并且数据库的端口号是3306。
         */
        String url = "jdbc:mysql://localhost:3306/DataBaseName?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        // 数据库用户名
        String user = "root";
        // 数据库密码
        String password = "password";
        Connection conn = DriverManager.getConnection(url,user,password);
        System.out.println("conn = " + conn); 
        // 3. 通过Connection数据库连接对象,获取Statement对象(用于向数据库发送 SQL 语句)
        Statement statement = conn.createStatement();
        // 4. 通过Statement对象的executeQuery()向数据库发送SQL语句,并且执行获取结果
        String sql = "select * from person";
        ResultSet resultSet = statement.executeQuery(sql);
        // 5. 处理结果 next()方法判断是否有数据,getString()方法获取对应字段的信息
        while (resultSet.next()) {
            String name = resultSet.getString("name");
            System.out.println("name = " + name);
        }
        // 6. 关闭连接,释放资源
        resultSet.close();
        statement.close();
        conn.close();
    }
}

五、jdbc-api详解

5.1、DriverManager介绍

Java.sql.DriverManager:管理一组 JDBC 驱动程序的基本服务。驱动管理类。

成员方法—注册驱动

static void registerDriver(Driver driver)  使用 DriverManager注册给定的驱动程序。
// 参数:Driver driver: 当前要连接的数据库 

registerDriver()方法注册加载驱动的不足:
1、对驱动api依赖性太高,如果此时要更换数据库,则需要更改代码,重新编译后重新部署。(硬编码问题)
2、驱动会注册两次。(因为在mysql中的Driver中有静态代码块,已经注册了。)
驱动会注册两次

反射加载注册驱动

// 加载驱动  -- 将Driver类加载到内存时,会自动执行静态代码块,从而实现驱动的注册
Class.forName("com.mysql.cj.jdbc.Driver");

成员方法—建立链接

static Connection getConnection(String url, String user, String password) 试图建立到给定数据库 URL 的连接。 
    /*
        String url : 连接数据库的相关信息,主机名、端口、编码、加密、时区等信息
        String user:连接数据的用户名
        String password:连接数据库的密码
    */ 

URL介绍 – 链接数据库链接数据库

5.2、Connection介绍

java.sql.Connection:与特定数据库的连接。在连接上下文中执行 SQL 语句并返回结果。Connection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过Connection对象完成的。
如果想要发送sql语句到数据库,一定要通过这个连接。获取方式是通过DriverManager类中的静态方法getConnection(String url, String user, String password)获取。

成员方法

成员方法描述
Statement createStatement()创建一个 Statement 对象来将 SQL 语句发送到数据库。
PreparedStatement prepareStatement(String sql)创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。

5.3、Statement 详解

java.sql.Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。向数据库发送sql的对象,并且得到执行sql之后的结果。

成员方法—增删改

int executeUpdate(String sql) 执行给定SQL语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句),返回的结果是被影响的数据条数

成员方法—查

ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 因为查询的结果可能是多条,所以返回的是个结果集。

成员方法—增删改查

boolean execute(String sql) 执行给定的 SQL 语句,该语句可能返回多个结果。如果sql语句为查询语句则返回 true。如果其为更新计数或者不存在任何结果,则返回 false

成员方法—获取增删改影响的数据条数

int getUpdateCount() 以更新计数的形式获取当前结果,如果结果为 ResultSet(查询操作) 对象或没有更多结果,则返回 -1

成员方法—获取查询结果集

ResultSet getResultSet() 以 ResultSet 对象的形式获取当前结果。
如果执行的是select 语句,我们需要处理select语句执行之后获取的结果集。

基本使用

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立链接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        // 获取Statement对象
        Statement statement = connection.createStatement();
        // 发送sql语句
        // String sql = "select * from person";
        String sql = "update person set age = 18";
        boolean execute = statement.execute(sql);
        // 判断结果,如果为true表示是查询语句,否则为其他语句
        if( execute ) {
            System.out.println("查询成功!");
            // 获取结果集
            ResultSet resultSet = statement.getResultSet();
            while ( resultSet.next() ) {
                int id = resultSet.getInt("id");
                int age = resultSet.getInt("age");
                String name = resultSet.getString("name");
                System.out.println( id + " , " + name + " , " + age );
            }
        }else{
            System.out.println("执行更新操作");
            int updateCount = statement.getUpdateCount();
            System.out.println("您的操作更改了" + updateCount + "条数据!");
        }
        // 释放资源
        statement.close();
        connection.close();
    }
}

5.4、ResultSet 详解

需要掌握:
1、如果去遍历结果集
2、如果从结果集中取出数据

java.sql.ResultSet:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。ResultSet 对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next() 方法将光标移动到下一行。因为该方法在 ResultSet对象没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。 默认的 ResultSe对象不可更新,仅有一个向前移动的光标。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。

成员方法—遍历

我们可以将ResultSet对象想像成一个指针,事实上它也确实是一个指针,有点类似于前面学习Collection集合时的iterator迭代器。只不过它提供了更丰富的对指针操作的方法。

成员方法描述
boolean next()将光标从当前位置向前移一行。
boolean previous()将光标移动到此 ResultSet 对象的上一行。
boolean absolute(int row)将光标移动到此 ResultSet 对象的给定行编号。
void afterLast()将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
void beforeFirst()将光标移动到此 ResultSet 对象的开头,正好位于第一行之前。
boolean first()将光标移动到此 ResultSet对象中的第一行。
boolean last()将光标移动到此 ResultSet对象中的最后一行。

成员方法—获取数据

上述介绍的方法都是对指针的操作,通过指针我们可以将光标指向结果集中的某一行数据,但是要获取对应的数据需要专门的方法来实现。
获取的方法统一叫做 getXxxx()方法,Xxxx表示具体的类型,数据库中的每一列都有自的数据类型。比如想要获取字符串类型则是getString()方法,获取int类型就是getInt()等。
获取的方法都有两种类型的参数,一种是通过列的名字获取,一种是通过列的顺序获取。如:
getString( String 列的名字):通过列的名字获取数据。常用,如果有别名要通过别名获取。
getString(int 列的顺序):通过列的顺序获取数据,列的顺序从1开始。

int getInt(int columnIndex) 
    Java 编程语言中 int 的形式获取此 ResultSet 对象的当前行中指定列的值。 
int getInt(String columnLabel)Java 编程语言中 int 的形式获取此 ResultSet 对象的当前行中指定列的值。 
String getString(int columnIndex)Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。 
String getString(String columnLabel)Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。 

代码演示 — 准备实体类

public class Person {
    private int id;
    private String name;
    private int age;
    // 构造方法
    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public Person() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

代码演示 — jdbc实现

import java.sql.*;
import java.util.ArrayList;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 创建集合,用于保存封装的Person对象
        ArrayList<Person> list = new ArrayList<>();
        // 加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立数据库链接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url,user,password);
        // 获取statement对象
        Statement statement = connection.createStatement();
        // 向数据库发送sql语句
        String sql = "select id as 编号 ,name as 姓名 , age from person";
        ResultSet resultSet = statement.executeQuery(sql);
        // 操作结果集
        while ( resultSet.next() ) {
            // 获取数据
            int id = resultSet.getInt("编号");
            String name = resultSet.getString("姓名");
            int age = resultSet.getInt("age");
            // 打印信息
            // System.out.println(id + " , " + name + " , " + age );
            // 创建Person对象,用获取的信息封装成对象后处理
            Person person = new Person(id, name, age);
            // 将创建的Person对象保存到集合中
            list.add(person);
        }
        // 遍历集合中的数据
        for( Person person : list ) {
            System.out.println(person);
        }
        // 释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

滚动结果集—[了解]

通过Connection接口中的createStatement()方法我们可以获取到数据库中数据的结果集,前面对结果集的操作都是直接获取某些数据然后操作。而在Connection接口中还有有一个重载的createStatement(int resultSetType, int resultSetConcurrency)方法,它可以实现对结果集中的结果更广泛的操作。
Connection接口中的方法

Statement createStatement(int resultSetType, int resultSetConcurrency) 
       创建一个Statement对象,该对象将生成具有给定类型和并发性的ResultSet对象。 

因为ResultSet集合对象才是结果集对象,所以上述方法中的参数是由ResultSet接口提供的,它们是ResultSet接口中的静态的成员变量。

createStatement(int resultSetType, int resultSetConcurrency)

	int resultSetType:表示结果集的类型
		ResultSet.TYPE_FORWARD_ONLY :只能向前,只能调用next() 不能向回滚动
		ResultSet.TYPE_SCROLL_INSENSITIVE  支持结果集向回滚动,不能查看修改结果
		ResultSet.TYPE_SCROLL_SENSITIVE    支持结果集向回滚动,查看修改结果
	int resultSetConcurrency:表示结果的并发策略
		ResultSet.CONCUR_READ_ONLY :表示只读,不可修改
		ResultSet.CONCUR_UPDATABLE :表示支持修改

常见三种组合
	ResultSet.TYPE_FORWARD_ONLYResultSet.CONCUR_READ_ONLY :(默认)只读不支持向回滚动
	ResultSet.TYPE_SCROLL_INSENSITIVEResultSet.CONCUR_READ_ONLY  :只读,支持向回滚动
	ResultSet.TYPE_SCROLL_SENSITIVEResultSet.CONCUR_UPDATABLE :支持向回滚动,支持对数据修改 

修改数据的方法

数据的修改和前面讲的获取类的方法很像,都叫做updateXxxx()方法,Xxxx表示具体的数据类型,如果想要修改字符串类型就用updateString(),修改int类型就用updateInt()等。修改的方法依然是两个种方式,一个是通过字段名修改,一个是通过字段顺序修改。

void updateInt(int columnIndex, int x)int 值更新指定列。 
void updateInt(String columnLabel, int x)int 值更新指定列。 
void updateString(int columnIndex, String x)String 值更新指定列。 
void updateString(String columnLabel, String x)String 值更新指定列。 

将修改的数据更新到数据库

上述介绍的修改方法都只是在内存中修改,并没有实际修改数据库中的方法,如果想要修改数据库中的数据,需要对应的方法实现。

void updateRow() 
    用此 ResultSet 对象的当前行的新内容更新底层数据库。

代码演示

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url,user,password);
        // 获取Statement对象
        // Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE ,ResultSet.CONCUR_READ_ONLY);
        Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE ,ResultSet.CONCUR_UPDATABLE);
        // 向数据库发送sql语句
        String sql = "select * from person";
        ResultSet resultSet = statement.executeQuery(sql);
        // 正向处理结果集
        while ( resultSet.next() ) {
            int id = resultSet.getInt("id");
            int age = resultSet.getInt("age");
            String name = resultSet.getString("name");
            System.out.println(id + " , " + name + " , " + age );
        }
        System.out.println("==============================");
        // 回滚处理结果集
        while ( resultSet.previous() ) {
            int id = resultSet.getInt("id");
            int age = resultSet.getInt("age");
            String name = resultSet.getString("name");
            System.out.println(id + " , " + name + " , " + age );
            // 修改结果集中的数据
            resultSet.updateInt("age",20);
            // 将修改的数据写到底层数据库
            resultSet.updateRow();
        }
        // 释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

六、资源释放代码

物理资源的链接是珍贵的,是有数目限制的。如果只有打开没有关闭,那么当达到一个限定之后,其他人将无法继续连接数据库。所以需要关闭连接,我们上述的关闭方式是有问题的,一旦发生了异常程序终止就无法关闭资源了,所以对于程序中的异常,我们应该捕获处理。

代码演示

import java.sql.*;
public class Demo {
    public static void main(String[] args)  {
        // 数据库链接对象
        Connection connection = null;
        // Statement 发送sql语句对象
        Statement statement = null;
        // 结果集对象
        ResultSet resultSet = null;
        try {
            // 注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 建立链接
            String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
            String user = "root";
            String password = "root";
            connection = DriverManager.getConnection(url, user, password);
            // 获取Statement对象
            statement = connection.createStatement();
            // 向数据库发送sql语句
            String sql = "select * from person";
            resultSet = statement.executeQuery(sql);
            // 处理结果
            while (resultSet.next()) {
                // 获取数据
                String name = resultSet.getString("name");
                int id = resultSet.getInt("id");
                int age = resultSet.getInt("age");
                System.out.println(id + " , " + name + " , " + age);
            }
        }catch (Exception e ) {
            e.printStackTrace();
        } finally {
            // 释放资源
            try {
                // 非空判断
                if( resultSet != null ) {
                    resultSet.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if( statement != null ) {
                    statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if( connection != null ) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

七、JDBC CRUD 操作

7.1、插入insert

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        // 获取Statement对象
        Statement statement = connection.createStatement();
        // 发送SQL语句
        String sql = "insert into person values(null,'孙尚香',33)";
        int count = statement.executeUpdate(sql);
        System.out.println("您成功插入了" + count + "条数据");
        // 释放资源
        statement.close();
        connection.close();
    }
}

7.2、修改update

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        // 获取Statement对象
        Statement statement = connection.createStatement();
        // 发送SQL语句
        String sql = "update person set age = 30 where id = 5";
        int count = statement.executeUpdate(sql);
        System.out.println("您修改了" + count + "条数据");
        // 释放资源
        statement.close();
        connection.close();
    }
}

7.3、删除delete

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        // 获取Statement对象
        Statement statement = connection.createStatement();
        // 发送SQL语句
        String sql = "delete from person where id = 5";
        int count = statement.executeUpdate(sql);
        System.out.println("您删除了" + count + "条数据");
        // 释放资源
        statement.close();
        connection.close();
    }
}

7.4、查询select

import java.sql.*;
public class Demo {
    public static void main(String[] args) throws Exception {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        // 获取Statement对象
        Statement statement = connection.createStatement();
        // 发送SQL 语句
        String sql = "select * from person";
        ResultSet resultSet = statement.executeQuery(sql);
        // 处理结果集
        while ( resultSet.next() ) {
            int id = resultSet.getInt("id");
            int age = resultSet.getInt("age");
            String name = resultSet.getString("name");
            System.out.println(id + " , " + name + " , " + age );
        }
        // 释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

八、工具类封装

上述的代码演示的过程中,我们会发现,在每一个程序中都要重复注册驱动,建立连接、包括释放资源的代码。代码的复用性降低,此时可以将对应的代码封装成方法,需要时调用即可。

8.1、基础方式抽取

工具类代码演示

import java.sql.*;
public class JDBCUtils {
    // 静态代码块 注册驱动
    static{
        /*
            注册驱动的代码放在获取连接对象的方法中,每个获取驱动时都会加载一次
            可以通过静态代码块的方式加载,好处是只会在类加载的时候注册一次
            反而更加好用
          */
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    // 获取连接功能封装
    public static Connection getConnection() throws SQLException, ClassNotFoundException {

        // 建立连接
        String url = "jdbc:mysql://localhost:3306/myjdbc?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        return connection;
    }
    // 释放资源的代码封装 关闭三个资源对象
    public static void close(Connection connection, Statement statement , ResultSet resultSet) {
        try {
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 调用重载的关闭两个资源的方法
        JDBCUtils.close(connection,statement);
    }
    // 释放资源的代码封装 关闭两个资源对象
    public static void close(Connection connection, Statement statement ) {
        try {
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

具类JDBC代码演示

import java.sql.*;
public class Demo {
    public static void main(String[] args)  {
        // 创建jdbc对象
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            // 建立连接
            connection = JDBCUtils.getConnection();
            // 获取Statement对象
            statement = connection.createStatement();
            // 发送SQL 语句
            String sql = "select * from person";
            resultSet = statement.executeQuery(sql);
            // 处理结果集
            while ( resultSet.next() ) {
                int id = resultSet.getInt("id");
                int age = resultSet.getInt("age");
                String name = resultSet.getString("name");
                System.out.println(id + " , " + name + " , " + age );
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(connection,statement,resultSet);
        }
    }
}

8.2、配置文件抽取

准备配置文件

准备配置文件

代码演示

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
    // 考虑把驱动的路径和数据库的相关信息配置到文件中,需要时候再去读取
    static String url;
    static String user;
    static String password;
    static String driverClass;
    // 静态代码块 注册驱动
    static{
        // 创建Properties属性集对象
        Properties prop = new Properties();
        try {
        // 将配置文件中的数据,读取到属性集中
            prop.load( new FileInputStream("prop.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 根据key值获取配置文件中的数据
        url = prop.getProperty("urlName");
        user = prop.getProperty("userName");
        password = prop.getProperty("passwordName");
        driverClass = prop.getProperty("driverClassName");
        // 注册驱动
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    // 获取连接功能封装
    public static Connection getConnection() throws SQLException, ClassNotFoundException {
        // 建立连接
        Connection connection = DriverManager.getConnection(url, user, password);
        return connection;
    }
    // 释放资源的代码封装 关闭三个资源对象
    public static void close(Connection connection, Statement statement , ResultSet resultSet) {
        try {
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 调用重载的关闭两个资源的方法
        JDBCUtils.close(connection,statement);
    }
    // 释放资源的代码封装 关闭两个资源对象
    public static void close(Connection connection, Statement statement ) {
        try {
            statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

九、异常处理

public class Demo04_Exception {
    public static void main(String[] args) {
        // 声明对象
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            // 1.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2.获取连接
            String url = "jdbc:mysql://localhost:3306/sh2306?characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
            String user = "root";
            String password = "root";
            connection = DriverManager.getConnection(url, user, password);
            // 3.获取Statement对象
            statement = connection.createStatement();
            // 4.发送SQL语句,返回结果
            String sql = "select * from person";
            resultSet = statement.executeQuery(sql);
            // 5.处理结果
            while (resultSet.next()) {
                System.out.println(resultSet.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6.释放资源
            if(resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值