使用PreparedStatement實現CRUD操作
文章目錄
操作和訪問資料庫
資料庫連線被用於向資料庫伺服器傳送命令和 SQL 語句,並接受資料庫伺服器返回的結果。其實一個資料庫連線就是一個Socket連線。
在 java.sql 包中有 3 個介面分別定義了對資料庫的呼叫的不同方式:
- Statement:用於執行靜態 SQL 語句並返回它所生成結果的物件。
- PrepatedStatement:SQL 語句被預編譯並儲存在此物件中,可以使用此物件多次高效地執行該語句。
- CallableStatement:用於執行 SQL 儲存過程
使用Statement運算元據表的弊端
通過呼叫 Connection 物件的 createStatement() 方法建立該物件。該物件用於執行靜態的 SQL 語句,並且返回執行結果。
Statement介面中定義了下列方法用於執行SQL語句:
int excuteUpdate(String sql):執行更新操作INSERT、UPDATE、DELETE
ResultSet executeQuery(String sql):執行查詢操作SELECT
但是使用Statement運算元據表存在弊端:
1.存在拼串操作,繁瑣
2.存在SQL隱碼攻擊問題
SQL隱碼攻擊問題:
SQL 注入是利用某些系統沒有對使用者輸入的資料進行充分的檢查,而在使用者輸入資料中注入非法的 SQL 語句段或命令(如:SELECT user, password FROM user_table WHERE user='a' OR 1 = ' AND password = ' OR '1' ='1')
,從而利用系統的 SQL 引擎完成惡意行為的做法。
對於 Java 而言,要防範 SQL 注入,只要用 PreparedStatement
(從Statement擴充套件而來) 取代 Statement
就可以了。
PreparedStatement的使用
PreparedStatement介紹
- PreparedStatement 介面是 Statement 的子介面,它表示一條預編譯過的 SQL 語句
- PreparedStatement 物件所代表的 SQL 語句中的引數用問號(?)來表示,呼叫 PreparedStatement 物件的setXxx() 方法來設定這些引數. setXxx() 方法有兩個引數,第一個引數是要設定的 SQL 語句中的引數的索引(從 1開始),第二個是設定的 SQL 語句中的引數的值
- 可以通過呼叫 Connection 物件的 preparedStatement(String sql) 方法獲取 PreparedStatement 物件
PreparedStatement vs Statement
Java與SQL對應資料型別轉換表
Java型別 | SQL型別 |
---|---|
boolean | BIT |
byte | TINYINT |
short | SMALLINT |
int | INTEGER |
long | BIGINT |
String | CHAR,VARCHAR,LONGVARCHAR |
byte array | BINARY,VAR BINARY |
java.sql.Date | DATE |
java.sql.Time | TIME |
java.sql.Timestamp | TIMESTAMP |
使用PreparedStatement實現增,刪,改操作
使用PreparedStatement實現增、刪、改操作
public void update(String sql,Object ...args){//sql中佔位符的個數與可變形參的長度相同!
Connection conn = null;
PreparedStatement ps = null;
try {
//1.獲取資料庫的連線
conn = JDBCUtils.getConnection();
//2.預編譯sql語句,返回PreparedStatement的例項
ps = conn.prepareStatement(sql);
//3.填充佔位符
for(int i = 0;i < args.length;i++){
ps.setObject(i + 1, args[i]);//小心引數宣告錯誤!!
}
//4.執行sql語句
ps.execute();
} catch (Exception e) {
e.printStackTrace();
}finally{
//5.資源的關閉
JDBCUtils.closeResource(conn, ps);
}
}
使用PreparedStatement實現查詢操作
public <T> T getInstance(Class<T> clazz,String sql,Object ...args){
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//獲取資料庫連線
conn= JDBCUtils.getConnection();
//預編譯sql語句,得到PreparedStatement物件
ps=conn.prepareStatement(sql);
//填充佔位符
for(int i=0;i<args.length;i++){
ps.setObject(i+1,args[i]);
}
//執行executeQuery(),得到結果集:ResultSet
rs=ps.executeQuery();
//獲取結果集的後設資料:ResultSetMetaData
ResultSetMetaData rsmd=rs.getMetaData();
//通過ResultSetMetaData獲取結果集的列數
int columnCount=rsmd.getColumnCount();
if(rs.next()){
T t=clazz.newInstance();
//處理結果集一行資料中的每一列
for (int i=0;i<columnCount;i++){
//獲取列值
Object columValue=rs.getObject(i+1);
//獲取每個列的列名
String columnName=rsmd.getColumnName(i+1);
String columnLable=rsmd.getColumnLabel(i+1);
//使用反射,給物件的相應屬性賦值射
Field field=clazz.getDeclaredField(columnLable);
field.setAccessible(true);
field.set(t,columValue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//關閉資源
JDBCUtils.closeResource(conn,ps,rs);
}
return null;
}
ResultSet和ResultSetMetaData
ResultSet
- 查詢需要呼叫PreparedStatement 的 executeQuery() 方法,查詢結果是一個ResultSet 物件
- ResultSet 物件以邏輯表格的形式封裝了執行資料庫操作的結果集,ResultSet 介面由資料庫廠商提供實現
- ResultSet 物件維護了一個指向當前資料行的遊標,初始的時候,遊標在第一行之前,可以通過 ResultSet 物件的 next() 方法移動到下一行。呼叫 next()方法檢測下一行是否有效。若有效,該方法返回 true,且指標下移。相當於Iterator物件的 hasNext() 和 next() 方法的結合體
- 當指標指向一行時, 可以通過呼叫 getXxx(int index) 或 getXxx(int columnName) 獲取每一列的值
- ResultSet介面的常用方法:
注意:
Java與資料庫互動涉及到的相關Java API中的索引都從1開始
相關文章
- JDBC3——SQL隱碼攻擊、及其解決方法——Statement與PreparedStatement對比——PreparedStatement的CRUDJDBCSQL
- 使用rails實現最簡單的CRUDAI
- 使用Node+React實現簡單CRUDReact
- MVC5使用Angular.Js實現CrudMVCAngularJS
- 如何基於COLA架構快速實現一個CRUD操作架構
- JPA之使用JPQL進行CRUD操作
- JDBC PreparedStatement 實現原理【推薦閱讀】JDBC
- 使用TS+Sequelize實現更簡潔的CRUD
- 使用go在mongodb中進行CRUD操作MongoDB
- Elasticsearch CRUD基本操作Elasticsearch
- go操作mongo CRUDGo
- 使用Spring Boot反應式R2DBC實現PostgreSQL的CRUD操作原始碼 - RajeshSpring BootSQL原始碼
- Vue+Element UI實現CRUDVueUI
- SpringBoot整合Redis使用Restful風格實現CRUD功能Spring BootRedisREST
- 教程:使用PreparedStatement訪問DLA
- JDBC使用PreparedStatement的好處JDBC
- 使用“純”Servlet做一個單表的CRUD操作Servlet
- SpringBoot實現mongoDB的CRUDSpring BootMongoDB
- Vue+Ant Design實現CRUDVue
- MyBatis 的簡單 CRUD 操作MyBatis
- Mybatis:CRUD操作及配置解析MyBatis
- Java Hibernate 之 CRUD 操作Java
- 如何快速的插入 100W資料到資料庫,使用PreparedStatement 最快實現!資料庫
- 【MongoDB學習筆記】-使用 MongoDB 進行 CRUD 操作(上)MongoDB筆記
- 【MongoDB學習筆記】-使用 MongoDB 進行 CRUD 操作(下)MongoDB筆記
- 教程:如何在.NET中使用MongoDB以及基本的CRUD操作MongoDB
- 07-SpringBoot+MyBatis+Spring 技術整合實現商品模組的CRUD操作Spring BootMyBatis
- 使用PrepareStatement實現批量插入操作REST
- java preparedStatementJava
- MySQL PreparedStatementMySql
- MongoDB 4.X CRUD基本操作MongoDB
- JPA工程的建立和CRUD操作
- mybatis 的crud及批量cud操作MyBatis
- 使用PreparedStatement為佔位符?賦值賦值
- maven非web專案整合mbatis實現CRUDMavenWebBAT
- Spring Boot+MiniUI CRUD操作Spring BootUI
- java-Statement、PreparedStatement、PreparedStatement + 批處理 的區別Java
- Spring Boot Crud操作示例 | Java Code GeeksSpring BootJava