JDBC快速入门

一、JDBC快速入门:

1.1 概念:

Java DataBase Connectivity = Java 数据库连接。Java 语言操作数据库

1.2 JDBC本质:

其实是官方定义的一套操作所有关系型数据库的规则,各个数据库厂商去实现这套接口,提供数据库驱动 jar 包。
我们可以使用这套接口(JDBC)编程,真正执行的代码时驱动 jar 包中的实现类。

1.3 快速入门:

步骤:
    1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
                1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
                2.右键-->Add As Library
    2. 注册驱动
    3. 获取数据库连接对象 Connection
    4. 定义sql
    5. 获取执行sql语句的对象 Statement
    6. 执行sql,接受返回结果
    7. 处理结果
    8. 释放资源

<补充注意:版本问题>

①jdbc在连接mysql6以下的版本时 :

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=

②jdbc在连接mysql6及以上的版本时 :

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=

在设定时区的时候,如果设定serverTimezone=UTC,会比中国时间早8个小时,如果在中国,可以选择Asia/Shanghai或者Asia/Hongkong

代码实现:
        //1.导入驱动jar包

        //2.注册驱动 - 加载入内存
        //在jar包下 - META-INF - services - java.sql.Driver
        Class.forName("com.mysql.jdbc.Driver");

        //3.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "2020");

        //4.定义sql语句
        String sql = "update account set balance = 500 where id = 1";

        //5.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();

        //6.执行sql
        int count = stmt.executeUpdate(sql);

        //7.处理结果
        System.out.println(count);

        //8.释放资源
        stmt.close();
        conn.close();

二、对JDBC各个接口和类详解:

2.1 DriverManager : 驱动管理对象

* 功能:
    1. 注册驱动:告诉程序该使用哪一个数据库驱动 jar
       static void registerDriver(Driver driver) : 注册与给定的驱动程序 DriverManager 。 
       写代码使用:  Class.forName("com.mysql.jdbc.Driver");
       通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
            static {
                try {
                   java.sql.DriverManager.registerDriver(new Driver());
                    } catch (SQLException E) {
                      throw new RuntimeException("Can't register driver!");
                     }
                }

        注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。

    2. 获取数据库连接:
        * 方法:static Connection getConnection(String url, String user, String password) 
        * 参数:
          url:指定连接的路径
          语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
          例子:jdbc:mysql://localhost:3306/db3
          细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称

          user:用户名
          password:密码 

2.2 Connection : 数据库连接对象

功能:
  1. 获取执行sql 的对象
    * Statement createStatement()
    * PreparedStatement prepareStatement(String sql)  

  2. 管理事务:
    * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
    * 提交事务:commit() 
    * 回滚事务:rollback() 

2.3 Statement : 执行 sql 的对象

            1. 执行sql
                1. boolean execute(String sql) :可以执行任意的sql 了解 
                2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
                    * 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
                3. ResultSet executeQuery(String sql)  :执行DQL(select)语句
            2. 练习:
                1. account表 添加一条记录
                2. account表 修改记录
                3. account表 删除一条记录
添加一条记录操作,代码:

        Statement stmt = null;
        Connection conn = null;
        try {
            //1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2. 定义sql
            String sql = "insert into account values(null,'王五',3000)";
            //3.获取Connection对象
            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
            //4.获取执行sql的对象 Statement
            stmt = conn.createStatement();
            //5.执行sql
            int count = stmt.executeUpdate(sql);//影响的行数
            //6.处理结果
            System.out.println(count);
            if(count > 0){
                System.out.println("添加成功!");
            }else{
                System.out.println("添加失败!");
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //stmt.close();
            //7. 释放资源
            //避免空指针异常
            if(stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
修改一条记录操作,代码:

        Connection conn = null;
        Statement stmt = null;
        try {
            //1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接对象
            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
            //3.定义sql
            String sql  = "update account set balance = 1500 where id = 3";
            //4.获取执行sql对象
            stmt = conn.createStatement();
            //5.执行sql
            int count = stmt.executeUpdate(sql);
            //6.处理结果
            System.out.println(count);
            if(count > 0){
                System.out.println("修改成功!");
            }else{
                System.out.println("修改失败");
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //7.释放资源

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

            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
删除一条记录操作,代码:

        Connection conn = null;
        Statement stmt = null;
        try {
            //1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接对象
            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");
            //conn = JDBCUtils.getConnection("jdbc:mysql:///db3", "root", "root");
            //3.定义sql
            String sql  = "delete from account where id = 3";
            //4.获取执行sql对象
            stmt = conn.createStatement();
            //5.执行sql
            int count = stmt.executeUpdate(sql);
            //6.处理结果
            System.out.println(count);
            if(count > 0){
                System.out.println("删除成功!");
            }else{
                System.out.println("删除失败");
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //7.释放资源

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

            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
执行DDL语句,创建表:        Connection conn = null;        Statement stmt = null;        try {            //1. 注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接对象            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");            //3.定义sql            String sql  = "create table student (id int , name varchar(20))";            //4.获取执行sql对象            stmt = conn.createStatement();            //5.执行sql            int count = stmt.executeUpdate(sql);            //6.处理结果            System.out.println(count);        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        } finally {            //7.释放资源            if(stmt != null){                try {                    stmt.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(conn != null){                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }

2.4 ResultSet : 结果集对象,封装查询结果

    * boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true    * getXxx(参数):获取数据                * Xxx:代表数据类型   如: int getInt() ,    String getString()                * 参数:                    1. int:代表列的编号,从1开始   如: getString(1)                    2. String:代表列名称。 如: getDouble("balance")                        * 注意:                * 使用步骤:                    1. 游标向下移动一行                    2. 判断是否有数据                    3. 获取数据  使用 Java 代码获取数据库表中的数据,并输出到控制台:  代码:        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;        try {            //1. 注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接对象            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");            //3.定义sql            String sql  = "select * from account";            //4.获取执行sql对象            stmt = conn.createStatement();            //5.执行sql            rs = stmt.executeQuery(sql);            //6.处理结果            //6.1 让游标向下移动一行            rs.next();            //6.2 获取数据            int id = rs.getInt(1);            String name = rs.getString("name");            double balance = rs.getDouble(3);            System.out.println(id + "---" + name + "---" + balance);            //6.1 让游标向下移动一行            rs.next();            //6.2 获取数据            int id2 = rs.getInt(1);            String name2 = rs.getString("name");            double balance2 = rs.getDouble(3);            System.out.println(id2 + "---" + name2 + "---" + balance2);            //6.1 让游标向下移动一行            rs.next();            //6.2 获取数据            int id3 = rs.getInt(1);            String name3 = rs.getString("name");            double balance3 = rs.getDouble(3);            System.out.println(id3 + "---" + name3 + "---" + balance3);        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        } finally {            //7.释放资源            if(rs != null){                try {                    rs.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(stmt != null){                try {                    stmt.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(conn != null){                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }
上一个代码的升级版,使用 while 循环获取表中的数据:    代码:        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;        try {            //1. 注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接对象            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");            //3.定义sql            String sql  = "select * from account";            //4.获取执行sql对象            stmt = conn.createStatement();            //5.执行sql            rs = stmt.executeQuery(sql);            //6.处理结果            //循环判断游标是否是最后一行末尾。            while(rs.next()){                //获取数据                //6.2 获取数据                int id = rs.getInt(1);                String name = rs.getString("name");                double balance = rs.getDouble(3);                System.out.println(id + "---" + name + "---" + balance);            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        } finally {            //7.释放资源            if(rs != null){                try {                    rs.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(stmt != null){                try {                    stmt.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(conn != null){                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }
  • 使用 Select 语句,把数据库表中的数据全部抓取出来,封装成集合对象,输出到控制台
  • emp 代码:
package cn.itcast.domain;import java.util.Date;/** * @author czh * @create 2020-05-20-20:48 */public class Emp {    private int id;    private String ename;    private int job_id;    private int mgr;    private Date joindate;    private double salary;    private double bonus;    private int dept_id;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getEname() {        return ename;    }    public void setEname(String ename) {        this.ename = ename;    }    public int getJob_id() {        return job_id;    }    public void setJob_id(int job_id) {        this.job_id = job_id;    }    public int getMgr() {        return mgr;    }    public void setMgr(int mgr) {        this.mgr = mgr;    }    public Date getJoindate() {        return joindate;    }    public void setJoindate(Date joindate) {        this.joindate = joindate;    }    public double getSalary() {        return salary;    }    public void setSalary(double salary) {        this.salary = salary;    }    public double getBonus() {        return bonus;    }    public void setBonus(double bonus) {        this.bonus = bonus;    }    public int getDept_id() {        return dept_id;    }    public void setDept_id(int dept_id) {        this.dept_id = dept_id;    }    @Override    public String toString() {        return "emp{" +                "id=" + id +                ", ename='" + ename + '\'' +                ", job_id=" + job_id +                ", mgr=" + mgr +                ", joindate=" + joindate +                ", salary=" + salary +                ", bonus=" + bonus +                ", dept_id=" + dept_id +                '}' + "\n";    }}
  • JDBCDemo8代码:
package cn.itcast.jdbc;import cn.itcast.domain.Emp;import java.sql.*;import java.util.ArrayList;import java.util.List;/** * @author czh * @create 2020-05-20-20:52 */public class JDBCDemo8 {    public static void main(String[] args) {        List<Emp> list = new JDBCDemo8().findAll();        System.out.println(list);        System.out.println(list.size());    }    /**     * 查询所有emp对象     */    public List<Emp> findAll(){        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;        List<Emp> list = null;        try {            //1.注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接            conn = DriverManager.getConnection("jdbc:mysql:///db4","root","2020");            //3.定义sql            String sql = "select * from emp";            //4.获取执行sql的对象            stmt = conn.createStatement();            //5.执行sql            rs = stmt.executeQuery(sql);            //6.遍历结果集,封装对象,转载集合            Emp emp = null;            list = new ArrayList<Emp>();            while (rs.next()){                //获取数据                int id = rs.getInt("id");                String ename = rs.getString("ename");                int job_id = rs.getInt("job_id");                int mgr = rs.getInt("mgr");                Date joindate = rs.getDate("joindate");                double salary = rs.getDouble("salary");                double bonus = rs.getDouble("bonus");                int dept_id = rs.getInt("dept_id");                //创建emp对象并赋值                emp = new Emp();                emp.setId(id);                emp.setEname(ename);                emp.setJob_id(job_id);                emp.setMgr(mgr);                emp.setJoindate(joindate);                emp.setSalary(salary);                emp.setBonus(bonus);                emp.setDept_id(dept_id);                //装载集合                list.add(emp);            }        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        }finally {            if (rs != null){                try {                    rs.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (stmt != null){                try {                    stmt.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if (conn != null){                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }        }        return list;    }}

2.5 JDBC 工具类

* 目的:简化书写    * 分析:        1. 注册驱动也抽取        2. 抽取一个方法获取连接对象            * 需求:不想传递参数(麻烦),还得保证工具类的通用性。            * 解决:配置文件                jdbc.properties                    url=                    user=                    password=        3. 抽取一个方法释放资源
代码实现:
package cn.itcast.util;import java.io.FileReader;import java.io.IOException;import java.net.URL;import java.sql.*;import java.util.Properties;/** * JDBC工具类 */public class JDBCUtils {    private static String url;    private static String user;    private static String password;    private static String driver;    /**     * 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块     */    static{        //读取资源文件,获取值。        try {            //1. 创建Properties集合类。            Properties pro = new Properties();            //获取src路径下的文件的方式--->ClassLoader 类加载器            ClassLoader classLoader = JDBCUtils.class.getClassLoader();            URL res  = classLoader.getResource("jdbc.properties");            String path = res.getPath();           // System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties            //2. 加载文件           // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));            pro.load(new FileReader(path));            //3. 获取数据,赋值            url = pro.getProperty("url");            user = pro.getProperty("user");            password = pro.getProperty("password");            driver = pro.getProperty("driver");            //4. 注册驱动            Class.forName(driver);        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    /**     * 获取连接     * @return 连接对象     */    public static Connection getConnection() throws SQLException {        return DriverManager.getConnection(url, user, password);    }    /**     * 释放资源     * @param stmt     * @param conn     */    public static void close(Statement stmt,Connection conn){        if( stmt != null){            try {                stmt.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if( conn != null){            try {                conn.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }    /**     * 释放资源     * @param stmt     * @param conn     */    public static void close(ResultSet rs,Statement stmt, Connection conn){        if( rs != null){            try {                rs.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if( stmt != null){            try {                stmt.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if( conn != null){            try {                conn.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}
/**     * 演示JDBC工具类     * @return     */    public static void main(String[] args) {        List<Emp> list = new JDBCDemo8().findAll2();        System.out.println(list);        System.out.println(list.size());    }    public List<Emp> findAll2(){        Connection conn = null;        Statement stmt = null;        ResultSet rs = null;        List<Emp> list = null;        try {           /* //1.注册驱动            Class.forName("com.mysql.jdbc.Driver");            //2.获取连接            conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");*/            conn = JDBCUtils.getConnection();            //3.定义sql            String sql = "select * from emp";            //4.获取执行sql的对象            stmt = conn.createStatement();            //5.执行sql            rs = stmt.executeQuery(sql);            //6.遍历结果集,封装对象,装载集合            Emp emp = null;            list = new ArrayList<Emp>();            while(rs.next()){                //获取数据                int id = rs.getInt("id");                String ename = rs.getString("ename");                int job_id = rs.getInt("job_id");                int mgr = rs.getInt("mgr");                Date joindate = rs.getDate("joindate");                double salary = rs.getDouble("salary");                double bonus = rs.getDouble("bonus");                int dept_id = rs.getInt("dept_id");                // 创建emp对象,并赋值                emp = new Emp();                emp.setId(id);                emp.setEname(ename);                emp.setJob_id(job_id);                emp.setMgr(mgr);                emp.setJoindate(joindate);                emp.setSalary(salary);                emp.setBonus(bonus);                emp.setDept_id(dept_id);                //装载集合                list.add(emp);            }        } catch (SQLException e) {            e.printStackTrace();        }finally {            /*if(rs != null){                try {                    rs.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(stmt != null){                try {                    stmt.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }            if(conn != null){                try {                    conn.close();                } catch (SQLException e) {                    e.printStackTrace();                }            }*/            JDBCUtils.close(rs,stmt,conn);        }        return list;    }

配置文件:

url=jdbc:mysql:///db3user=rootpassword=rootdriver=com.mysql.jdbc.Driver

2.6 JDBC 练习:登录案例

第一个版本:会被sql注入强行登录
/** * 练习: *      * 需求: *          1. 通过键盘录入用户名和密码 *          2. 判断用户是否登录成功 */public class JDBCDemo9 {    public static void main(String[] args) {        //1.键盘录入,接受用户名和密码        Scanner sc = new Scanner(System.in);        System.out.println("请输入用户名:");        String username = sc.nextLine();        System.out.println("请输入密码:");        String password = sc.nextLine();        //2.调用方法        boolean flag = new JDBCDemo9().login2(username, password);        //3.判断结果,输出不同语句        if(flag){            //登录成功            System.out.println("登录成功!");        }else{            System.out.println("用户名或密码错误!");        }    }    /**     * 登录方法     */    public boolean login(String username ,String password){        if(username == null || password == null){            return false;        }        //连接数据库判断是否登录成功        Connection conn = null;        Statement stmt =  null;        ResultSet rs = null;        //1.获取连接        try {            conn =  JDBCUtils.getConnection();            //2.定义sql            String sql = "select * from user where username = '"+username+"' and password = '"+password+"' ";            System.out.println(sql);            //3.获取执行sql的对象            stmt = conn.createStatement();            //4.执行查询            rs = stmt.executeQuery(sql);            //5.判断           /* if(rs.next()){//如果有下一行,则返回true                return true;            }else{                return false;            }*/           return rs.next();//如果有下一行,则返回true        } catch (SQLException e) {            e.printStackTrace();        }finally {            JDBCUtils.close(rs,stmt,conn);        }        return false;    }

2.7 PreparedStatement : 执行 sql 的对象

            1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题                  1. 输入用户随便,输入密码:a' or 'a' = 'a                  2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'             2. 解决sql注入问题:使用PreparedStatement对象来解决            3. 预编译的SQL:参数使用?作为占位符            4. 步骤:                  1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar                  2. 注册驱动                  3. 获取数据库连接对象 Connection                  4. 定义sql                      * 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;                  5. 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql)                   6. 给?赋值:                      * 方法: setXxx(参数1,参数2)                          * 参数1:?的位置编号 从1 开始                          * 参数2:?的值                  7. 执行sql,接受返回结果,不需要传递sql语句                  8. 处理结果                  9. 释放资源            5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作                  1. 可以防止SQL注入                  2. 效率更高
代码演示:
/**     * 登录方法,使用PreparedStatement实现     */    public boolean login2(String username ,String password){        if(username == null || password == null){            return false;        }        //连接数据库判断是否登录成功        Connection conn = null;        PreparedStatement pstmt =  null;        ResultSet rs = null;        //1.获取连接        try {            conn =  JDBCUtils.getConnection();            //2.定义sql            String sql = "select * from user where username = ? and password = ?";            //3.获取执行sql的对象            pstmt = conn.prepareStatement(sql);            //给?赋值            pstmt.setString(1,username);            pstmt.setString(2,password);            //4.执行查询,不需要传递sql            rs = pstmt.executeQuery();            //5.判断           /* if(rs.next()){//如果有下一行,则返回true                return true;            }else{                return false;            }*/            return rs.next();//如果有下一行,则返回true        } catch (SQLException e) {            e.printStackTrace();        }finally {            JDBCUtils.close(rs,pstmt,conn);        }        return false;    }

三、JDBC 控制事务:

    1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。    2. 操作:        1. 开启事务        2. 提交事务        3. 回滚事务    3. 使用Connection对象来管理事务        * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务            * 在执行sql之前开启事务        * 提交事务:commit()             * 当所有sql都执行完提交事务        * 回滚事务:rollback()             * 在catch中回滚事务
代码:
        Connection conn = null;        PreparedStatement pstmt1 = null;        PreparedStatement pstmt2 = null;        try {            //1.获取连接            conn = JDBCUtils.getConnection();            //开启事务            conn.setAutoCommit(false);            //2.定义sql            //2.1 张三 - 500            String sql1 = "update account set balance = balance - ? where id = ?";            //2.2 李四 + 500            String sql2 = "update account set balance = balance + ? where id = ?";            //3.获取执行sql对象            pstmt1 = conn.prepareStatement(sql1);            pstmt2 = conn.prepareStatement(sql2);            //4. 设置参数            pstmt1.setDouble(1,500);            pstmt1.setInt(2,1);            pstmt2.setDouble(1,500);            pstmt2.setInt(2,2);            //5.执行sql            pstmt1.executeUpdate();            // 手动制造异常            int i = 3/0;            pstmt2.executeUpdate();            //提交事务            conn.commit();        } catch (Exception e) {            //事务回滚            try {                if(conn != null) {                    conn.rollback();                }            } catch (SQLException e1) {                e1.printStackTrace();            }            e.printStackTrace();        }finally {            JDBCUtils.close(pstmt1,conn);            JDBCUtils.close(pstmt2,null);        }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容