【JDBC】

JDBC

什么是 JDBC

  1. 概述

    JDBC(Java DataBase Connectivity) 是一种开发与数据库无关的"一次编写, 到处运行" 的 Java 数据库应用程序的技术。

    同时,JDBC 规范定义接口,我们只需要调用 JDBC 接口中的方法即可,数据库驱动由数据库产商提供,具体的实现也由各大数据库厂商来实现。

    即编写的代码无需改变, 就可以访问不同的数据库。

  2. 好处

    提供了很简单、便捷的访问数据库的方法。
    非常灵活构建 SQL , 也可以编写很复杂的 SQL 语句。

使用 JDBC 连接数据库,执行数据库查询和增加、删除、修改。

注:
下文例子数据库名为"student" 、表名为"t_student",表结构如下:

【JDBC】

【JDBC】

  1. 导入驱动 Jar 包

    【JDBC】

    【JDBC】

    【JDBC】

    【JDBC】

  2. 加载驱动

// 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
  1. 连接数据库
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 16:08
 * @Description:
 */
public class JDBC {
    static Connection conn = null;

    private static void connectDB(String url, String name, String pwd) {
        try {
            // 加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 连接数据库
            conn = DriverManager.getConnection(url, name, pwd);
            System.out.println("连接数据库 : " + conn);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn != null || conn.isClosed()){
                   conn.close();
                   conn = null;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
    	// student 为创建的数据库名
        String url = "jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8";
        String name = "root";
        String pwd = "052018";
		// 拼接字符串URL 、 用户名 、 密码
        connectDB(url, name, pwd);
    }

}

连接结果界面: 成功
【JDBC】
4. 获取 Statement 对象并执行查询和更新的 SQL 语句
数据库里的数据:
【JDBC】

封装类:操作数据库的流程细节

import java.sql.*;
import java.util.Properties;

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 16:08
 * @Description:
 */
public class JDBC {
    static Connection conn = null;
    static Statement stmt = null;
    static ResultSet rs = null;

    public static void connectToAndQueryDB(String driverClass, String url, String name,String pwd, String sql) {
        try {
            // 加载 JDBC 驱动类
            Class.forName(driverClass);
            // 连接数据库
            Properties info;
            conn = DriverManager.getConnection(url, name, pwd);
            // 使用 Statement 对象执行 sql 语句并获取查询结果存储在 ResultSet 对象中
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);

            // 根据 rs 对象获取查询结果的元数据, 表的列数
            ResultSetMetaData rsm = rs.getMetaData();
            int count = rsm.getColumnCount();

            // 输出元数据
            for (int i = 1; i <= count; i++) {
                System.out.print(rsm.getColumnName(i) + "\t");
            }
            System.out.println();
            // 输出查询结果
            while (rs.next()) {
                for (int i = 1; i <= count ; i++) {
                    System.out.print(rs.getObject(i) + "\t");
                }
                System.out.println();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            // 最后关闭连接
            try {
                if (rs != null) {
                    rs.close();
                    rs = null;
                }
                if (stmt != null) {
                    stmt.close();
                    stmt = null;
                }
                if (conn != null  && conn.isClosed()) {
                    conn.close();
                    conn = null;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

执行类:调用封装类的方法去查询数据库

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 17:31
 * @Description:
 */
public class Test {

    public static void main(String[] args) {
        // 数据库驱动字符串
        String driverClass = "com.mysql.cj.jdbc.Driver";
        // 数据库 URL 字符串
        String url = "jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8";
        // 数据库用户名
        String name = "root";
        // 数据库密码
        String pwd = "052018";
        // 查询语句
        String querySQL = "select * from t_student";
        JDBC.connectToAndQueryDB(driverClass, url, name, pwd, querySQL);
    }
}

查询结果截图:

【JDBC】

  1. 增删改查的 SQL 语句

封装类新增一个方法

public static void connectToAndUpdateDB(String driverClass, String url, String name, String pwd, String sql){
        try {
            // 加载 JDBC 驱动类
            Class.forName(driverClass);
            // 连接数据库
            Properties info;
            conn = DriverManager.getConnection(url, name, pwd);
            // 使用 Statement 对象执行 sql 语句并获取查询结果存储在 ResultSet 对象中
            stmt = conn.createStatement();
            int n = stmt.executeUpdate(sql);
            System.out.println("已经更新了 " + n + "条记录");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            // 最后关闭连接
            try {
                if (rs != null) {
                    rs.close();
                    rs = null;
                }
                if (stmt != null) {
                    stmt.close();
                    stmt = null;
                }
                if (conn != null && conn.isClosed()) {
                    conn.close();
                    conn = null;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

注:
除了查询语句要调用 Statement 的 executeQuery(String sql) 函数, JDBC 的增删改功能都是调用另一个函数 executeUpdate(String sql) 就行。
在本例中,替换 JDBC.connectToAndUpdateDB(String driverClass, String url, String name, String pwd, String sql) 对应的 sql 语句就可以实现对应的功能。

// 插入语句
String insertSQL = "insert into t_student values('9090','小明','24')";
// 更新语句
String updateSQL = "update t_student set age = '29' where id== = '9090'";
// 删除语句
String deleteSQL = "delete from t_student where id = '9090'";

执行结果:

【JDBC】

【JDBC】

【JDBC】

  1. 查询结果集 ResultSet 的使用
  • 封装数据库查询的结果集, 对结果集进行遍历,取出每一条记录。
  • 实现 Statement 接口的任何对象 (包含 PreparedStatement ,CallalbleStatement 和 RowSet)都可以创建一个 ResultSet 对象。
ResultSet rs = stmt.executeQuery(sql);
  • 可以通过游标访问 ResultSet 对象的数据。
    游标可以看做是指向 ResultSet 对象中的一行数据的指针。
    最初,游标位于数据表第一行之前。 ResultSet.next() 方法将游标移动到下一行。如果游标位于最后一行之后,此方法返回 false,否则返回 true。 此方法可以作为 while 循环的条件, 来遍历 ResultSet 中的所有数据。

【JDBC】

  1. 获取 PreparedStatement 对象并执行增删改查语句,如果向包含 ?参数的 SQL 语句中插入参数值
  • PreparedStatement 接口是 Statement 的子接口, 它表示一条预编译过的 SQL 语句。

  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号 (?) 来表示。 ?在SQL中表示占位符
    调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值

编程实现了 ORM:使数据库中的字段 与 实体对象的属性相映射

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 20:47
 * @Description:
 */
public class Student {

    private Integer id;
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

操作数据库的封装类

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 16:08
 * @Description:
 */
public class JDBC {

    Connection con;

    /**
     * 连接数据库
     */
    public JDBC() {
        // 数据库驱动字符串
        String driverClass = "com.mysql.cj.jdbc.Driver";
        // 数据库 URL 字符串
        String url = "jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8";
        // 数据库用户名
        String name = "root";
        // 数据库密码
        String pwd = "052018";
        try {
            // 加载 JDBC 驱动类
            Class.forName(driverClass);
            // 连接数据库
            con = DriverManager.getConnection(url, name, pwd);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询
     * @return
     */
    public List<Student> query() {
        List<Student> list = new ArrayList<>();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        if (con != null) {
            try {
                // 获取 PrepareStatement 对象, 包含了一个 SQL 语句
                pstmt = con.prepareStatement("select * from t_student");
                // 用 PrepareStatement 对象执行查询语句, 获取的查询结果赋值给一个 ResultSet 对象
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    Student stu = new Student();
                    stu.setId(rs.getInt("id"));
                    stu.setName(rs.getString("name"));
                    stu.setAge(rs.getInt("age"));
                    list.add(stu);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (rs != null) {
                        rs.close();
                        rs = null;
                    }
                    if (pstmt != null) {
                        pstmt.close();
                        pstmt = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }

    /**
     * 插入数据
     * @param stu
     * @return
     */
    public boolean insert(Student stu) {
        PreparedStatement pstmt = null;
        if (con != null){
            try {
                // 获取 PrepareStatement 对象, 包含了一个带?参数 SQL 语句
                pstmt = con.prepareStatement("insert into t_student values (?,?,?)");
                pstmt.setInt(1, stu.getId());
                pstmt.setString(2, stu.getName());
                pstmt.setInt(3, stu.getAge());
                int i = pstmt.executeUpdate();
                if (i != 0){
                    return true;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (pstmt != null) {
                        pstmt.close();
                        pstmt = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }

        }
        return false;
    }

    /**
     * 修改学生信息
     * @param stu
     * @return
     */
    public boolean update(Student stu) {
        PreparedStatement pstmt = null;
        if (con != null) {
            try {
                pstmt = con.prepareStatement("update t_student set name = ?, age = ? where id = ?");
                pstmt.setString(1, stu.getName());
                pstmt.setInt(2, stu.getAge());
                pstmt.setInt(3, stu.getId());
                int i = pstmt.executeUpdate();
                if (i != 0) {
                    return true;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (pstmt != null) {
                        pstmt.close();
                        pstmt = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 按id删除学生记录
     * @param id
     * @return
     */
    public boolean deleteById(int id) {
        PreparedStatement pstmt = null;

        if (con != null) {
            try {
                pstmt = con.prepareStatement("delete from t_student where id=?");
                pstmt.setInt(1, id);
                int i = pstmt.executeUpdate();
                if (i != 0) {
                    return true;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (pstmt != null) {
                        pstmt.close();
                        pstmt = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

        }
        return false;
    }

    /**
     * 关闭数据库连接
     */
    public void close() {
        try {
            if (con != null) {
                con.close();
                con = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

可执行类:验证增删改查代码的可行性

import java.util.List;

/**
 * @Author: Travelmate
 * @CreateTime: 2021/5/28 17:31
 * @Description:
 */
public class Test {

    public static void main(String[] args) {
        // 创建封装类的构造方法连接数据库
        JDBC jdbc = new JDBC();

        System.out.println("查询的数据输出: ");
        List<Student> list = jdbc.query();
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        Student stu = new Student(9092, "小明", 15);
        if (jdbc.insert(stu)) {
            System.out.println("添加成功");
            System.out.println("添加后的数据: ");
            List<Student> list1 = jdbc.query();
            for (int i = 0; i < list1.size(); i++) {
                System.out.println(list1.get(i));
            }
        }else {
            System.out.println("添加失败");
        }

        stu.setName("小红帽");
        if (jdbc.update(stu)){
            System.out.println("更新成功");
            System.out.println("更新后的数据: ");
            List<Student> list1 = jdbc.query();
            for (int i = 0; i < list1.size(); i++) {
                System.out.println(list1.get(i));
            }
        }else {
            System.out.println("更新失败");
        }

        if (jdbc.deleteById(9092)){
            System.out.println("删除成功");
            System.out.println("删除后的数据: ");
            List<Student> list1 = jdbc.query();
            for (int i = 0; i < list1.size(); i++) {
                System.out.println(list1.get(i));
            }
        }else {
            System.out.println("删除失败");
        }
    }
}

执行结果截图:
【JDBC】

上一篇:JS Leetcode 198. 打家劫舍 题解分析,再次感受动态规划的魅力


下一篇:数据库操作整合成一个DBUtil,去除重复代码(如果报错,注意导包,导包应该导的是java.sql下的包)