六、JDBC--获取自动生成的主键值&处理Blob&数据库事务处理

【孤立的技术是没有价值的】,我们这里只是为了了解具体的实现步骤:我们在插入数据的时候,经常会需要获取我们插入的这一行数据对应的主键值。

具体的代码实现:

/**
     * 获取数据库自动生成的主键
     */
    @Test
    public void testGetKeyValues(){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet rs=null;
        try {
            connection=JDBCTools.getConnection();
            String sql="insert into customers(name,email,birth)"+
            " values(?,?,?)";
//            preparedStatement=connection.prepareStatement(sql);
            //我们这里使用重载的prepareStatement(sql,flag)方法
            //来生成prepareStatement对象
            preparedStatement=connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            preparedStatement.setString(1, "ABCDE");
            preparedStatement.setString(2, "[email protected]");
            preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));
            preparedStatement.executeUpdate();
            //通过getGeneratedKeys方法获取包含了新生成的主键的ResultSet对象
            //在ResultSet结果集中,只包含一列,列名:GENERATED_KEY,用于存放新生成的主键值
            rs=preparedStatement.getGeneratedKeys();
            if(rs.next()){
                System.out.println(rs.getObject(1));
            } 
            ResultSetMetaData rsmd=rs.getMetaData();
            for(int i=0;i<rsmd.getColumnCount();i++){
                System.out.println(rsmd.getColumnName(i+1));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            JDBCTools.release(rs,preparedStatement,connection);
        }
    }

处理Blob

Blob的基本概念

1).插入Blob类型数据

/**
     * 插入Blob类型的数据必须使用PreparedStatement
     * 因为Blob类型的数据是无法使用字符串拼写的
     * 
     * 调用setBlob(int index,InputStream inputStream)
     */
@Test
    public void testInsertBlod(){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet rs=null;
        try {
            connection=JDBCTools.getConnection();
            String sql="insert into customers(name,email,birth,picture)"+
            " values(?,?,?,?)";
//            preparedStatement=connection.prepareStatement(sql);
            //我们这里使用重载的prepareStatement(sql,flag)方法
            //来生成prepareStatement对象
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1, "ABCDE");
            preparedStatement.setString(2, "[email protected]");
            preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));
            InputStream inputStream=new FileInputStream("blob.png");
            preparedStatement.setObject(4, inputStream);
            preparedStatement.executeUpdate();
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            JDBCTools.release(rs,preparedStatement,connection);
        }
    }

2).读取Blob类型数据 

/**
     * 读取Blob数据:
     * 1.使用getBlob方法,读取Blod对象
     * 2.调用Blob的getBinaryStream()方法得到输入流,再使用IO操作即可
     */
@Test
    public void testReadBlob(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JDBCTools.getConnection();
            String sql = "select id,name,email,birth,picture"+
            " from customers where id =18";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                int id=resultSet.getInt(1);
                String name=resultSet.getString(2);
                String email=resultSet.getString(3);
                System.out.println(id+":"+name+":"+email);
                Blob pictureBlob=resultSet.getBlob(5);
                InputStream inputStream=pictureBlob.getBinaryStream();
                OutputStream out=new FileOutputStream("flo.png");
                byte[] buffer=new byte[1024];
                int len =0;
                while((len=inputStream.read(buffer))!=-1){
                    out.write(buffer,0,len);
                }
                out.close();
                inputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(resultSet, preparedStatement, connection);
        }
    }

数据库事务

数据库事务概述

数据库事务的四个属性

JDBC的数据库事务

我们做一个小实验:

先建立一个数据表:

试验中要用到的更新数据的通用方法update():要保证两次操作用一个connection连接,否则就不能被称为一次事务了。

public static void update(Connection connection,String sql,
            Object ...args){
            /**
             * 执行SQL语句,使用PreparedStatement
             */
            PreparedStatement preparedStatement=null;
            try {
                preparedStatement=connection.prepareStatement(sql);
                for(int i=0;i<args.length;i++){
                    preparedStatement.setObject(i+1, args[i]);
                }
                preparedStatement.executeUpdate();
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                JDBCTools.release(null, preparedStatement, null);
    }

我们要完成的是:Tom->Jerry汇款500元
  * 数据库事务
  * 关于事务:
  * 1.如果多个操作,每个操作使用的是自己的单独的连接,则无法保证事务
  * 2.具体步骤:
  * 1).开始事务,取消默认自动提交行为
  * 2).如果事务的操作都成功,则提交事务:connection.commit();
  * 3).回滚事务:若出现异常,则在catch块中回滚事务

我们组织代码就按照上面的步骤来进行.

public void testTeansaction() throws Exception{
        Connection connection=null;
        try {
            connection=JDBCTools.getConnection();
            System.out.println(connection.getAutoCommit());
            String sql="update users set balance=balance-500 where id=1";
            //开始事务:取消默认提交
            connection.setAutoCommit(false);
            update(connection,sql);
            int i=10/0;
            System.out.println(i);
            sql="update users set balance=balance+500 where id=2";
            JDBCTools.update(sql);
            //提交事务
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            //关闭连接
            JDBCTools.release(null, null, connection);
        }
    }

可以发现,因为我们使用的是同一个connection连接,当异常(除数为0)发生的时候,事务会发生回滚,数据库的数据会恢复到事务开始之前的状态.

猜你喜欢

转载自blog.csdn.net/m2606707610/article/details/83589886
今日推荐