6.JDBC學(xué)習(xí)筆記

本文內(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說)

?PreparedStatement

管理事務(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的批處理操作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末格侯,一起剝皮案震驚了整個(gè)濱河市鼻听,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌联四,老刑警劉巖撑碴,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異朝墩,居然都是意外死亡醉拓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亿卤,“玉大人愤兵,你說我怎么就攤上這事∨盼猓” “怎么了秆乳?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钻哩。 經(jīng)常有香客問我屹堰,道長,這世上最難降的妖魔是什么街氢? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任双藕,我火速辦了婚禮,結(jié)果婚禮上阳仔,老公的妹妹穿的比我還像新娘。我一直安慰自己扣泊,他們只是感情好近范,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著延蟹,像睡著了一般评矩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阱飘,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天斥杜,我揣著相機(jī)與錄音,去河邊找鬼沥匈。 笑死蔗喂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的高帖。 我是一名探鬼主播缰儿,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼散址!你這毒婦竟也來了乖阵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤预麸,失蹤者是張志新(化名)和其女友劉穎瞪浸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吏祸,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡对蒲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片齐蔽。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡两疚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出含滴,到底是詐尸還是另有隱情诱渤,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布谈况,位于F島的核電站勺美,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碑韵。R本人自食惡果不足惜赡茸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祝闻。 院中可真熱鬧占卧,春花似錦、人聲如沸联喘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豁遭。三九已至叭喜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蓖谢,已是汗流浹背捂蕴。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闪幽,地道東北人啥辨。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像盯腌,于是被迫代替她去往敵國和親委可。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • JDBC簡介 SUN公司為了簡化腊嗡、統(tǒng)一對數(shù)據(jù)庫的操作着倾,定義了一套Java操作數(shù)據(jù)庫的規(guī)范,稱之為JDBC燕少。JDBC...
    奮斗的老王閱讀 1,518評論 0 51
  • JDBC概述 在Java中卡者,數(shù)據(jù)庫存取技術(shù)可分為如下幾類:JDBC直接訪問數(shù)據(jù)庫、JDO技術(shù)客们、第三方O/R工具崇决,如...
    usopp閱讀 3,534評論 3 75
  • jdbc學(xué)習(xí) 認(rèn)真的回顧一下jdbc材诽。鞏固一下知識。爭取用最通俗的話來解釋恒傻。 首先我們在編程中肯定是要用到數(shù)據(jù)庫的...
    沉醉000閱讀 256評論 0 0
  • 2017-6-12【能量世界1013】 桂林陽朔 陳艷霞 幼兒園放學(xué)后回到家脸侥,人極其的困倦,無力盈厘!能量雖然穩(wěn)定睁枕,想...
    陳艷霞小樹媽閱讀 255評論 0 0
  • 她踩著高跟鞋疾走,清晨還有微涼沸手,今天的天氣應(yīng)該很好外遇,這樣美好的念頭也是一閃而過,地鐵迎來高峰契吉,人流擁著她停不下腳步...
    蔣棲子閱讀 170評論 0 0