JDBC技术(三)

JDBC 2020-03-06 105 次浏览 本文字数:4268字

本文主要内容:JDBC实现数据库的增删改查操作---Version2.0(事务版)

一、 数据库事务简要说明

  1. 什么叫数据库事务?

    事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态
               > 一组逻辑操作单元:一个或多个DML语句
    
  2. 事务处理的原则:保证所有的事务都作为一个工作单元来执行,即使处理故障,都不能改变这种方式,要么所有的事务都被提交(commit),这些修改就会永久的保存;要么就整个事务回滚(rollback)到最初状态
  3. 数据一旦提交,就不可回滚
  4. 哪些操作会导致数据的自动提交?

     > DDL操作一旦执行,都会自动提交
         > set autocommit = false对DDL失效
     > DML默认会自动提交
         > 我们可以通过set autocommit = false的方式取消自动提交
    > 关闭数据库链接库时也会自动提交
    

二、获取数据库连接与关闭的通用方法 2.0版

//通用的增删改操作---version 2.0 开启事务版
    public int update(Connection conn, String sql, Object...args){     
        PreparedStatement ps = null;
        try {
            //1. 预编译sql语句,返回PrepareStatement实例
            ps = conn.prepareStatement(sql);

            //2. 填充占位符
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);  
            }

            //3.执行
            return ps.executeUpdate();  
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4. 资源关闭
            JDBCUtils.closeResource(null, ps);
        }
        return 0;
    }

    /**
     * 转账功能测试
     */
    @Test
    public void testUpdate() {
        Connection coon = null;
        try {
            coon = JDBCUtils.getConnection();
            //取消数据的自动提交(必须执行此步)否则DML语句默认自动提交
            coon.setAutoCommit(false);

            String sql1 = "update account set money = money - 100 where name = ?";
            update(coon, sql1, "MT");

            //模拟转账异常情况,开启事务只会可以让数据回滚,防止钱不翼而飞的情况
            System.out.println(10 / 0);

            String sql2 = "update account set money = money + 100 where name = ?";
            update(coon, sql2, "F6");

            System.out.println("转账成功");

            //2. 数据提交
            coon.commit();
        } catch (Exception e) {
            System.out.println("转账失败");
            try {
                if (coon != null) {
                    coon.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            //修改commit为自动提交, 主要应用于数据库连接池
            try {
                if (coon != null) {
                    coon.setAutoCommit(true);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            JDBCUtils.closeResource(coon, null);
        }
    }

二、数据库表中查的通用方法 2.0版

//通用的查询操作---version 2.0 开启事务版
    public <T> List<T> MultiplyQuery(Connection coon, Class<T> clazz, String sql, Object...args){
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = coon.prepareStatement(sql);
            //填充占位符
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            rs = ps.executeQuery();
            //获取结果的元数据:ResultSetMetaData
            ResultSetMetaData rsm = rs.getMetaData();
            //通过ResultSetMetaData获取结果集的列数
            int columnCount = rsm.getColumnCount();
            //创建集合对象
            ArrayList<T> list = new ArrayList<>();
            while (rs.next()) {
                T t = clazz.getDeclaredConstructor().newInstance();
                //处理结果集一行数据的每一个列
                for (int i = 0; i < columnCount; i++) {
                    //获取列值
                    Object columnValue = rs.getObject(i + 1);

                    //getColumnLabel():在sql有别名的情况下,可以获得别名,无别名的情况下,可以获得原列名
                    String columnLabel = rsm.getColumnLabel(i + 1);

                    //给stu对象指定的columnLabel属性,赋值为columnValue:通过反射
                    Field field = clazz.getDeclaredField(columnLabel);
                    field.setAccessible(true);
                    field.set(t, columnValue);
                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(null, ps, rs);
        }
        return null;
    }

本文由 WarlockMarten 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。