Java高级--JDBC

1.为什么使用JDBC

  • 现在程序中的数据状态:瞬时的,将来程序中的数据必须是:持久化的

  • 所以要把程序中的数据放在数据库中,在java程序中,如果要连接访问数据库,就需要JDBC

  • 选择项目要用的数据库

    • Oracle MySQL

  • 在使用数据库这方面,java是老大,它制定程序使用数据库的规范(接口),各个数据库厂商按照java语言的要求来提供相应的程序供开发人员使用

  • JDBC(java database connectivity),java数据库连接

    • sun公司制定的java应用程序操作关系型数据库的规范(接口),供各个数据库厂商遵循,以便它们提供自己的数据库驱动(实现类,操作自己的数据库)。

2.JDBC连接数据库的步骤

public static void main(String[] args) throws Exception {
    //1.导入驱动jar包
    //2.加载数据库驱动类
    //Class.forName("com.mysql.cj.jdbc.Driver");
    //3.连接数据库,获取数据库连接对象
    //数据库使用的时区和本地时区有区别,UTC是统一世界标准时间
    Connection connection = DriverManager
            .getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
    System.out.println(connection + "数据库连接成功");
​
    //4.操作数据库
    //4.1查询数据库
    //定义查询SQL,注意select后面不能出现*
    String sql = "select empno eno, ename, sex, hiredate from emp";
​
    //5.获取执行sql的Statement对象
    Statement statement = connection.createStatement();
    //6.执行SQL,获取查询结果集
    ResultSet resultSet = statement.executeQuery(sql);
    //7.遍历结果集
    System.out.println("员工编号\t员工姓名\t性别\t入职日期");
    while(resultSet.next()) {//next():判断是否还有下一条记录,有的话就指向这条数据
        //循环一次,代表获取一条记录
        //int---getInt() varchar---getString()  double---getDouble()
        System.out.println(resultSet.getInt("eno") + "\t"
                + resultSet.getString("ename") + "\t"
                + resultSet.getString("sex") + "\t"
                + resultSet.getString("hiredate"));
    }
    //8.关闭资源  connection、statement、resultset //注意异常处理
    resultSet.close();
    statement.close();
    connection.close();
}
  1. 导入驱动jar包:

    • 在项目下创建lib文件夹,将驱动jar包复制到该文件夹下

    • 右键lib文件夹,选择add as Library

  2. 加载驱动程序

    • 通过Class.forName("类名")加载到JVM中,驱动被加载成功后,就自动注册到DriverManager里去里

  3. 获取数据库连接对象

    • Connection conn = DriverManager.getConnection(url,user,password)

    • url就是连接数据库的url(网址,统一资源定位符)

      • 连接mysql数据库的url为:jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC

      • 组成

        • 协议:jdbc

        • 子协议:mysql

        • 数据库所在服务器的IP地址:如果是本机是localhost或127.0.0.1

        • 端口号:3306

        • 数据库名称:mwb

        • 统一世界标准时间:serverTimezone=UTC

  4. 定义sql语句

    • 涉及字符串的拼接

      • StringBuffer append()

      • StringBuffer转换为String toString()

  5. 获取一个执行sql的对象Statement,它执行的是静态的sql

    • 获取Statement对象:Statement statement = conn.createStatement();

    • 执行sql时,常用的方法有以下三种

      • execute():可以执行所有的sql语句,但是因为它的返回值是boolean类型,所以很少使用

      • executeQuery():执行DQL(select)语句,它的返回值是结果集ResultSet

      • executeUpdate():这个方法是用来更新数据的,一般用它来执行DML(insert、update、delete)语句,返回值类型为int,代表你的sql语句作用了几条记录,通过这个值可以判断sql语句是否执行成功,大于0则执行成功,否则执行失败

  6. 获取结果集

    • ResultSet rs = statement.executeQuery(sql);

    • 遍历结果集,通过rs的next()方法,注意:此方法包含判断结果集中是否还有记录以及向下移动记录

    • 获取具体的字段值时,需要根据数据库表中字段的数据类型来选择相应的方法

    • int(10)----getInt("字段名"),这里的字段名时select后的字段,不是数据库表中的字段

    • varchar(100)----getString("字段名")

  7. 关闭资源

    • 所有的资源在使用完后必须释放,也就是通过close()方法关闭

    • Connection Statement ResultSet的对象

  • 注意处理异常

3.JDBC API

  • 由sun公司开发的,供程序员调用的接口和类

  • 数据库驱动程序:由各个数据库厂商根据JDBC规范开发的jar包

  • DriverManager类:管理各个数据库驱动程序的类

    • 注册驱动

    • 获取数据库连接

  • Connection接口:负责连接数据库并承担数据传输任务的接口,每连接到一个数据库就会获得一个连接对象

    • 获取执行SQL的statement对象

    • 管理事务

      • 开启事务、提交事务、回滚事务

  • Statement接口:由Connection产生,用来执行具体的静态的sql语句

  • PreparedStatement接口:用来执行动态的或称为预编译的sql语句

  • ResultSet接口:查询结果集,负责保存执行查询语句后所产生的查询结果(executeQuery的返回值类型)

4.资源的释放

  • 程序的执行不论成功还是失败,都应对资源进行释放,因为资源是占用内存的,所以应该将资源的释放放在finally中,异常的处理应该使用try-catch,不应该抛出

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection conn = null;
        Statement statement = null;
        try {
            conn = DriverManager
                    .getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
            String sql = "update emp set ename='貂蝉', sex='女' where empno=4";
            statement = conn.createStatement();
            int num =statement.executeUpdate(sql);
            if (num > 0) {
                System.out.println("修改成功");
            } else {
                System.out.println("修改失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    ​
    }

5.PreparedStatement

public static void main(String[] args) {
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        conn = DriverManager
                .getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
        //使用?做占位符,有几个值写几个?
        String sql = "insert into emp values(null, ?, ?, ?)";
        //创建PreparedStatement对象,PreparedStatement继承了Statement,同时预编译sql
        ps = conn.prepareStatement(sql);
        //设置占位符内容,有几个问号,就需要几个值
        ps.setString(1, "赵云");
        ps.setString(2, "男");
        ps.setString(3, "2022-04-09");
        //执行sql
        int num = ps.executeUpdate();
        if (num > 0) {
            System.out.println("新增成功");
        } else {
            System.out.println("新增失败");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            assert conn != null;
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
​
    }
}
  • PreparedStatement接口继承了Statement接口,项目中一般使用PreparedStatement, 用于执行预编译的动态的SQL,这个对象执行的SQL语句中,通过?占位符来设置数据或字段

  • 优点: 1.可以更加灵活方便的设置参数,使用了?占位符 2.提高了代码的可读性,可维护性和复用性 3.提高了sql语句执行的性能,有一个预编译的过程 4.提高了代码的安全性,有效防止sql注入,用?占位符,是将输入作为一个整体

6.JDBC对事务的支持

public static void main(String[] args) {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
        //关闭自动提交,开启事务
        conn.setAutoCommit(false);
        //执行多条新增操作
        String sql = "insert into emp (ename, sex, hiredate) values(?,?,?)";
        //创建PreparedStatement对象,并预编译SQL
        ps = conn.prepareStatement(sql);
        //设置占位符内容
        //插入第一个员工
        ps.setString(1,"小乔");
        ps.setString(2,"女");
        ps.setString(3,"2022-03-07");
        //执行sql
        ps.executeUpdate();
​
        //插入第二个员工
        ps.setString(1,"周瑜");
        ps.setString(2,"男");
        ps.setString(3,"2022-02-07");
        ps.executeUpdate();
​
        ///提交事务
        conn.commit();
    } catch (SQLException e) {
        try {
            if (conn != null) {
                conn.rollback();
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        e.printStackTrace();
    } finally {
        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  • 数据库事务:数据库中的最小执行单元,通常包含一条或多条sql,这些sql要么全部执行成功,如果有一条执行失败,则全部回滚。

  • JDBC连接提供了事务支持,由Connection提供

    • 默认情况下,Connection开启自动提交,即关闭事务,执行完一条sql语句后就直接更新到数据库

    • 在执行sql语句之前调用Connection的setAutoCommit(false)关闭自动提交

      • 关闭自动提交,开启事务

      • connection.setAutoCommit(false);

    • 一般项目中涉及到批量操作(增删改)的时候,我们才会将它设置为false,然后通过Connection的commit()来提交,单独的增删改,不需要设置

      • 提交事务

        connection.commit();

    • 如果任意一条sql语句执行失败,则需要使用Connection的rollback()来回滚事务,保证操作的原子性

      • 回滚事务:

        connection.rollback();

  • 注意:实际上,当Connection遇到一个未处理的SQLException时,系统会非正常退出,事务也会自动回滚,但是如果程序捕获到了该异常,则需要在异常处理块中显式的回滚事务

7.JDBC批处理

  • 将多条sql语句一次性发送到服务器,而不是多条sql发送多次

  • 除事务的支持外,jdbc还提供了批量更新的功能,即多条sql被作为一批操作被同时收集并同时执行

  • JDBC批量更新-->Statement

    try {
        conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
        statement = conn.createStatement();
        //执行多条删除操作
        String sql1 = "delete from emp where empno = 1";
        //通过addBatch()方法添加多条sql
        statement.addBatch(sql1);
        String sql2 = "delete from emp where empno = 2";
        statement.addBatch(sql2);
        String sql3 = "delete from emp where empno = 3";
        statement.addBatch(sql3);
        //批量执行
        statement.executeBatch();
    }
  • JDBC批量更新-->PreparedStatement

    try {
        conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mwb?serverTimezone=UTC","root","123456");
        String sql = "update emp set hiredate = ? where empno = ?";
        ps = conn.prepareStatement(sql);
        //第一个员工
        ps.setString(1,"2021-09-08");
        ps.setInt(2,4);
        //添加sql
        ps.addBatch();
        ps.setString(1,"2020-02-02");
        ps.setInt(2,5);
        ps.addBatch();
        //统一执行
        ps.executeBatch();
    }
  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值