本文內(nèi)容
1.什么是JDBC以及為什么要使用JDBC
2.JDBC核心API的講解
3.使用JDBC核心API進(jìn)行CRUD操作
4.JDBC的工具類的抽取與改進(jìn)
5.JDBC的SQL注入漏洞分析與解決方案
6.使用JDBC的PreparedStatement預(yù)編譯對象進(jìn)行CRUD操作(重點(diǎn))
7.JDBC的批處理操作
使用JDBC的預(yù)編譯對象進(jìn)行CRUD操作(重點(diǎn))
[if !supportLists]1.1?[endif]1.JDBC的概述
JDBC:(Java DataBase Connectivity Java數(shù)據(jù)庫連接).
*是一種用于執(zhí)行SQL語句的Java 的API.可以為多種關(guān)系型數(shù)據(jù)庫提供統(tǒng)一的訪問.它是由一組使用Java語言編寫的類或接口組成.
簡說:用java語言編寫的一組用于訪問關(guān)系型數(shù)據(jù)庫的接口和類.
作用:使用Java語言連接到數(shù)據(jù)庫
驅(qū)動:兩個(gè)設(shè)備之間的通信橋梁.
Java語言要連接數(shù)據(jù)庫必須使用數(shù)據(jù)庫的驅(qū)動
本質(zhì):
SUN公司提供了一組接口,各個(gè)數(shù)據(jù)庫生產(chǎn)商提供了這套接口的實(shí)現(xiàn).(這組規(guī)范就是JDBC規(guī)范.)
[if !supportLists]1.2?[endif]02_JDBC的入門(寫)
先解釋下,再寫
設(shè)置工作空間的編碼為utf-8
SQL腳本:
create database web_test3;
use web_test3;
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(20),
age int
);
insert into user values (null,'aaa','123','小麗',34);
insert into user values (null,'bbb','123','大王',32);
insert into user values (null,'ccc','123','小明',28);
insert into user values (null,'ddd','123','大黃',21);
引入數(shù)據(jù)庫的驅(qū)動.
注意:復(fù)制驅(qū)動包過來后,一定要選中, add to Build Path
1.加載驅(qū)動.
2.獲得連接.
獲得語句(Statement )對象
3.執(zhí)行SQL
4.釋放資源.
public?class?JDBCDemo1 {
@Test
/**
* JDBC的入門
?*/
public?void?demo1() throws?Exception{
// 1.加載驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
// 2.獲得連接
Connection conn?= DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "abc");?//注意:密碼改成你的密碼
// 3.基本操作:執(zhí)行SQL
// 3.1獲得執(zhí)行SQL語句的對象
Statement statement?= conn.createStatement();
// 3.2編寫SQL語句:
String sql?= "select * from user";
// 3.3執(zhí)行SQL:
ResultSet rs?= statement.executeQuery(sql);
// 3.4遍歷結(jié)果集:
while(rs.next()){
System.out.print(rs.getInt("id")+" ");
System.out.print(rs.getString("username")+" ");
System.out.print(rs.getString("password")+" ");
System.out.print(rs.getString("nickname")+" ");
System.out.print(rs.getInt("age"));
System.out.println();
}
// 4.釋放資源
rs.close();
statement.close();
conn.close();
}
}
[if !supportLists]1.3?[endif]03_DriverManager的介紹
問題:
DriverManager對象有什么作用?
?為什么沒有使用registerDriver()注冊驅(qū)動芦圾?
?獲取連接的url路徑的含義椰棘?
1.DriverManager對象兩個(gè)作用:①刀闷、注冊驅(qū)動和②貌矿、獲取連接虎敦;
2.為什么使用沒有使用registerDriver注冊驅(qū)動滔岳?
DriverManager類:
原來這樣寫:
DriverManager.registerDriver(new?com.mysql.jdbc.Driver());
com.mysql.jdbc.Driver源碼:
現(xiàn)在這樣寫:
Class.forName(“com.mysql.jdbc.Driver”);//強(qiáng)制加載class到內(nèi)存
結(jié)論:直接調(diào)用registerDriver方法會導(dǎo)致驅(qū)動加載2次.
[if !supportLists]3.[endif]獲取連接的url路徑的含義声邦?
[if !supportLists]1.4?[endif]04_Connection的介紹
[if !supportLists]??[endif]Connection對象有哪些作用驻仅?
有兩個(gè)作用:①谅畅、創(chuàng)建執(zhí)行SQL的Statement(語句)對象;②噪服、管理事務(wù)
作用一毡泻、創(chuàng)建執(zhí)行sql語句的對象:
作用二:管理事務(wù)
總結(jié):
[if !supportLists]1.[endif]Connection對象的作用?
獲取語句對象
Statement
?CallableStatement(后面Oracle說)
管理事務(wù)
setAutoCommit(false);//手動開啟事務(wù)
...
...
commit()
rollback();
[if !supportLists]1.5?[endif]05_Statement的介紹
[if !supportLists]??[endif]Statement對象有哪些作用?
有兩個(gè)作用:①粘优、執(zhí)行sql語句仇味;②、進(jìn)行批處理
作用一:執(zhí)行sql語句
作用二:進(jìn)行批處理:就是把幾條sql語句添加到Statement對象命令列表中敬飒,一次性執(zhí)行多條sql語句邪铲。
[if !supportLists]1.6?[endif]06_ResultSet的介紹
ResultSet代表select查詢后的結(jié)果集
方法:
*向下移動光標(biāo).
*獲得結(jié)果集中整形數(shù)據(jù).
*獲得結(jié)果集中字符串類型的數(shù)據(jù):
...
遍歷結(jié)果集:
* while(rs.next()){
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id+" ???"+username+" ???"+password);
}
獲得結(jié)果集中的數(shù)據(jù):
* int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
如果結(jié)果集中只有一條記錄:
* if(rs.next()){
...
}
原理:
總結(jié):
???1. Result rs = statement.executeQuery(“select * from user”);
???2.while(rs.next()) {
???????rs.getInt(“id”);
rs.getString(“username”);
rs.getObject(“password”);
rs.getInt(4);
}
[if !supportLists]1.7?[endif]07_JDBC的資源的釋放
Connection的使用原則:盡量要晚創(chuàng)建,盡量早釋放!!!
try{
..
...
}catch(){...}
finally {....}
要掌握,看看代碼,晚上寫
[if !supportLists]??[endif]掌握釋放資源的標(biāo)準(zhǔn)代碼:一般把釋放資源的代碼放到finally里面去執(zhí)行
finally?{
//5、方法資源
if?(resultSet!=null) {
try?{
resultSet.close();
} catch?(SQLException e) {
e.printStackTrace();
}
resultSet=null;
}
if?(statement!=null) {
try?{
statement.close();
} catch?(SQLException e) {
e.printStackTrace();
}
statement=null;
}
if?(conn!=null) {
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn=null;
}
}
1无拗、為什么對象調(diào)用了close()方法以后還要把對象手動賦值為null?
資源釋放的一段標(biāo)準(zhǔn)代碼:
// 4.釋放資源.
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null; // 為了讓JVM垃圾回收更早回收該對象.
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
總結(jié):
try {
//加載驅(qū)動
//獲取連接
//創(chuàng)建statement
//執(zhí)行SQL
//遍歷結(jié)果集
}catch(Exception ex) {
}finally {
//釋放資源
rs,stat,conn
if (rs!=null) {
try {
rs.close();
}catch() {}
rs = null;
}
}
[if !supportLists]1.8?[endif]08_JDBC的CRUD操作之保存(寫)
思路:
加載驅(qū)動
獲得連接
獲得Statement對象,執(zhí)行SQL
釋放資源
@Test
/**
*保存操作的代碼實(shí)現(xiàn)
?*/
public?void?demo1(){
Connection conn?= null;
Statement stmt?= null;
try{
//注冊驅(qū)動:
Class.forName("com.mysql.jdbc.Driver");
//獲得連接:
conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
//執(zhí)行操作:
//創(chuàng)建執(zhí)行SQL語句對象:
stmt = conn.createStatement();
//編寫SQL語句:
String sql?= "insert into user values (null,'eee','123','阿黃',21)";
//執(zhí)行SQL語句:
int?num = stmt.executeUpdate(sql);
if(num?> 0){
System.out.println("保存用戶成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
//資源釋放:
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
}
[if !supportLists]1.9?[endif]09_JDBC的CRUD操作之修改操作(寫)
????@Test
/**
*修改操作的代碼實(shí)現(xiàn)
?*/
public?void?demo2(){
Connection conn?= null;
Statement stmt??= null;
try{
//注冊驅(qū)動:
Class.forName("com.mysql.jdbc.Driver");
//獲得連接
conn?= DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
//執(zhí)行操作:
//創(chuàng)建執(zhí)行SQL語句的對象:
stmt?= conn.createStatement();
//編寫SQL語句:
String sql = "update user set password='abc',nickname='旺財(cái)' where id = 5";
//執(zhí)行SQL語句:
int?num?= stmt.executeUpdate(sql);
if(num?> 0){
System.out.println("修改用戶成功!!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
//資源釋放:
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
}
[if !supportLists]1.10?[endif]10_JDBC的CRUD操作之刪除操作
@Test
/**
*刪除操作的代碼實(shí)現(xiàn)
?*/
public?void?demo3(){
Connection conn?= null;
Statement stmt?= null;
try{
//注冊驅(qū)動:
Class.forName("com.mysql.jdbc.Driver");
//獲得連接:
conn?= DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
//創(chuàng)建執(zhí)行SQL語句對象:
stmt?= conn.createStatement();
//編寫SQL:
String sql = "delete from user where id = 5";
//執(zhí)行SQL:
int?num?= stmt.executeUpdate(sql);
if(num?> 0){
System.out.println("刪除用戶成功4健!!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
//資源釋放:
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
}
[if !supportLists]1.11?[endif]11_JDBC的CRUD操作之查詢操作
@Test
/**
*查詢多條記錄
?*/
public?void?demo4(){
Connection conn?= null;
Statement stmt?= null;
ResultSet rs?= null;
try{
//注冊驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
//獲得連接
conn?= DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");
//執(zhí)行操作
//創(chuàng)建執(zhí)行SQL語句的對象:
stmt?= conn.createStatement();
//編寫SQL:
String sql?= "select * from user";
//執(zhí)行SQL:
rs?= stmt.executeQuery(sql);
//遍歷結(jié)果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
//資源釋放:
if(rs?!= null){
try?{
rs.close();
} catch?(SQLException e) {
e.printStackTrace();
}
rs?= null;
}
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
}
[if !supportLists]1.12?[endif]12_JDBC的工具類的抽取(寫)
[if !supportLists]??[endif]總結(jié)一下抽取的原則:把相同的操作抽到一個(gè)方法里揽惹,可以重復(fù)利用被饿。
關(guān)于JDBC我們可以抽取:加載驅(qū)動搪搏、獲取連接狭握、釋放資源這三部分的代碼。
/**
* JDBC的工具類
?* @author??itheima
?*/
public?class?JDBCUtils {
private?static?final?String driverClassName;
private?static?final?String url;
private?static?final?String username;
private?static?final?String password;
static{
driverClassName="com.mysql.jdbc.Driver";
url="jdbc:mysql:///web_test3";
username="root";
password="abc";
}
/**
*注冊驅(qū)動的方法
?*/
public?static?void?loadDriver(){
try?{
Class.forName(driverClassName);
} catch?(ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
*獲得連接的方法
?*/
public?static?Connection getConnection(){
Connection conn?= null;
try{
//將驅(qū)動一并注冊:
loadDriver();
//獲得連接
conn?= DriverManager.getConnection(url,username, password);
}catch(Exception e){
e.printStackTrace();
}
return?conn;
}
/**
*釋放資源的方法
?*/
public?static?void?release(Statement stmt,Connection conn){
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
public?static?void?release(ResultSet rs,Statement stmt,Connection conn){
//資源釋放:
if(rs?!= null){
try?{
rs.close();
} catch?(SQLException e) {
e.printStackTrace();
}
rs?= null;
}
if(stmt?!= null){
try?{
stmt.close();
} catch?(SQLException e) {
e.printStackTrace();
}
stmt?= null;
}
if(conn?!= null){
try?{
conn.close();
} catch?(SQLException e) {
e.printStackTrace();
}
conn?= null;
}
}
}
測試工具類
@Test
/**
*查詢操作:使用工具類
?*/
public?void?demo1(){
Connection conn?= null;
Statement stmt?= null;
ResultSet rs?= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
// 創(chuàng)建執(zhí)行SQL語句的對象:
stmt?= conn.createStatement();
//編寫SQL:
String sql?= "select * from user";
//執(zhí)行查詢:
rs?= stmt.executeQuery(sql);
//遍歷結(jié)果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
//釋放資源:
JDBCUtils.release(rs, stmt, conn);
}
}
[if !supportLists]1.13?[endif]13_JDBC的配置信息提取到配置文件
[if !supportLists]??[endif]如何定義配置文件以及加載配置文件中的信息疯溺?
定義配置文件:
獲取配置文件中的信息:
[if !supportLists]1.14?[endif]14_JDBC的SQL注入漏洞(SQL演示)
[if !supportLists]??[endif]什么是sql注入漏洞论颅?
在我們的網(wǎng)站中肯定會有登錄的操作,用戶之所以能登錄成功囱嫩,肯定是通過用戶名和對應(yīng)的密碼去數(shù)據(jù)庫中能找到對應(yīng)的一條數(shù)據(jù)恃疯,假設(shè)某個(gè)人不清楚密碼,只通過輸入用戶名就能從數(shù)據(jù)庫中找到一條對應(yīng)的數(shù)據(jù)墨闲,那么這就稱為sql注入漏洞今妄。
簡單說:
通過表單或界面輸入一些SQL字符串,能到達(dá)服務(wù)器執(zhí)行,達(dá)到非法操作的目的.
正常的基本登錄流程代碼:?
sql注入代碼演示:
輸入用戶名
[if !supportLists]n?[endif]aaa’?or ‘1=1密碼隨意
[if !supportLists]n?[endif]aaa’?-- 密碼隨意??注意:--后面有空格
SQL環(huán)境演示:
SELECT * FROM USER WHERE username='aaa' AND PASSWORD='123'
SELECT * FROM USER WHERE username='aaa' OR '1=1' AND PASSWORD='wrwrw'
SELECT * FROM USER WHERE username='aaa'-- ' AND PASSWORD='wrwrw'
代碼參見:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java
[if !supportLists]1.15?[endif]15_JDBC的SQL注入漏洞分析及解決
[if !supportLists]??[endif]sql注入漏洞的原因是什么?
[if !supportLists]??[endif]如何解決sql注入的漏洞鸳碧?
[if !supportLists]1盾鳞、?[endif]原因:主要是用戶輸入了sql中規(guī)定的關(guān)鍵字,導(dǎo)致我們的sql語句的判斷條件發(fā)生了變化瞻离。
使用Statement對象來執(zhí)行一個(gè)sql語句是這樣的:
resultSet=statement.executeQuery("select * from user where username='"+username+"' and password='"+password+"';");
???我們把用戶輸入的內(nèi)容放到上面的sql語句對應(yīng)的變量處:
or前面的一部分判斷成立就能查到結(jié)果腾仅。
[if !supportLists]2、?[endif]解決sql注入的漏洞:使用PreparedStatement對象而不是Statement對象琐脏。
PreparedStatement有一個(gè)預(yù)編譯的過程攒砖,這個(gè)過程會固定sql語句的格式,對于變量要求是用日裙?來占位吹艇,那么傳遞過來的數(shù)據(jù)即使包含了sql關(guān)鍵字也不會當(dāng)做關(guān)鍵字來識別。
public?class?UserDao {
public?boolean?login(String username,String password){
Connection conn?= null;
PreparedStatement pstmt?= null;
ResultSet rs?= null;
//定義一個(gè)變量:
boolean?flag?= false;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL語句:
String sql = "select * from user where username = ? and password = ?";
//預(yù)編譯SQL
pstmt?= conn.prepareStatement(sql);
//設(shè)置參數(shù):
pstmt.setString(1, username);
pstmt.setString(2, password);
//執(zhí)行SQL語句:
rs?= pstmt.executeQuery();//無需傳入SQL
if(rs.next()){
//說明根據(jù)用戶名和密碼可以查詢到這條記錄
flag?= true;
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
return?flag;
}
代碼參見:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java
[if !supportLists]1.16?[endif]16_JDBC的CRUD操作之PreparedStatement保存操作(寫)
@Test
/**
*保存操作
?*/
public?void?demo1(){
Connection conn?= null;
PreparedStatement pstmt?= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL語句:
String sql = "insert into user values (null,?,?,?,?)";
//預(yù)編譯SQL:
pstmt?= conn.prepareStatement(sql);
//設(shè)置參數(shù):
pstmt.setString(1, "eee");
pstmt.setString(2, "abc");
pstmt.setString(3, "旺財(cái)");
pstmt.setInt(4, 32);
//執(zhí)行SQL
int?num?= pstmt.executeUpdate();//不傳SQL
if(num?> 0){
System.out.println("保存成功昂拂!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
[if !supportLists]1.17?[endif]17_JDBC的CRUD操作之PreparedStatement修改操作
@Test
/**
*修改操作
?*/
public?void?demo2(){
Connection conn?= null;
PreparedStatement pstmt = null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL語句:
String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";
//預(yù)編譯SQL:
pstmt?= conn.prepareStatement(sql);
//設(shè)置參數(shù):
pstmt.setString(1, "abc");//設(shè)置第一個(gè)?的值
pstmt.setString(2, "1234");
pstmt.setString(3, "旺旺");
pstmt.setInt(4, 23);
pstmt.setInt(5, 4);
//執(zhí)行SQL:
int?num?= pstmt.executeUpdate();
if(num?> 0){
System.out.println("修改成功受神!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
[if !supportLists]1.18?[endif]18_JDBC的CRUD操作之PreparedStatement刪除操作
@Test
/**
*刪除操作
?*/
public?void?demo3(){
Connection conn?= null;
PreparedStatement pstmt??= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL語句:
String sql = "delete from user where id = ?";
//預(yù)編譯SQL
pstmt?= conn.prepareStatement(sql);
//設(shè)置參數(shù):
pstmt.setInt(1, 4);
//執(zhí)行SQL:
int?num?= pstmt.executeUpdate();
if(num?> 0){
System.out.println("刪除成功!");
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
}
[if !supportLists]1.19?[endif]19_JDBC的CRUD操作之PreparedStatement查詢操作
@Test
/**
*查詢操作
?*/
public?void?demo4(){
Connection conn?= null;
PreparedStatement pstmt?= null;
ResultSet rs?= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL:
String sql = "select * from user";
//預(yù)編譯SQL:
pstmt?= conn.prepareStatement(sql);
//設(shè)置參數(shù):
//執(zhí)行SQL:
rs?= pstmt.executeQuery();
//遍歷結(jié)果集:
while(rs.next()){
System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("nickname"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(rs, pstmt, conn);
}
}
[if !supportLists]1.20?[endif]20_JDBC的批處理操作
批處理:一批SQL一起執(zhí)行
@Test
/**
*批處理基本操作
?*/
public?void?demo1(){
Connection conn?= null;
Statement stmt?= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//創(chuàng)建執(zhí)行批處理對象:
stmt?= conn.createStatement();
//編寫一批SQL語句:
String sql1?= "create database test1";
String sql2?= "use test1";
String sql3?= "create table user(id int primary key auto_increment,name varchar(20))";
String sql4?= "insert into user values (null,'aaa')";
String sql5?= "insert into user values (null,'bbb')";
String sql6?= "insert into user values (null,'ccc')";
String sql7?= "update user set name = 'mmm' where id = 2";
String sql8?= "delete from user where id = 1";
//添加到批處理
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);
stmt.addBatch(sql5);
stmt.addBatch(sql6);
stmt.addBatch(sql7);
stmt.addBatch(sql8);
//執(zhí)行批處理:
stmt.executeBatch();
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(stmt, conn);
}
}
批量插入(使用PreparedStatement)
@Test
/**
*批量插入記錄:
*需要在url后面拼接一個(gè)參數(shù)即可,效率高
??????????rewriteBatchedStatements=true
?*/
public?void?demo2(){
//記錄開始時(shí)間:
long?begin?= System.currentTimeMillis();
Connection conn?= null;
PreparedStatement pstmt?= null;
try{
//獲得連接:
conn?= JDBCUtils.getConnection();
//編寫SQL語句:
String sql?= "insert into user values (null,?)";
//預(yù)編譯SQL:
pstmt?= conn.prepareStatement(sql);
for(int?i=1;i<=10000;i++){
pstmt.setString(1, "name"+i);
//添加到批處理
pstmt.addBatch();
//注意問題:
//執(zhí)行批處理
if(i?% 1000 == 0){
//執(zhí)行批處理:
pstmt.executeBatch();
//清空批處理:
pstmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
JDBCUtils.release(pstmt, conn);
}
long?end?= System.currentTimeMillis();
System.out.println((end-begin));
}
1.21總結(jié):
闡述什么是JDBC以及為什么要使用JDBC
獨(dú)立完成使用JDBC核心API對數(shù)據(jù)庫表記錄的CRUD操作(重點(diǎn))
完成JDBC工具類的抽取與改進(jìn)(重點(diǎn))
闡述什么是SQL注入漏洞并給出解決方法
獨(dú)立完成使用JDBC的預(yù)編譯對象進(jìn)行CRUD操作(重點(diǎn))
JDBC的批處理操作