JDBC4—自动提交机制(演示转账)—工具类封装(演示模糊查询)—悲观锁、乐观锁、演示行级锁

1.自动提交机制

1.1.重点3行代码:
  •         conn.setAutoCommit(false / true);   false / true 决定自动提交开关
    
  •         conn.commit();
    
  •         conn.rollback();
    
1.2.银行转账
  • 账户1——>账户2 , 转账999
    1.2.1.创建账户:
    在这里插入图片描述

  •   drop table if exists t_act;
       create table t_act(
       actno int,
       balance double(7,2)    //7位有效数字。2位小数
       );
       insert into t_act(actno,balance) values (1,1999);
       insert into t_act(actno,balance) values (2,0);
       commit;
    
1.3.开启自动提交
  •   conn.setAutoCommit(true); //开启自动提交
    
  • 插入空指针异常,来中断代码,测试是否关闭自动提交!!!!!!

  •   String str = null;
      str.toString();
    

原账户:
在这里插入图片描述
执行结果:(错误)
在这里插入图片描述

public class JdbcAutoCommit {
    public static void main(String[] args) {

        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            //1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接(表示JVM的进程和数据库进程之间的  通道 打开了,使用完之后  必须关闭)
            String url = "jdbc:mysql://localhost:3306/bjpowernode"; //自己的地址链接
            String user = "root";
            String password = "333";
            conn = DriverManager.getConnection(url,user,password);


            conn.setAutoCommit(true); //开启自动提交
//            conn.setAutoCommit(false); //关闭自动提交


            //3.获取数据库操作对象(专门执行sql语句的对象)
            //一个问号表示一个占位符
 //改
            String sql2 = "update t_act set balance= ? where actno=?";
            ps = conn.prepareStatement(sql2);
//          给占位符传值
            ps.setDouble(1,1000);
            ps.setInt(2,1);

            int count = ps.executeUpdate();

            //插入空指针异常,来中断代码,测试是否关闭自动提交!!!!!!
            String str = null;
            str.toString();



//          再给占位符传值
            ps.setDouble(1,999);
            ps.setInt(2,2);
            count += ps.executeUpdate();

            System.out.println(count==2?"转账成功":"转账失败");

//查
            String sql4 = " select * from t_act";
            ps = conn.prepareStatement(sql4);
//          给占位符传值
            //程序执行到此,会发送sql语句”框子“给DBMS,然后它进行‘预编译

            conn.commit(); //提交代码

            //4.执行sql语句(主要执行DQL、DML……)
            rs = ps.executeQuery(); //专门执行DQL查询语句
            //5.处理查询结果集(只有当第4步执行的是select语句时,才有这第5步)
            boolean flag = false;
            flag = rs.next();
            while (flag){
                //列表标签
                String actno = rs.getString("actno");
                String balance = rs.getString("balance");


                System.out.println(actno+","+balance);
                flag = rs.next();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //6.释放资源(使用完资源后一定要关闭资源,java和数据库属于进程间通信,开启后一定要关闭)

            try {
                if (ps != null)
                    ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (conn != null)
                    conn.rollback();
//                    conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

        }

    }
}

1.4.关闭自动提交:

原账户:
在这里插入图片描述

执行结果:(正确)
在这里插入图片描述

public class JdbcAutoCommit {
    public static void main(String[] args) {

        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            //1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接(表示JVM的进程和数据库进程之间的  通道 打开了,使用完之后  必须关闭)
            String url = "jdbc:mysql://localhost:3306/bjpowernode"; //自己的地址链接
            String user = "root";
            String password = "333";
            conn = DriverManager.getConnection(url,user,password);


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


            //3.获取数据库操作对象(专门执行sql语句的对象)
            //一个问号表示一个占位符
 //改
            String sql2 = "update t_act set balance= ? where actno=?";
            ps = conn.prepareStatement(sql2);
//          给占位符传值
            ps.setDouble(1,1000);
            ps.setInt(2,1);

            int count = ps.executeUpdate();

            //插入空指针异常,来中断代码,测试是否关闭自动提交!!!!!!
//            String str = null;
//            str.toString();



//          再给占位符传值
            ps.setDouble(1,999);
            ps.setInt(2,2);
            count += ps.executeUpdate();

            System.out.println(count==2?"转账成功":"转账失败");

//查
            String sql4 = " select * from t_act";
            ps = conn.prepareStatement(sql4);
//          给占位符传值
            //程序执行到此,会发送sql语句”框子“给DBMS,然后它进行‘预编译

            conn.commit(); //提交代码

            //4.执行sql语句(主要执行DQL、DML……)
            rs = ps.executeQuery(); //专门执行DQL查询语句
            //5.处理查询结果集(只有当第4步执行的是select语句时,才有这第5步)
            boolean flag = false;
            flag = rs.next();
            while (flag){
                //列表标签
                String actno = rs.getString("actno");
                String balance = rs.getString("balance");


                System.out.println(actno+","+balance);
                flag = rs.next();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //6.释放资源(使用完资源后一定要关闭资源,java和数据库属于进程间通信,开启后一定要关闭)

            try {
                if (ps != null)
                    ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (conn != null)
                    conn.rollback();
//                    conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

        }

    }
}

2.工具类封装(演示模糊查询)

把JDBC的第1、2、6步封装

  • 1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
  • 2.获取连接(表示JVM的进程和数据库进程之间的 通道 打开了,使用完之后 必须关闭)
  • 6.释放资源(使用完资源后一定要关闭资源,java和数据库属于进程间通信,开启后一定要关闭)
2.1. 封装部分
import java.sql.*;
/**
 * 简化JDBC编程
 */

public class DBUtils {
    /**
     * 工具类中的构造方法都是私有的
     * 因为工具类中的方法都是静态的,不用new对象
     */
    private DBUtils(){}
    /**
     * 静态代码块,只在类加载的时候执行1次
     * 驱动只注册1次就行了
     */
    static {
        //1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 封装JDBC的连接部分
     * @return
     * @throws Exception
     */
    public static Connection getConnection() throws Exception {
        //2.获取连接(表示JVM的进程和数据库进程之间的  通道 打开了,使用完之后  必须关闭)
        String url = "jdbc:mysql://localhost:3306/bjpowernode"; //自己的地址链接
        String user = "root";
        String password = "333";
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 封装JDBC的close部分
     * @param connection
     * @param ps
     * @param resultSet
     */
    public  static void close(Connection connection, Statement ps, ResultSet resultSet){

        try{
            if(ps != null){
                ps.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }

        try{
            if(connection != null){
                connection.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        try{
            if(resultSet != null){
                resultSet.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
2.2.模糊查询——调用部分
  • 查找emp表内,ename含有字母A的
    执行结果:
    在这里插入图片描述
    明显可见,代码量少很多。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


/**
 * 模糊查询
 *    查找emp表内,ename含有字母A的
 */

public class JDBCFuzzyQuery {
    public static void main(String[] args) {

        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtils.getConnection();

            //3.获取数据库操作对象(专门执行sql语句的对象)
            //一个问号表示一个占位符
            String sql = "select ename from emp where ename like ?";
            ps = conn.prepareStatement(sql);
//          给占位符传值
            ps.setString(1,"%A%");

            //4.执行sql语句(主要执行DQL、DML……)
            rs = ps.executeQuery(); //专门执行DQL查询语句

            while (rs.next()){
                String ename = rs.getString("ename");
                System.out.println(ename);
                rs.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtils.close(conn,ps,rs);
        }


    }
}

3.悲观锁、乐观锁

在这里插入图片描述

演示行级锁,需要用到两个程序

程序1:查询输出job是manager的员工
  •   //                                                        for update    加上悲观锁
          String sql = " select ename,job,sal from emp where job=?  for update";
    
  • 说明:如果给程序1在commit或之前,加上断点
    那程序2会卡住,必须等待程序1执行完才能继续执行
    在这里插入图片描述

import java.sql.*;
/**
 * 演示乐观锁、悲观锁
 */
public class JDBCLock01 {
    public static void main(String[] args) {
        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try{
            //1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接(表示JVM的进程和数据库进程之间的  通道 打开了,使用完之后  必须关闭)
            String url = "jdbc:mysql://localhost:3306/bjpowernode"; //自己的地址链接
            String user = "root";
            String password = "333";
            conn = DriverManager.getConnection(url,user,password);
            conn.setAutoCommit(false);//关闭自动提交

            //3.获取数据库操作对象(专门执行sql语句的对象)
            //一个问号表示一个占位符
            //                                                        for update    加上悲观锁
            String sql = " select ename,job,sal from emp where job=?  for update";
            ps = conn.prepareStatement(sql);
//          给占位符传值
            ps.setString(1,"MANAGER");
            //程序执行到此,会发送sql语句”框子“给DBMS,然后它进行‘预编译

            //4.执行sql语句(主要执行DQL、DML……)
            rs = ps.executeQuery(); //专门执行DQL查询语句
            //5.处理查询结果集(只有当第4步执行的是select语句时,才有这第5步)
            while (rs.next()){
                //列表标签
                String ename = rs.getString("ename");
                String job = rs.getString("job");
                String sal = rs.getString("sal");
                System.out.println(ename+","+job+","+sal);
//                rs.next();
            }

            conn.commit();


        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (ps != null)
                    ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (conn != null)
                    conn.rollback();
//                    conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (rs != null)
                    rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

程序2:为job是manager的每个人加薪10%
  •    String sql = "update emp set sal=sal*1.1 where job=manager";
    
import java.sql.*;

/**
 * 演示乐观锁、悲观锁
 */


public class JDBCLock02 {
    public static void main(String[] args) {

        //JDBC代码
        Connection conn = null;
        PreparedStatement ps = null;


        try{
            //1.注册驱动(作用:告诉java程序,即将要连接哪个品牌的数据库)
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接(表示JVM的进程和数据库进程之间的  通道 打开了,使用完之后  必须关闭)
            String url = "jdbc:mysql://localhost:3306/bjpowernode"; //自己的地址链接
            String user = "root";
            String password = "333";
            conn = DriverManager.getConnection(url,user,password);
            conn.setAutoCommit(false);//关闭自动提交

            //3.获取数据库操作对象(专门执行sql语句的对象)
            //一个问号表示一个占位符
            String sql = "update emp set sal=sal*1.1 where job=? ";
//            String sql = " select ename,job,sal from emp where job=?  for update";
            ps = conn.prepareStatement(sql);
//          给占位符传值
            ps.setString(1,"MANAGER");
            int count = ps.executeUpdate();
            System.out.println(count==3?"运行成功":"运行失败");
            //程序执行到此,会发送sql语句”框子“给DBMS,然后它进行‘预编译

            conn.commit();


        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (ps != null)
                    ps.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            try {
                if (conn != null)
                    conn.rollback();
//                    conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值