MySQL实战系列 -- 4. 原生JDBC

306 阅读8分钟

作者: 欢迎观看我的文章, 注定了我们今生有缘分! 我已从事Java开发教育十多年, 怀着教书育人的情怀, 正在让更多的同学们少走弯路, 改变千万IT人的命运!

期待同学动动你的小手给'霈哥'点赞、加关注、分享给更多的朋友共同学习交流, 每天持续更新离不开你的支持! 3Q

欢迎关注我的B站,可观看本文章配套视频~~~ 欢迎关注我的公众号,获取更多资料~~~


学习目标

  • 能够理解JDBC的概念
  • 能够使用DriverManager类
  • 能够使用Connection接口
  • 能够使用Statement接口
  • 能够使用ResultSet接口

第一章 JDBC

1.1 JDBC概述

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

JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。 今天我们使用的是mysql的驱动mysql-connector-java-8.0.15.jar

JDBC规范(掌握四个核心对象):

  • DriverManager:用于注册驱动
  • Connection: 表示与数据库创建的连接
  • Statement: 操作数据库sql语句的对象
  • ResultSet: 结果集或一张虚拟表

1.2 JDBC原理

Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。

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

1.3 JDBC入门案例

准备数据

之前我们学习了sql语句的使用,并创建的分类表category及 用户表users,今天我们将使用JDBC对分类表进行增删改查操作。

#创建分类表
create table category(
	cid int PRIMARY KEY AUTO_INCREMENT,
  	cname varchar(100)
);
#初始化数据
insert into category (cname) values('家电');
insert into category (cname) values('服饰');
insert into category (cname) values('化妆品');

#创建用户表
create table users(
	uid int PRIMARY KEY AUTO_INCREMENT,
  	username varchar(100),
    `password` varchar(100)
);
#初始化数据
insert into users (username, password) values('admin','1234');
insert into users (username, password) values('jack','1234');
insert into users (username, password) values('rose','1234

导入驱动jar包

创建lib目录,存放mysql的驱动mysql-connector-java-8.0.15.jar

选中mysql的jar包,右键选择“ Add as Library...” 完成jar导入

开发步骤

  1. 注册驱动.
  2. 获得连接.
  3. 获得执行sql语句的对象
  4. 执行sql语句,并返回结果
  5. 处理结果
  6. 释放资源.

案例实现

/**
 * 通过JDBC 完成对 数据库表 的 增删改查操作
 */
public class JDBCDemo {

    @Test
    public void testJDBC() throws ClassNotFoundException, SQLException {
        //1.注册驱动,  就是把 Driver.class 文件 加载到内存
        Class.forName("com.mysql.jdbc.Driver");

        /**
         *   2.获得连接
         *   参数 url : 需要连接数据库的地址  jdbc:mysql://IP地址:端口号/要连接的数据库名称
         *   参数 user : 连接数据库 使用的用户名
         *   参数 password: 连接数据库 使用的密码
         */
        String url = "jdbc:mysql://localhost:3306/mydb";
        Connection conn = DriverManager.getConnection(url, "root", "root");
        System.out.println("conn = " + conn);

        //3.获取执行sql语句的对象
        Statement stat = conn.createStatement();

        //4.执行sql语句, 并返回结果
        String sql = "select * from category";
        ResultSet rs = stat.executeQuery(sql);
        System.out.println("rs = " + rs);

        //5.处理结果
        while (rs.next()) {
            //int cid = rs.getInt(1); // 通过列的位置 获取值
            //int cid2 = rs.getInt("cid"); //通过列的名称 获取值
            int cid = rs.getInt("cid");
            String cname = rs.getString("cname");
            System.out.println("cid = " + cid + ", cname = " + cname);
        }

        //6.释放资源
        rs.close();
        stat.close();
        conn.close();
    }
}

1.4 API详解

API详解:注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用,原因有2个:

  • 导致驱动被注册2次
  • 强烈依赖数据库的驱动jar

解决办法:

  • Class.forName("com.mysql.jdbc.Driver");

API详解:获得链接

static Connection getConnection(String url, String user, String password) :试图建立到给定数据库 URL 的连接。

  • 参数说明:
    • url 需要连接数据库的位置(网址)
    • user用户名
    • password 密码
  • 例如:getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");

扩展:

URL: SUN公司与数据库厂商之间的一种协议。

jdbc:mysql://localhost:3306/mydb

协议子协议 IP :端口号数据库 mysql数据库: jdbc:mysql://localhost:3306/mydb 或者 jdbc:mysql:///mydb(默认本机连接) ​ oracle数据库: jdbc:oracle:thin:@localhost:1521:sid

API详解:java.sql.Connection接口:一个连接

接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。

  • Statement createStatement(); //创建操作sql语句的对象

API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果

String sql = "某SQL语句";
获取Statement语句执行平台:Statement stmt =con.createStatement();

常用方法:

  • int executeUpdate(String sql); --执行insert update delete语句.

  • ResultSet executeQuery(String sql); --执行select语句.

  • boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.

API详解:处理结果集(注:执行insert、update、delete无需处理)

ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法来获取指定列的数据:(与数组索引从0开始不同,这里索引从1开始)

rs.next();//指向第一行
rs.getInt(1);//获取第一行第一列的数据

常用方法:

  • Object getObject(int index) / Object getObject(String name) 获得任意对象

  • String getString(int index) / String getString(String name) 获得字符串

  • int getInt(int index) / int getInt(String name) 获得整形

  • double getDouble(int index) / double getDouble(String name) 获得双精度浮点型

API详解:释放资源

与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。

rs.close();
stmt.close();
con.close();

1.5 JDBC增删改查操作

插入

    @Test
    public void testJDBC2() throws SQLException, ClassNotFoundException {
        /**
         * JDBC 完成 记录的插入
         * 1.注册驱动
         * 2.获得连接 
         * 3.获得执行sql语句的对象
         * 4.执行sql语句, 并返回结果
         * 5.处理结果
         * 6.释放资源
         * 注意: 若插入中文出现乱码, 请设置编码
         		jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
         */
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
        Connection conn = DriverManager.getConnection(url, "root", "root");
        Statement stat = conn.createStatement();

        String sql = "insert into category(cname) values('测试')";
        int result = stat.executeUpdate(sql);
        System.out.println("result = " + result);

        stat.close();
        conn.close();
    }

修改

    @Test
    public void testJDBC3() throws SQLException, ClassNotFoundException {
        /**
         * JDBC 完成 记录的更新
         * 1.注册驱动
         * 2.获得连接
         * 3.获得执行sql语句的对象
         * 4.执行sql语句, 并返回结果
         * 5.处理结果
         * 6.释放资源
         */
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
        Connection conn = DriverManager.getConnection(url, "root", "root");
        Statement stat = conn.createStatement();

        String sql = "update category set cname='测试2' where cid=4";
        int result = stat.executeUpdate(sql);
        System.out.println("result = " + result);

        stat.close();
        conn.close();
    }

删除

    @Test
    public void testJDBC4() throws SQLException, ClassNotFoundException {
        /**
         * JDBC 完成 记录的删除
         * 1.注册驱动
         * 2.获得连接
         * 3.获得执行sql语句的对象
         * 4.执行sql语句, 并返回结果
         * 5.处理结果
         * 6.释放资源
         */
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
        Connection conn = DriverManager.getConnection(url, "root", "root");
        Statement stat = conn.createStatement();

        String sql = "delete from category where cid=4";
        int result = stat.executeUpdate(sql);
        System.out.println("result = " + result);

        stat.close();
        conn.close();
    }

查询

    @Test
    public void testJDBC5() throws SQLException, ClassNotFoundException {
        /**
         * JDBC 完成 基于ID的查询
         * 1.注册驱动
         * 2.获得连接
         * 3.获得执行sql语句的对象
         * 4.执行sql语句, 并返回结果
         * 5.处理结果
         * 6.释放资源
         */
        // 通过id 查询数据
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
        Connection conn = DriverManager.getConnection(url, "root", "root");
        Statement stat = conn.createStatement();

        String sql = "select * from category where cid = 3";
        ResultSet rs = stat.executeQuery(sql);
        if (rs.next()) {
            int cid = rs.getInt("cid");
            String cname = rs.getString("cname");
            System.out.println("cid = " + cid + ",cname = " +cname);
        } else {
            System.out.println("数据没有查到");
        }

        rs.close();
        stat.close();
        conn.close();
    }

1.6 JDBC工具类

“获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。

该工具类提供方法:public static Connection getConnection()。代码如下:

  • jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=root
  • JDBC工具类
public class JDBCUtils {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;

    static {
        try {
            //使用类加载器, 读取配置文件
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            Properties prop = new Properties();
            prop.load(is);

            driver = prop.getProperty("jdbc.driver");
            url = prop.getProperty("jdbc.url");
            user = prop.getProperty("jdbc.user");
            password = prop.getProperty("jdbc.password");

            //注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回连接对象 Connection
     */
    public static Connection getConnection() throws SQLException {
       Connection conn = DriverManager.getConnection(url, user, password);
       return conn;
    }

    /**
     * 释放资源
     */
    public static void close(ResultSet rs, Statement stat, Connection conn) throws SQLException {
        if (rs != null) {
            rs.close();
        }
        if (stat != null) {
            stat.close();
        }
        //看Connection来自哪里, 如果Connection是从连接池里面获得的, close()方法其实是归还; 如果Connection是创建的, 就是销毁
        if (conn != null) {
            conn.close();
        }
    }
}
  • 使用JDBC工具类 完成查询
    @Test
    public void testJDBC6() throws SQLException {
        /**
         * 使用JDBC工具类, 完成查询所有分类
         * 1.通过JDBC工具类, 获得连接
         * 2.获得执行sql语句的对象
         * 3.执行sql语句, 并返回结果
         * 4.处理结果
         * 5.释放资源
         */
        Connection conn = JDBCUtils.getConnection();
        Statement stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("select * from category");
        while (rs.next()) {
            int cid = rs.getInt("cid");
            String cname = rs.getString("cname");
            System.out.println("cid = " + cid + ",cname = " + cname);
        }
        JDBCUtils.close(rs, stat, conn);
    }