数据库最基本的操作为一般的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();
}
}
}