一.添加数据
添加数据分为两种情况,一种情况是一次只添加一条记录,另一种情况是一次添加多条记录,即批量添加记录。因为PreparedStatement接口和CallableStatement接口均继承了Statement接口,所以通过这三种类型的实例均可以完成添加一条记录的操作。
1.通过Statement实例完成的典型代码如下:
statement.executeUpdate("insert into record(id,name) values(060522,'马先生')");
2.通过PreparedStatement实例完成的典型代码如下:
preparedStatement = conn.prepareStatement("insert into record(id,name) values(?,?)");
preparedStatement.setInt(1, 060522);
preparedStatement.setString(2, "马先生");
preparedStatement.executeUpdate();
3.通过CallableStatement实例完成的典型代码如下:
callableStatement = conn.prepareCall("{call testInsert(?,?)}");
callableStatemen.setInt(1, 060522);
callableStatemen.setString(2, "马先生");
callableStatemen.executeUpdate();
如果一次只添加一条记录,只有在执行executeUpdate()方法时才真正提交到数据库,例如在通过PreparedStatement和CallableStatement实例添加时,必须在设置完参数后执行executeUpdate()方法。
如果需要批量添加记录,则只能通过PreparedStatement或CallableStatement实例实现。
// 执行静态INSERT语句
public void insertOne(String name) throws SQLException {
conn = DriverManager.getConnection(url, username, password);
stmt = conn.createStatement();
stmt.executeUpdate("insert into tb_testInsert(name) values('" + name
+ "')");// 执行静态INSERT语句
stmt.close();
conn.close();
}
// 执行动态INSERT语句
public void insertMore(String[] names) throws SQLException {
conn = DriverManager.getConnection(url, username, password);
prpdStmt = conn
.prepareStatement("insert into tb_testInsert(name) values(?)");// 预//处理动态INSERT语句
prpdStmt.clearBatch();// 清除Batch
for (int i = 0; i < names.length; i++) {
prpdStmt.setString(1, names[i]);// 为动态SQL语句赋值
prpdStmt.addBatch();// 向Batch中添加INSERT语句
}
prpdStmt.executeBatch(); // 批量执行Batch中的INSERT语句
prpdStmt.close();
conn.close();
}
// 通过存储过程执行INSERT语句
public void insertProcedure(String[] names) throws SQLException {
conn = DriverManager.getConnection(url, username, password);
cablStmt = conn.prepareCall("{call test_insert(?)}");// 调用存储过程
cablStmt.clearBatch();
for (int i = 0; i < names.length; i++) {
cablStmt.setString(1, names[i]);
cablStmt.addBatch();
}
cablStmt.executeBatch();
cablStmt.close();
conn.close();
}
// 查询所有记录
public List<Object[]> selectAll() {
List<Object[]> list = new ArrayList<Object[]>();
try {
conn = DriverManager.getConnection(url, username, password);
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from tb_testInsert");
while (rs.next()) {
Object note[] = new Object[2];
for (int i = 0; i < note.length; i++) {
note[i] = rs.getObject(i + 1);
}
list.add(note);
}
stmt.close();
conn.close();
} catch (SQLException e) {
System.out.println("------ 在检索记录时抛出异常,内容如下:");
e.printStackTrace();
}
return list;
}
}
二.查询数据
在查询数据时,既可以利用Statement实例通过执行静态SELECT语句完成,也可以利用PreparedStatement实例通过执行动态SELECT语句完成,还可以利用CallableStatement实例通过执行存储过程来完成。
利用Statement实例通过执行静态SELECT语句完成数据查询的典型代码如下:
ResultSet rs = statement.executeQuery("select * from tb_record where sex='" + sex + "'");
利用PreparedStatement实例通过执行动态SELECT语句完成数据查询的典型代码如下:
preparedStatement = connection.prepareStatement("select * from tb_record where sex=?");
preparedStatement.setString(1, sex);
ResultSet rs = preparedStatement.executeQuery();
利用CallableStatement实例通过执行存储过程来完成数据查询的典型代码如下:
callableStatement = connection.prepareCall("{call select_by_sex(?)}");
callableStatement.setString(1, sex);
ResultSet rs = callableStatement.executeQuery();
无论利用哪种方式查询记录,都需要执行executeQuery()方法,并且该方法将返回一个ResultSet型的结果集,在该结果集中不仅包含所有满足查询条件的记录,还包含相应数据表的相关信息,例如每一列的名称、类型和列的数量等。在执行executeQuery()方法时可能抛出SQLException类型的异常,所以需要通过try-catch语句进行捕获。
在查询记录时,通常情况下将返回的结果集遍历成一个List型的集合,在List集合中存放的是数组对象,每一个数组对象代表一条满足条件的记录。
通常情况下利用while循环遍历ResultSet结果集,并通过执行next()方法判断是否还存在满足查询条件的记录,如果存在则返回true,并将指针移动到下一条记录上,如果不存在则返回false。遍历ResultSet结果集的典型代码如下:
src/com/mwq/TestSelect.java关键代码:
prpdStmt = conn.prepareStatement("select * from tb_testSelect where sex=?");
prpdStmt.setString(1, sex);
ResultSet rs = prpdStmt.executeQuery();
while (rs.next()) {// 利用while循环遍历ResultSet结果集,并通过next()方法判断是否存在下一条记录
Object note[] = new Object[3];// 创建一个数组,每个数组代表一条满足条件的记录
for (int i = 0; i < note.length; i++) {// 利用for循环将记录信息读取到数组中
note[i] = rs.getObject(i + 1);
}
list.add(note);// 将数组添加到List集合中
}
注意:
数组的索引从0开始,而ResultSet结果集中数据列的索引从1开始,必须注意区分,否则将导致列索引越 界异常,即“Column index 0 is out of range”。
下面利用ResultSet结果集读取数据表信息,并不能通过ResultSet实例直接读取,需要执行ResultSet实例的getMetaData()方法,通过返回ResultSetMetaData型的实例读取,例如下面的代码:
src/com/mwq/TestSelect.java关键代码:
ResultSet rs = stmt.executeQuery("select * from tb_testSelect");
ResultSetMetaData rsmd = rs.getMetaData();
int column = rsmd.getColumnCount();// 列的数量
Object[] columnNames = { "列的名称", "列值的类型", "对应JAVA类型", "列值的最大宽度",
"是否允许为空", "是否默认自增", "是否为只读" };
list.add(columnNames);
for (int i = 1; i <= column; i++) {
Object[] columnInfo = new Object[columnNames.length];
columnInfo[0] = rsmd.getColumnName(i);// 列的名称
columnInfo[1] = rsmd.getColumnTypeName(i);// 列值的类型
columnInfo[2] = rsmd.getColumnClassName(i);// 对应Java类型
columnInfo[3] = rsmd.getColumnDisplaySize(i);// 列值的最大宽度,以字符为单位
columnInfo[4] = rsmd.isNullable(i);// 是否允许为空,0为不允许为空,1为允许为空
columnInfo[5] = rsmd.isAutoIncrement(i);// 是否默认自增
columnInfo[6] = rsmd.isReadOnly(i);// 是否为只读
list.add(columnInfo);
}
三.修改数据
修改数据分为两种情况,一种情况是一次只执行一条UPDATE语句,另一种情况是一次执行多条UPDATE语句,即批量修改记录。因为PreparedStatement和CallableStatement均继承了Statement,所以通过这3种类型的实例均可以完成非批量修改记录的操作。
l 通过Statement实例完成的典型代码如下:
statement.executeUpdate("update tb_record set salary=5800 where id=6");
l 通过PreparedStatement实例完成的典型代码如下:
preparedStatement = conn.prepareStatement("update tb_record set salary=? where id=?");
preparedStatement.setInt(1, 5800);
preparedStatement.setInt(2, 6);
preparedStatement.executeUpdate();
l 通过CallableStatement实例完成的典型代码如下:
callableStatement = conn.prepareCall("{call update_salary_by_id(?,?)}");
callableStatemen.setInt(1, 5800);
callableStatemen.setString(2, 6);
callableStatemen.executeUpdate();
如果需要批量修改记录,则只能通过PreparedStatement或CallableStatement实例实现,在下面的例子中,主要讲解批量修改记录。
下面的代码通过动态UPDATE语句实现了批量修改记录,关键代码如下:
src/com/mwq/TestUpdate.java关键代码:
prpdStmt = conn.prepareStatement("update tb_testUpdate set salary=? where id=?");
prpdStmt.clearBatch();
Iterator<Entry<String, String>> entryIt = map.entrySet().iterator();
while (entryIt.hasNext()) {// 通过遍历Map循环为动态UPDATE语句赋值并添加到Batch中
Entry<String, String> entry = entryIt.next();
prpdStmt.setString(1, entry.getValue());
prpdStmt.setString(2, entry.getKey());
prpdStmt.addBatch();
}
prpdStmt.executeBatch();
下面的代码通过存储过程实现了批量修改记录,与通过动态UPDATE语句实现基本相同,关键代码如下:
src/com/mwq/TestUpdate.java关键代码:
cablStmt = conn.prepareCall("{call update_salary_by_id(?,?)}");
cablStmt.clearBatch();
Iterator<Entry<String, String>> entryIt = map.entrySet().iterator();
while (entryIt.hasNext()) {// 通过遍历Map循环为动态UPDATE语句赋值并添加到Batch中
Entry<String, String> entry = entryIt.next();
cablStmt.setString(1, entry.getKey());
cablStmt.setString(2, entry.getValue());
cablStmt.addBatch();
}
cablStmt.executeBatch();
四.删除数据
删除数据分为两种情况,一种情况是一次只执行一条DELETE语句,另一种情况是一次执行多条DELETE语 句,即批量删除记录。因为PreparedStatement和CallableStatement均继承了Statement,所以通过这3 种类型的实例均可以完成非批量删除记录的操作:
l 通过Statement实例完成的典型代码如下:
statement.executeUpdate("delete from tb_record where id>6");
l 通过PreparedStatement实例完成的典型代码如下:
preparedStatement = conn.prepareStatement("delete from tb_record where id>?");
preparedStatement.setInt(1, 6);
preparedStatement.executeUpdate();
通过CallableStatement实例完成的典型代码如下:
callableStatement = conn.prepareCall("{call delete_by_id(?)}");
callableStatemen.setInt(1, 6);
callableStatemen.executeUpdate();
如果需要批量删除记录,则只能通过PreparedStatement或CallableStatement实例实现,在下面的例子中,将主要讲解批量删除记录。
下面的代码通过动态DELETE语句实现了批量删除记录,关键代码如下:
src/com/mwq/TestUpdate.java关键代码:
prpdStmt = conn.prepareStatement("delete from tb_testDelete where id=?");
prpdStmt.clearBatch();
for (int i = 0; i < ids.length; i++) {
prpdStmt.setString(1, ids[i]);
prpdStmt.addBatch();
}
prpdStmt.executeBatch();
src/com/mwq/TestUpdate.java关键代码:
cablStmt = conn.prepareCall("{call delete_by_id(?)}");
cablStmt.clearBatch();
for (int i = 0; i < ids.length; i++) {
cablStmt.setString(1, ids[i]);
cablStmt.addBatch();
}
cablStmt.executeBatch();