MySQL数据库JDBC2.0操作

来源:互联网 发布:linux查看hba驱动版本 编辑:程序博客网 时间:2024/05/22 04:59

数据库最基本的操作为一般的JDBC操作,在JDBC2.0后为了方便数据库的开发,加入了很多方便的操作,包括可滚动的数据集和使用数据集对数据进行增删改查.

如果要使用这些新特性,就必须依靠ResultSet,以下是其新特性

这里写图片描述

常量大致分为两部分,
(1)设置ResultSet类型:TTYPE_XXXX设置的都是类型,表示其是 否可以滚动以及是否可以修改数据表的内容
(2)设置并发性:CONCUR_XXXX设置的都是并发性,并发性主要表示结果集是否是只读,还是可以进行数据库更新操作

A 首先,可滚动的数据集
之前的ResultSet在取出数据时,数据都是右前向后顺序输出,如果想要获取数据集任意位置的数据,就必须使用滚动数据集.
只是在创建preparedstatement对象时,加入参数即可,如

    String sql = "insert into tb_user (username,password) values (?,?)";    preparedStatement = connection.prepareStatement (sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

随后使用ResultSet的方法,将指针移向不同数据行,在对其进行操作即可,即可以输出指定的行,也可以跳转到开头和结尾.

B 其次,使用结果集操作数据
(1)使用结果集插入数据
在插入数据之前,将指针移向可以插入的位置:rs.moveToInsertRow();
使用rs.updateXXXX()插入数据
最后使用rs.insertRow()即可

            rs = preparedStatement.executeQuery();            rs.moveToInsertRow();            rs.updateString("username", "user");            rs.updateString("password", "password");            rs.insertRow();

(2)使用结果集更新数据
使用结果集的指针移动方法,将指针移向想要更新的数据行(可以先查询该行数据,存储到rs,再使用rs.last()将指针跳转到该行)
使用rs.updateXXXX()方法进行更新数据
最后使用rs.updateRow()即可

            String sql = "select username,password from tb_user where username = ?";            preparedStatement = connection.prepareStatement (sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);            preparedStatement.setInt(1,"user");            rs = preparedStatement.executeQuery();            rs.last();            rs.updateString("username", "user-1");            rs.updateString("password", "password-1");            rs.updateRow();

另外,在执行rs.updateRow()之前,如果发现数据库更新有错误,则可以使用cancelRowUpdates()方法取消之前的更新,这样就算 执行了rs.updateRow()方法,也不会更新数据库,但是一定要基记住,必须在rs.updateRow()之前使用cancelRowUpdates()方法

            rs.cancelRowUpdates();            rs.updateRow();

(3)使用结果集删除数据
与之前一样,只不过删除数据使用的是deleteRow()

            rs.last();            rs.deleteRow();

C 批处理操作
批处理操作可以一次性执行多条SQL语句,只需使用addBatch()加入要执行的一条SQL命令以及executeBatch()执行所有的命令即可

String sql = "insert into tb_user(username,password) values (?,?)";            preparedStatement=connection.prepareStatement(sql1);            for(int i=0;i<=5;i++){                preparedStatement.setString(1, "user-"+i);                preparedStatement.addBatch();            }            preparedStatement.executeBatch();

D 事务处理

所谓事务,就是指所有的操作要么一起成功,要么一起失败
事务的ACID特性:
Atomicity(原子性),Consistency(一致性),Isolation(隔性),Durability(持久性)

原子性:原子性是事务最小的单元,是不可再分割的单元,相当于一个个小的数据库操作,这些操作必须同时完成,如果有一个失败,一切的操作全部失败,A和B转账是一个完整的不可再分割的整体,如果A转账失败,则B的操作肯定无法成功
一致性:数据库操作的前后是完全一致的,保证数据的有效性,正常操作则会维持有效性,如果事务出现了错误,则回到最原始状态,也要维持数据有效性,这样保证事务开始和结束时系统处于一致状态,如果A和B转账成功,则A的钱减少,B的钱增加,保持一致,如果转账失败,A的钱不会减少,B的钱不会增加,也要保持一致
隔离性:多个事务可以同时进行且无法彼此访问,只有当事务完成最终操作时,才可以看到结果

MySQL对事务的支持如下:

这里写图片描述

在MySQL数据库中,如果要应用事务处理,应按照以下命令执行:
a.取消自动提交,执行SET AUTOCOMMIT=0,这样所有的更新指令并不会立即发送到数据表中,而只存于当前的session;
b.开启事务,执行START TRANSACTION或BEGIN;
c.编写数据库更新语句,可以在编写的数据库更新语句之间记录事务的保存点,使用SAVEPOINT指令;
d.提交事务,如果确信数据库操作没有错误,使用COMMIT提交事务;

            //事务处理            //如果不加事务处理,则只有错误的SQL语句不能执行,而其前后的语句都可以执行            //加了事务处理后,但凡有一个SQL语句有错误,则所有的语句都不会执行            //取消自动提交            connection.setAutoCommit(false);            state = connection.createStatement();            state.addBatch("insert into tb_user (username,password) values ('user-1','password-1')");            state.addBatch("insert into tb_user (username,password) values ('user-2','password-2')");            state.addBatch("insert into tb_user (username,password) values ('user-3,'password-3')");            state.addBatch("insert into tb_user (username,password) values ('user-4','password-4')");            state.addBatch("insert into tb_user (username,password) values ('user-5','password-5')");            try{            state.executeBatch();//执行批处理            connection.commit();提交事务            }catch (Exception e){                try{                connection.rollback();回滚                }catch (Exception ex){                }            }       

注意:
以上代码有一句少了一个单分号,博主故意为之,目的就是测试事务的ACID特性,测试结果:如果不加事务,那么只有错误SQL语句执行不成功,其他则会成功,一旦加上事务操作,只要含有任一错误SQL语句,则所有的操作都不成功,从而验证了事务的ACID特性.

再附加一点内容,即使用元数据分析数据库

JDBC提供了DatabaseMetaData和ResultSetMetaData接口分析数据库的元数据
使用DatabaseMetaData,可以得到数据库的一些基本信息,数据库的名称,版本,以及表的一些基本信息

这里写图片描述

            //使用元数据获取数据库的信息            DatabaseMetaData metaData =       connection.getMetaData();         System.out.println(metaData.getDatabaseProductName());          System.out.println(metaData.getDatabaseMajorVersion()+"."+metaData.getDatabaseMinorVersion());            ResultSet primaryKeys = metaData.getPrimaryKeys(null, null, "tb_user");            while(primaryKeys.next()){              System.out.println(primaryKeys.getString(1));               System.out.println(primaryKeys.getString(2));               System.out.println(primaryKeys.getString(3));               System.out.println(primaryKeys.getString(4));               System.out.println(primaryKeys.getString(5));               System.out.println(primaryKeys.getString(6));            }

使用ResultSetMetaData可以获取查询数据的信息,如数据行数,列数,列名称等等
可以使用PreparedStatement的getMetaData()得到ResultSetMetaData对象,之后再使用其一系列的方法.

这里写图片描述

            //使用结果集元数据获取查询结果的信息            String sql = "select * from tb_user";            preparedStatement = connection.prepareStatement(sql);               ResultSetMetaData metaData = preparedStatement.getMetaData();            System.out.println(metaData.getColumnCount());

最后,附上以上操作的全部代码:

package cn.mysql;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Statement;import javax.swing.JOptionPane;public class MySql2 {    public static void main(String[] args) throws Exception {        String DRIVER = "com.mysql.jdbc.Driver";        String URL = "jdbc:mysql://localhost:3306/login";        String USER = "root";         String PASSWORD = "root";        Connection connection = null;        PreparedStatement preparedStatement = null;        Statement state = null;        ResultSet rs = null;        try {            Class.forName(DRIVER);        } catch (ClassNotFoundException e) {            JOptionPane.showMessageDialog(null, "驱动程序加载失败");        }        try {            connection = DriverManager.getConnection(URL, USER, PASSWORD);        } catch (SQLException e) {            JOptionPane.showMessageDialog(null, "数据库连接失败");        }        try {//          String sql = "select username,password from tb_user where username like '%user%'";//          preparedStatement = connection.prepareStatement(//                  sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);//          rs = preparedStatement.executeQuery();            //use ResultSet to insert data            /*            rs.moveToInsertRow();            rs.updateString("username", "user");            rs.updateString("password", "password");            rs.insertRow();            */            //use ResultSet to update data            /*            rs.last();            rs.updateString("username", "user-1");            rs.updateString("password", "password-1");            rs.updateRow();            */            //use ResultSet to delete data//          rs.last();//          rs.deleteRow();            //批处理操作//          String sql = "insert into tb_user(username,password) values (?,?)";//          String sql1 = "delete from tb_user where username = ?";//          preparedStatement = connection.prepareStatement(sql1);//          for(int i=0;i<5;i++){//              preparedStatement.setString(1, "user-"+i);//              preparedStatement.addBatch();//          }//          preparedStatement.executeBatch();//          while(rs.next()){//              System.out.println(rs.getString(1) + "\t" + rs.getString(2));//          }            //事务处理            //如果不加事务处理,则只有错误的SQL语句不能执行,而其前后的语句都可以执行            //加了事务处理后,但凡有一个SQL语句有错误,则所有的语句都不会执行//          connection.setAutoCommit(false);//          state = connection.createStatement();//          state.addBatch("insert into tb_user (username,password) values ('user-1','password-1')");//          state.addBatch("insert into tb_user (username,password) values ('user-2','password-2')");//          state.addBatch("insert into tb_user (username,password) values ('user-3,'password-3')");//          state.addBatch("insert into tb_user (username,password) values ('user-4','password-4')");//          state.addBatch("insert into tb_user (username,password) values ('user-5','password-5')");            try{            state.executeBatch();//执行批处理            connection.commit();提交事务            }catch (Exception e){                try{                connection.rollback();回滚                }catch (Exception ex){                }            }            //使用元数据获取数据库的信息//          DatabaseMetaData metaData = connection.getMetaData();//          System.out.println(metaData.getDatabaseProductName());//          System.out.println(metaData.getDatabaseMajorVersion()+"."+metaData.getDatabaseMinorVersion());//          ResultSet primaryKeys = metaData.getPrimaryKeys(null, null, "tb_user");//          while(primaryKeys.next()){//              System.out.println(primaryKeys.getString(1));//              System.out.println(primaryKeys.getString(2));//              System.out.println(primaryKeys.getString(3));//              System.out.println(primaryKeys.getString(4));//              System.out.println(primaryKeys.getString(5));//              System.out.println(primaryKeys.getString(6));//          }            //使用结果集元数据获取查询结果的信息            String sql = "select * from tb_user";            preparedStatement = connection.prepareStatement(sql);               ResultSetMetaData metaData = preparedStatement.getMetaData();            System.out.println(metaData.getColumnCount());//          rs.close();//          preparedStatement.close();//          state.close();            connection.close();        } catch (Exception e) {            JOptionPane.showMessageDialog(null, "执行出错");//          e.printStackTrace();        }    }}
原创粉丝点击