JDBC中使用PreparedStatement执行SQL语句并管理结果集
基本說明
1、使用PreparedStatement在對反復操作多條結構相似的SQL語句時效率更高,并且可以使用參數替代變量,可以防止SQL注入。
2、PreparedStatement也提供了 execute()? 、 executeUpdate()? 、 executeQuery()? 三個方法來執行crud操作,這三個方法無需傳遞參數,因為PreparedStatsments已經存儲了預編譯的SQL語句。
3、推薦使用PreparedStatement。
代碼示例,簡單PreparedStatement操作工具類。本例使用連接SqlServer 08 R2為例
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class PreparedStatementUtils {private String url;private String user;private String password;public PreparedStatementUtils(String urlString,String userString,String pasString){this.url = urlString;this.user = userString;this.password = pasString;}static{try {Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");} catch (ClassNotFoundException e) {e.printStackTrace();}}/**** 對輸入SQL進行查詢* @param sql* @throws SQLException*/public void queryResult(String sql)throws SQLException{try(//獲取數據庫連接Connection connection = DriverManager.getConnection(this.url, this.user, this.password);//使用conntection來創建一個PreparedStatement對象PreparedStatement preparedStatement =connection.prepareStatement(sql);){ResultSet rSet= preparedStatement.executeQuery();while(rSet.next()){System.out.println("Id=" + rSet.getLong(1) + ";ProductName=" + rSet.getString(2));}}}/**** 對輸入SQL進行新增、更新操作* @param sql* @return* @throws SQLException*/public int updateResult(String sql)throws SQLException{try(Connection connection = DriverManager.getConnection(this.url, this.user, this.password);PreparedStatement preparedStatement = connection.prepareStatement(sql); ){return preparedStatement.executeUpdate();}}/*** 使用PreparedStatement進行批量* @throws SQLException*/public void updateResult()throws SQLException{long stat = System.currentTimeMillis();try(Connection connection = DriverManager.getConnection(this.url, this.user, this.password);PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO dbo.Product( ProductName ,IsEffective ,Remark ,UnitId)VALUES (?,'Y',?,1)");){for (int i = 0; i < 10; i++) {preparedStatement.setString(1, "測試名字" + i);preparedStatement.setString(2, "測試備注" + i);preparedStatement.executeUpdate();}}long end = System.currentTimeMillis();System.out.println("使用PreparedStatement進行費時:" + (end-stat));} }?
可滾動可更新的結果集?
1、ResultSet定位記錄指針的方法由absolute()、previous()、last()、afterLast()等方法。可以對結果集進行滾動操作。
2、以默認的方式打開的結構集ResultSet是不能更新的。如果希望更新,可以在創建Statement或者PreparedStatement時傳入額外的參數。
?
resultSetType:控制ResultSet的類型,該參數有如下三個值:
1、ResultSet.TYPE_FORWARD_ONLY:該常量控制記錄指針只能向前移動。
2、ResultSet.TYPE_SCROLL_INSENSITIVE:該常量控制記錄指針可以自由移動(可滾動結果集),但是底層數據的改變不會影響ResultSet里的內容。(sqlserver 可能不支持此操作,會報錯:不支持此游標類型/并發組合)
3、ResultSet.TYPE_SCROLL_SENSITIVE:常量控制記錄指針可以自由移動(可滾動結果集),但是底層數據的改變會影響ResultSet里的內容。
?
resultSetConcurrency:控制ResultSet的并發類型,該參數可以接受如下兩個值:
1、ResultSet.CONCUR_UPDATABLE:該常量指示ResultSet是可更新的并發模式。
? ? ? 這里有兩個條件:1、所有數據來自同個表。2、選出的數據必須包含主鍵列。
2、ResultSet.CONCUR_READ_ONLY:該常量指示ResultSet是只讀的并發模式(默認)。
?
代碼舉例說明,在上述代碼中再增加一個方法:
/*** 查詢并修改指定結果集數據* @param sql* @throws SQLException*/public void queryAndUpdata(String sql)throws SQLException{try(Connection connection = DriverManager.getConnection(this.url, this.user, this.password);PreparedStatement preparedStatement = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);ResultSet rSet = preparedStatement.executeQuery();){ rSet.last();//移動到最后一行int rowCount = rSet.getRow();//獲得最后一行的行號for (int i = rowCount; i > 0; i--) {rSet.absolute(i);//移動指針到指定行System.out.println("Id=" + rSet.getLong(1) + ";ProductName=" + rSet.getString(2));rSet.updateString(2, rSet.getString(2) + "X");//修改查詢結果第二列的值rSet.updateRow();//提交修改}}}?
使用ResultSetMetaData分析結果集?
如果程序不知道ResultSet里面有哪些數據列,以及每個數據列的數據類型,那么可以通過ResultSetMetaData來獲取關于ResultSet里的描述信息。
ResultSet里包含了一個getMetaData()方法,該方法返回該ResultSet對應的ResultSetMetaData對象。通過ResultSetMetaData對象里的方法可以獲取信息。常用的方法由如下三個:
1、int getColumnCount():返回該ResultSet的列的數量。
2、String getColumnName(int column):返回指定索引的列名。
3、int getColumnType(int column):返回指定索引的列類型。
?
代碼舉例說明,在上述代碼中再增加一個方法:
/**** 查詢顯示結果列* @param sql* @throws SQLException*/public void queryAndCheck(String sql)throws SQLException{try(Connection connection = DriverManager.getConnection(this.url, this.user, this.password);PreparedStatement preparedStatement = connection.prepareStatement(sql);ResultSet resultSet = preparedStatement.executeQuery();){ResultSetMetaData resultSetMetaData = resultSet.getMetaData();int colCount = resultSetMetaData.getColumnCount();for (int i = 1; i <= colCount; i++) {System.out.println("第" + i + "列列名是" + resultSetMetaData.getColumnName(i) + ";類型是" + resultSetMetaData.getColumnType(i));}}}?
總結
以上是生活随笔為你收集整理的JDBC中使用PreparedStatement执行SQL语句并管理结果集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VueJS项目
- 下一篇: CSS3动画和VUE动画整理