JDBC基础的那些事,一篇搞定

1 概述

1.1 概念

JDBC, Java DataBase Connectivity, java 数据库连接. 通过 JDBC , 可以实现使用 java 代码操作数据库管理系统(DBMS), 使用 JDBC 主要是对数据库进行DML和DQL操作.

JDBC基础的那些事,一篇搞定_第1张图片

JDBC中重要的API

  • DriverManager, 类, 用来对驱动进行管理;
  • Connection, 接口, 表示和数据库间的连接;
  • Statement, 接口, SQL语句发送器, 将SQL语句发送到数据库进行执行;
  • ResultSet, 接口, 执行DQL操作的返回结果集.

1.2 数据库驱动

数据库驱动是数据库厂商对JDBC规范提供的实现, 用来帮助程序员简化相应DBMS的操作. 各厂商使用java代码完成驱动的开发, 开发成功后, 编译并进行打包为.jar格式的包对外发布, .jar文件中存储了所有的class文件. 只需要将.jar驱动文件加入到开发环境

MySQL的驱动叫: mysql-connector-java-xxx.jar

Oracle的驱动叫: ojdbc.jar

1.3 JDBC操作数据库的大致流程

  • 在项目中添加指定的驱动jar包;
  • 加载驱动
  • 建立数据库连接, 需要定位(数据库的位置, 驱动类, 用户名, 密码), Connection
  • 定义操作用的SQL语句
  • 将SQL语句发送到数据库执行, 需要使用发送器Statement
  • 接收数据库返回的结果. DML返回int, DQL返回ResultSet
  • 处理结果
  • 关闭资源. ResultSet, Statement, Connection. 先开后关

2 JDBC 实现 CRUD 操作

2.1 增删改操作

package com.wuyw.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

/**
 * jdbc实现MySQL数据库表格的DML操作
 * DML操作在jdbc中返回的结果都是int, 代表本次操作受影响的行数
 */
public class TestDML {
    public static void main(String[] args) throws Exception {
        // 声明连接参数
        String url = "jdbc:mysql://localhost:3306/mp"; // 数据库访问路径
        String user = "root"; // 用户名
        String password = "123456"; // 密码
        // 加载驱动类, 让虚拟机找到驱动类, 并且将驱动类交给DriverManager进行统一管理
        Class.forName("com.mysql.jdbc.Driver");
        // 建立连接, 通过DriverManager建立
        Connection conn = DriverManager.getConnection(url, user, password);
        // 定义SQL语句
        // String sql = "insert into emp values (6666, '小明', '程序员', 6379, now(), 600, 0, 10)";
        // String sql = "update emp set sal=700 where empno=6666";
        String sql = "delete from emp where empno=6666";
        // 得到SQL语句的发送器, 通过连接对象获取
        Statement stmt = conn.createStatement();
        // 发送并执行SQL语句, 得到结果
        int rows = stmt.executeUpdate(sql);
        // 处理结果
        if(rows == 1) {
            System.out.println("操作成功!");
        } else {
            System.out.println("操作失败!");
        }
        // 关闭资源
        stmt.close();
        conn.close();
    }
}

2.2 查询操作

package com.wuyw.jdbc;

import java.sql.*;

/**
 * 完成查询操作
 */
public class TestDQL {
    public static void main(String[] args) throws Exception {
        // 声明连接信息
        String url = "jdbc:mysql:///mp";
        String user = "root";
        String password = "123456";
        // 定义SQL语句
        String sql = "select * from emp";
        // 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
        // 获取数据库连接
        Connection conn = DriverManager.getConnection(url, user, password);
        // 获取发送器
        Statement stmt = conn.createStatement();
        // 发送并执行SQL语句, 得到结果集
        ResultSet rs = stmt.executeQuery(sql);
        // 处理结果集: 打印出每个员工的编号, 姓名, 入职日期和工资
        while(rs.next()) {
            int empno = rs.getInt(1);// 索引从1开始
            String ename = rs.getString("ename");
            Date hiredate = rs.getDate("hiredate");
            double sal = rs.getDouble("sal");
            String mgr = rs.getString("mgr");
            System.out.println("empno: "+empno+", ename: "+ename+", hiredate: "+hiredate+", sal: "+sal+", mgr: " + mgr);
        }
        // 关闭资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

3 PreparedStatement替代Statement

  • Statement是发送器的顶级接口. 每次发送sql语句到数据库时, 会先进行编译, 然后再执行.
  • PreparedStatement, 是Statement接口的子接口, 对Statement进行了扩展. 提供了对SQL语句预编译的功能. 支持再SQL语句中使用占位符(?). 一旦进行预编译, 那么SQL语句的结构就已经固定了, 后续用户的输入只能作为占位符位置的值出现.
package com.wuyw.jdbc;

import java.sql.*;
import java.util.Scanner;

/**
 * 模拟登录的实现, 使用PreparedStatement替代Statement
 *  数据库执行效率高
 *  防止SQL注入, 提高安全性
 */
public class TestLogin {
    public static void main(String[] args) throws Exception {
        // 声明信息
        String url = "jdbc:mysql:///db_scott?useSSL=false";
        String user = "root";
        String password = "123456";
        // 接收控制台用户输入的信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.nextLine();
        System.out.println("请输入密码:");
        String pwd = sc.nextLine();
        // 加载驱动类
        Class.forName("com.mysql.jdbc.Driver");
        // 连接
        Connection conn = DriverManager.getConnection(url, user, password);
        // 拼接sql语句, ?占位符
        String sql = "select count(*) from tb_user where username=? and password=?";
        // 发送器
        PreparedStatement pstmt = conn.prepareStatement(sql);
        // 参数绑定
        pstmt.setString(1, username);
        pstmt.setString(2, pwd);
        // 执行
        ResultSet rs = pstmt.executeQuery();
        // 处理结果
        while(rs.next()) {
            int cnt = rs.getInt(1);
            if(cnt == 1) {
                System.out.println("登录成功!");
            } else {
                System.out.println("登录失败!");
            }
        }
        // 关闭资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

4 JDBC进行事务管理

JDBC中默认自动提交事务, 在执行一条DML操作后事务就被自动提交了. JDBC中是通过Connection对象来控制事务的自动管理和手动管理的.

  • 管理是否自动提交: conn.setAutoCommit(true | false);
  • 事务的提交: conn.commit();
  • 事务的回滚: conn.rollback();
package com.wuyw.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

/**
 * 事务管理 - 模拟转账
 */
public class TestTx {
    public static void main(String[] args) throws Exception {
        // 声明信息
        String url = "jdbc:mysql:///mp";
        String user = "root";
        String password = "123456";

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(url, user, password);

        // 关闭自动提交事务
        conn.setAutoCommit(false);

        String sql1 = "update tb_account set balance=balance+100 where name='zhangsan'";
        String sql2 = "update tb_account set balance=balance-100 where name='lisi'";

        Statement s1 = conn.createStatement();
        Statement s2 = conn.createStatement();

        int r1 = s1.executeUpdate(sql1);
        int r2 = s2.executeUpdate(sql2);

        if(r1 == 1 && r2 == 1) {
            // 提交事务
            conn.commit();
            System.out.println("转账成功!");
        } else {
            // 回滚事务
            conn.rollback();
            System.out.println("转账失败!");
        }

        // 关闭资源
        s1.close();
        s2.close();
        conn.close();
    }
}

 

你可能感兴趣的:(java学习)