JavaWeb——JDBC

cool_cool_coo1發表於2019-01-14

1.JDBC:

Java DataBase Connectivity  可以為多種關係型資料庫DBMS 提供統一的訪問方式,用Java來運算元據庫

2.JDBC API 主要功能:

三件事,具體是通過以下類/介面實現:

  • DriverManager : 管理jdbc驅動
  • Connection: 連線(通過DriverManager產生)
  • Statement(PreparedStatement) :增刪改查  (通過Connection產生 )
  • CallableStatement  : 呼叫資料庫中的 儲存過程/儲存函式  (通過Connection產生 )
  • Result :返回的結果集  (上面的Statement等產生 )

Connection產生運算元據庫的物件:

 

  • Connection產生Statement物件:createStatement()
  • Connection產生PreparedStatement物件:prepareStatement()
  • Connection產生CallableStatement物件:prepareCall();

Statement運算元據庫:

增刪改:executeUpdate()
查詢:executeQuery();

ResultSet儲存結果集 :

select * from xxx
next():游標下移,判斷是否有下一條資料;true/false
previous():  true/false
getXxx(欄位名|位置):獲取具體的欄位值 

PreparedStatement運算元據庫:

public interface PreparedStatement extends Statement 
因此
增刪改:executeUpdate()
查詢:executeQuery();
--此外
賦值操作 setXxx();


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import java.sql.PreparedStatement;

public class JDBCPreparedStatementDemo {
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "scott";
	private static final String PWD = "tiger";

	public static void update() {// 增刪改
		Connection connection = null;
		PreparedStatement  pstmt = null;
		try {
			// a.匯入驅動,載入具體的驅動類
			Class.forName("oracle.jdbc.OracleDriver");// 載入具體的驅動類
			// b.與資料庫建立連線
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			
			/* Statement
			// c.傳送sql,執行(增刪改、查)
			stmt = connection.createStatement();
			//String sql = "insert into student values(1,'zs',23,'s1')";
//			String sql = "update student set STUNAME='ls' where stuno=1";
			String sql = "delete from student where stuno=1";
			// 執行SQL
			int count = stmt.executeUpdate(sql); // 返回值表示 增刪改 幾條資料
			*/
			//PreparedStatement
			String sql = "insert into student values(?,?,?,?)";
			pstmt = connection.prepareStatement(sql);//預編譯
			pstmt.setInt(1, 36);
			pstmt.setString(2, "zhangsan");
			pstmt.setInt(3, 56);
			pstmt.setString(4, "s3");
			
			int count =pstmt.executeUpdate() ;
			
			// d.處理結果
			if (count > 0) {  
				System.out.println("操作成功!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(pstmt!=null) pstmt.close();// 物件.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public static void query() {
		Connection connection = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null ; 
		try {
			// a.匯入驅動,載入具體的驅動類
			Class.forName("oracle.jdbc.OracleDriver");// 載入具體的驅動類
			// b.與資料庫建立連線
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			// c.傳送sql,執行(增刪改、【查】)
			Scanner input= new Scanner(System.in);
			System.out.println("請輸入使用者名稱:");
			String name = input.nextLine() ;
			System.out.println("請輸入密碼:");
			String pwd = input.nextLine() ;
		
//			String sql = "select * from student where stuname like '%"+name+"%'";
//			String sql = "select * from student where stuname like ?";
			String sql ="select count(*) from login where uname= ? and upwd =?"; 
			pstmt = connection.prepareStatement(sql) ;
			pstmt.setString(1, name);
			pstmt.setString(2, pwd);
			
//			String sql = "select stuno,stuname from student";
					// 執行SQL(增刪改executeUpdate(),查詢executeQuery())
			rs = pstmt.executeQuery(); // 返回值表示 增刪改 幾條資料
			// d.處理結果
//			while(rs.next()) {
//				int sno = rs.getInt( "stuno") ;
//				String sname = rs.getString("stuname") ;
////				int sno = rs.getInt(1) ; //下標:從1開始計數
////				String sname = rs.getString(2) ;
//				System.out.println(sno+"--"+sname);
//			}
			int count = -1;
			if(rs.next()) {
				count = rs.getInt(1) ;
			}
			if(count>0) {
				System.out.println("登陸成功!");
			}else {
				System.out.println("登陸失敗!");
			}

		} catch (ClassNotFoundException e) {
			System.out.println("111");
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				if(rs!=null) rs.close(); 
				 if(pstmt!=null) pstmt.close();// 物件.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public static void main(String[] args) {
//		update() ;
		query() ;
	}
}

PreparedStatement與Statement在使用時的區別:


1.Statement:
先寫sql
再執行executeUpdate(sql)

2.PreparedStatement:
sql(可能存在佔位符?)
在建立PreparedStatement 物件時,將sql預編譯 prepareStatement(sql)
executeUpdate()
setXxx()替換佔位符?

String sql ="select count(*) from login where uname= ? and upwd =?"; 
			pstmt = connection.prepareStatement(sql) ;
			pstmt.setString(1, name);
			pstmt.setString(2, pwd);

推薦使用PreparedStatement:原因如下:1、2、3

1.編碼更加簡便(避免了字串的拼接
要增加:String name = "zs" ; int age = 23 ;

stmt:

String sql =" insert into student(stuno,stuname) values('"+name+"',  "+age+" )    " ;
stmt.executeUpdate(sql);

pstmt:

String sql =" insert into student(stuno,stuname) values(?,?) " ;
pstmt = connection.prepareStatement(sql);//預編譯SQL
pstmt.setString(1,name);
pstmt.setInt(2,age);
stmt.executeUpdate();//無參


2.提高效能(因為 有預編譯操作,預編譯只需要執行一次)
需要重複增加100條數 
stmt:

String sql =" insert into student(stuno,stuname) values('"+name+"',  "+age+" )    " ;
for(100)
stmt.executeUpdate(sql);

pstmt:

String sql =" insert into student(stuno,stuname) values(?,?) " ;
pstmt = connection.prepareStatement(sql);//預編譯SQL
pstmt.setString(1,name);
pstmt.setInt(2,age);
for( 100){
pstmt.executeUpdate();
}

3.安全(可以有效防止sql注入)
sql注入: 將客戶輸入的內容  和 開發人員的SQL語句 混為一體

stmt:存在被sql注入的風險  
(例如輸入  使用者名稱:任意值 ' or 1=1 --密碼:任意值)
分析:
select count(*) from login where uname='任意值 ' or 1=1 --' and upwd ='任意值'  ;             永遠為TURE(輸入的東西與sql語句衝突)
select count(*) from login where uname='任意值 ' or 1=1 ;                                                     永遠為TURE(輸入的東西與sql語句衝突)
select count(*) from login ;


select count(*) from login where uname='"+name+"' and upwd ='"+pwd+"' 

pstmt:有效防止sql注入


推薦使用pstmt

3.jdbc訪問資料庫的具體步驟:

  • a.匯入驅動,載入具體的驅動類
  • b.與資料庫建立連線
  • c.傳送sql,執行
  • d.處理結果集 (查詢)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCDemo {
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "MANAGER";
	private static final String PWD = "manager";

	public static void update() {// 增刪改
		Connection connection = null;
		Statement stmt = null;
		try {
			// a.匯入驅動,載入具體的驅動類
			Class.forName("oracle.jdbc.OracleDriver");// 載入具體的驅動類
			// b.與資料庫建立連線
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			// c.傳送sql,執行(增刪改、查)
			stmt = connection.createStatement();
			String sql = "insert into table_user values('zs','s1')";
			//String sql = "update table_user set STUNAME='ls' where stuno=1";
			//String sql = "delete from table_user where stuno=1";
			// 執行SQL
			int count = stmt.executeUpdate(sql); // 返回值表示 增刪改 幾條資料
			// d.處理結果
			if (count > 0) {  
				System.out.println("操作成功!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				 if(stmt!=null) stmt.close();// 物件.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public static void query() {
		Connection connection = null;
		Statement stmt = null;
		ResultSet rs = null ; 
		try {
			// a.匯入驅動,載入具體的驅動類
			Class.forName("oracle.jdbc.OracleDriver");// 載入具體的驅動類
			// b.與資料庫建立連線
			connection = DriverManager.getConnection(URL, USERNAME, PWD);
			// c.傳送sql,執行(增刪改、【查】)
			stmt = connection.createStatement();
//			String sql = "select stuno,stuname from student";
			Scanner input= new Scanner(System.in);
			System.out.println("請輸入使用者名稱:");
			String name = input.nextLine() ;
			System.out.println("請輸入密碼:");
			String pwd = input.nextLine() ;
			String sql = "select count(*) from login where uname='"+name+"' and upwd ='"+pwd+"' " ;
//			String sql = "select * from student where stuname like '%"+name+"%'";
			// 執行SQL(增刪改executeUpdate(),查詢executeQuery())
			rs = stmt.executeQuery(sql); // 返回值表示 增刪改 幾條資料
			// d.處理結果
			int count = -1;
			if(rs.next()) {
				count = rs.getInt(1) ;
			}
			if(count>0) {
				System.out.println("登陸成功!");
			}else {
				System.out.println("登陸失敗!");
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				if(rs!=null) rs.close(); 
				 if(stmt!=null) stmt.close();// 物件.方法
				 if(connection!=null)connection.close();
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	public static void main(String[] args) {
	update() ;
//		query() ;
	}
}

4.資料庫驅動

   驅動jar     具體驅動類   連線字串
Oracle       ojdbc-x.jar  oracle.jdbc.OracleDriver  jdbc:oracle:thin:@localhost:1521:ORCL
MySQL  mysql-connector-java-x.jar  com.mysql.jdbc.Driver   jdbc:mysql://localhost:3306/資料庫例項名
SqlServer   sqljdbc-x.jar  com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:microsoft:sqlserver:localhost:1433;databasename=資料庫例項名

使用jdbc運算元據庫時,如果對資料庫進行了更換,只需要替換:驅動、具體驅動類、連線字串、使用者名稱、密碼