JDBC基础使用方法

JDBC基础语法

简介

  1. 什么是JDBC
    • 是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法,我们通常说的JDBC是面向关系型数据库的
    • 通俗的说就是java公司编写的一套规范,和Java连接的数据库,都要遵守这个规范来编写驱动程序。

使用步骤

  1. 以mySQL为例,展示数据库与ieda的连接

  2. 由于Java只是给出了规范没有具体的连接数据的类,所以我们需要导入第三方编写好的类来连接

    • 在官网上下载jar包,将包导入到程序中,通常在程序中创建lib文件夹,导入后一定要依赖一下

  3. 和数据库的连接步骤

    1. 通过反射加载驱动

      Class.forName("com.mysql.cj.jdbc.Driver");
      
    2. 获取连接对象

      String url="jdbc:mysql://127.0.0.1:3306/shoping?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";
      String username="root";
      String password="13892035";
      DriverManager.getConnection(url,username,password);
      

      要注意由于数据库的版本不相同,在定义url上也有区别,数据库8.0是上述表示定义的。5.7的url是这样定义的:String url=“jdbc:mysql://localhost:3306/mydb”;

    3. 获取操作对象

      Connection connection = DriverManager.getConnection(url, username, password);
      PreparedStatement preparedStatement = connection.prepareStatement("select *from users");
      
    4. 发送sql语句

      ResultSet resultSet = preparedStatement.executeQuery();
      
    5. 释放资源

      connection.close();
      preparedStatement.close();
      resultSet.close();
      

    以上就是Java连接数据库的基本操作步骤

获取操作对象

  1. 获取操作对象的两种方式

    • Statement statement = connection.createStatement();
      statement.executeQuery(“select *from users”);

      这种方式获取操作对象,在发送sql语句时,可能有sql注入发生,这样就会产生非法获取数据,因此这种方式获取操作对象我们一般是不用的

    • PreparedStatement preparedStatement = connection.prepareStatement(“select *from users”);

      表示预编译的 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。使用如下

      Connection connection2 = JDBCUtils.getConnection();
      //获取预编译sql语句对象
      PreparedStatement preparedStatement1 = connection2.prepareStatement("select users.id,users.username,orders.oid,miditem.ppid,products.*from users join orders on users.id=orders.uid and users.username=? join miditem on orders.oid=miditem.ooid join products on miditem.ppid=products.pid ");
      //设置?的参数值
      preparedStatement1.setString(1, name);
      ResultSet resultSet3 = preparedStatement1.executeQuery();
      

发送sql语句

  1. 预编译对象发送sql语句

    返回值方法描述
    booleanexecute()发送SQL语句,这个语句可以是各种类型的,一些预处理过的语句返回多个结果,execute 方法处理这些复杂的语句
    voidaddBatch()将一组参数添加到此 PreparedStatement 对象的批处理命令中。
    int[]executeBatch()发送批处理操作
    ResultSetexecuteQuery()执行sql查询,并返回查询的结果集
    intexecuteUpdate()该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 语句;
    • 批处理,先将要发送的数据添加到批处理,先存在缓存中,这样比一条条发送数据效率要高,

        Connection connection = DriverManager.getConnection(url, user, password);
        PreparedStatement preparedStatement = connection.prepareStatement("insert into demo(username,upassword) values(?,?)");
      preparedStatement.setString(1,"liuhao");
      preparedStatement.setString(2,"1234556");
      //添加到批处理中
        preparedStatement.addBatch();
        preparedStatement.setString(1,"lihui");
        preparedStatement.setString(2,"1234556");
        preparedStatement.addBatch();
        preparedStatement.setString(1,"zhaowei");
        preparedStatement.setString(2,"1234556");
        preparedStatement.addBatch();
      //发送批处理操作
        long[] longs = preparedStatement.executeBatch();
      
  2. 获取自增键

    有时候我们在添加数据的时候,需要获取自增长的键值,这样我们就要在获取操作对象时,就要添加一个参数:Statement.RETURN_GENERATED_KEYS

    //获取自增长键值
    PreparedStatement preparedStatement = connection2.prepareStatement("insert into orders(uid) values (?)", Statement.RETURN_GENERATED_KEYS);
    preparedStatement.setInt(1, userId);
    int i = preparedStatement.executeUpdate();
    if (i == 1) {
        ResultSet oid = preparedStatement.getGeneratedKeys();
        while (oid.next()){
             ooid = oid.getInt(1);
        }
    

事务

  1. 概念:数据库中的一个操作,这个操作肯能有很多步骤,但是要将这些步骤看成一个整体操作,要么同时成功,或者同时失败,而不能以部分成功,一部分失败。提交失败就回滚到原来的状态

    • 例如,在银行取钱过程这就是一个事务,账户余额查询,减少,出钱,这几个步骤就要同时成功,或者同时失败。
  2. 在现在的数据库中,默认自动开启事务

  3. 事务的四大特性:

    原子性:事务的操作不可分割,要么同时成功,要么同时失败

    一致性:事务必须让数据库从一个一致性状态切换到另一个一致性状态

    隔离性:数据库被多个用户并发访问时,数据库为每个客户开启的事务不能被其他事务的数据访问。

    持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

  4. 事务的创建

    //示例1
    //订单在创建一半时,如果出现异常就要回滚到原来的状态
     connection2.setAutoCommit(false);// 设置事务
    //        Savepoint savepoint = connection2.setSavepoint();  如果想要回到指定的点,那就要设置事务的回滚点
            ResultSet resultSet1 = null;
            int ooid = 0;
            try {
                PreparedStatement statement1 = connection2.prepareStatement("select id from users where username=?");
                statement1.setString(1, name);
                resultSet1 = statement1.executeQuery();
                ooid = -1;
                if (resultSet1.next()) {
                    int userId = resultSet1.getInt(1);
                    PreparedStatement preparedStatement = connection2.prepareStatement("insert into orders(uid) values (?)", Statement.RETURN_GENERATED_KEYS);
                    preparedStatement.setInt(1, userId);
                    int i = preparedStatement.executeUpdate();
                    if (i == 1) {
                        ResultSet oid = preparedStatement.getGeneratedKeys();
                        while (oid.next()) {
                            ooid = oid.getInt(1);
                        }
    //                            System.out.println(oid);
                        System.out.println("请输入商品编号  0:退出并提交");
                        Scanner sc2 = new Scanner(System.in);
    
                        boolean flag = true;
                        while (flag) {
                            int produnctNum = sc2.nextInt();
                            if (produnctNum != 0) {
                                PreparedStatement preparedStatement1 = connection2.prepareStatement("insert into miditem(ooid,ppid) values (?,?)");
                                preparedStatement1.setInt(1, ooid);
                                preparedStatement1.setInt(2, produnctNum);
                                int i1 = preparedStatement1.executeUpdate();
                                if (i1 == 1) {
                                    System.out.println("提交成功");
                                } else {
                                    System.out.println("订单提交失败");
                                }
                            } else {
                                flag = false;
                            }
                        }
                    }
                }
            } catch (Exception throwables) {
    //            如果出错就回滚到原来的状态
                connection2.rollback();
            } finally {
    //            完成就提交事务
                connection2.commit();
            }
    
    
    //示例2
    try {
        conn = JDBCUtils.getConnection();
        conn.setAutoCommit(false); //把事务设置为手动提交。
    
        String sql1 = "UPDATE bank SET money=money-1000 WHERE NAME='zhangsan'";
        PreparedStatement preparedStatement = conn.prepareStatement(sql1);
        int i = preparedStatement.executeUpdate();
        //模拟异常
        //System.out.println(1/0);
    
        //加钱
        String sql2 = "UPDATE bank SET money=money+1000 WHERE NAME='lisi'";
        PreparedStatement preparedStatement2 = conn.prepareStatement(sql2);
        int i2 = preparedStatement2.executeUpdate();
    
        System.out.println("====================================");
    
         //设置回滚点
    
         //hehe = conn.setSavepoint();
        //第二次转账
        String sql3 = "UPDATE bank SET money=money-500 WHERE NAME='zhangsan'";
        PreparedStatement preparedStatement3 = conn.prepareStatement(sql3);
        preparedStatement3.executeUpdate();
        //模拟异常
          System.out.println(1 / 0);
    
        //加钱
        String sql4 = "UPDATE bank SET money=money+500 WHERE NAME='lisi'";
        PreparedStatement preparedStatement4 = conn.prepareStatement(sql4);
       preparedStatement4.executeUpdate();
    
    
    } catch (Exception e) {
        e.printStackTrace();
        //一旦遇到异常,就回滚事务
        conn.rollback();
        //回滚到回滚点的地方
        // conn.rollback(hehe);
    }finally {
        //手动提交事务
        conn.commit();
    }
    
  5. 事务的隔离

    • 事务在不同的隔离等级下有不同的数据访问状态
    • read uncommitted 读未提交 上面的三个问题都会出现 出现数据脏读
    • read committed 读已提交 可以避免脏读的发生 Oracle 默认级别
    • epeatable read 可重复读 可以避免脏读和不可重复读的发生 MySQL 默认级别
    • serializable 串行化 可以避免所有的问题
  6. 不隔离产生的问题

    脏读:在一个事务中读取到另一个事务没有提交的数据

    不可重复读:在一个事务中,两次查询的结果不一致(针对的update操作) 不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。

    虚读(幻读):在一个事务中,两次查询的结果不一致(针对的insert操作) 无法演示出来,MySQL已经默认避免了

和不可重复读的发生 MySQL 默认级别

  • serializable 串行化 可以避免所有的问题
  1. 不隔离产生的问题

    脏读:在一个事务中读取到另一个事务没有提交的数据

    不可重复读:在一个事务中,两次查询的结果不一致(针对的update操作) 不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。

    虚读(幻读):在一个事务中,两次查询的结果不一致(针对的insert操作) 无法演示出来,MySQL已经默认避免了

  2. 数据库默认的就是epeatable read 的数据访问状态,一般情况下我们不会去修改这个状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值