4.JDBC編程
阿新 • • 發佈:2018-07-16
黑窗口 values 接口 span etc prepare png 增加 col 01.JDBC_Java程序和MySQL的關系:
1).Java程序跟其它MySQL客戶端一樣,就是一個"客戶端",用於"封裝SQL語句"並發送給MySQL服務器,
MySQL服務器會直接返回結果給我們的程序。
(上面的命令行就是黑窗口,它與 SQLYog、JAVA程序一樣,同級)
02.JDBC_驅動的概念:
由數據庫廠商為每種編程語言提供的一個程序包。有兩種語言組成:前端:所面向的編程語言;後端:數據庫本身的語言。
它可以使各種編程語言直接訪問本語言,就可以訪問數據庫軟件,方便操作。
JDBC物理上由一組類和接口組成(通過工具類進行具體操作,JDBC接口實現類),隨JDK一起發放。
03.JDBC_JDBC的概念:
由SUN公司提出的Java連接數據庫的規範,它規範了Java連接各種數據庫所遵循的步驟和數據類型。它要求各數據庫廠商的驅動程序必須遵守這套規範,也需要Java程序員直接學習這套規範,這樣可以使得Java程序員訪問各種數據庫都使用同樣的步驟和數據類型。
04.JDBC_JDBC的四個核心類:
1).DriverManager(類) : 驅動管理器。 用於連接數據庫的"驅動程序",並通過驅動程序去連接數據庫軟件,向程序返回一個"連接通道(Connection對象)"。
2).Connection(接口) : "連接"對象。代表了程序和數據庫之間的一個"連接通道"。
3).Statement(接口) : SQL執行器。用於執行SQL語句。
4).ResultSet(接口) : 結果集。當Statement執行"查詢"語句時,會返回此對象。
05.JDBC_JDBC的開發步驟:
1).下載MySQL的Java驅動包,並復制到項目目錄下,並添加到構建路徑:
mysql-connector-java-5.1.37-bin.jar
2).開發步驟:
1.註冊驅動
2.獲取連接
3.獲取SQL執行器
4.執行SQL,並獲取結果集(查詢)
5.解析結果集
6.關閉資源
/*06.JDBC_關於Statement的常用方法: 1).public int executeUpdate(String sql):用於執行添加(insert)、修改(update)、刪除(delete)語句的。 返回值:int,影響的行數。 2).public ResultSet executeQuery(String sql):用於執行查詢(select) 返回值:ResultSet結果集。 註意:兩種不能混用。不能用executeUpdate()執行查詢語句,反之也不可以。 07.JDBC_關於ResultSet的使用: 1).ResultSet就類似於之前的"叠代器" 叠代器:while(it.hasNext()) { 結果集:while(rs.next()) { it.next(); rs.get數據類型(String 列名) } 或者 rs.get數據類型(int 列索引) 大招: rs.getObject(String 列名) rs.getObject(int 列索引) }* 1.註冊驅動 * 2.獲取連接 * 3.獲取SQL執行器 * 4.執行SQL,並獲取結果集(查詢) * 5.解析結果集 * 6.關閉資源 */ public class Demo { public static void main(String[] args) throws Exception { //1.註冊驅動 // 數據庫.jdbc.驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1", "root", "root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL,並獲取結果集(查詢) String sql = "select * from product"; ResultSet rs = stmt.executeQuery(sql); //5.解析結果集 while(rs.next()){ System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } //6.關閉資源 rs.close(); stmt.close(); conn.close(); } @Test public void delete() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "delete from product where pid = 6"; int row = stmt.executeUpdate(sql); System.out.println("刪除影響的行數:" + row); stmt.close(); conn.close(); } }
08.JDBC_使用JDBC實現增刪改查:
public class Demo {
@Test public void add() throws Exception{ //1.註冊驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL語句 String sql = "insert into product values(null,‘鋼琴‘,28000,1)"; int row = stmt.executeUpdate(sql); System.out.println("添加影響的行數:" + row); //5.釋放資源 stmt.close(); conn.close(); }
@Test public void update() throws Exception{ //1.註冊驅動 Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.獲取SQL執行器 Statement stmt = conn.createStatement(); //4.執行SQL String sql = "update product set price = 38000 where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("修改影響的行數:" + row); //5.釋放資源 stmt.close(); conn.close(); }
@Test public void delete() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "delete from product where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("刪除影響的行數:" + row); stmt.close(); conn.close(); } @Test public void findAll() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "select * from product"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } rs.close(); stmt.close(); conn.close(); } }
09.JDBC_JDBC工具類的制作:
public class JDBCUtils { //1.獲取Connection對象--代碼重用的目的 --靜態方法 public static Connection getConnection() throws Exception{ //前兩步 定義了一個靜態方法 Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); return conn; } //2.關閉資源 public static void closeAll(ResultSet rs,Statement stmt,Connection conn) throws SQLException{ if(rs != null){ rs.close(); } if(stmt != null){ stmt.close(); } if(conn != null){ conn.close(); } } }
升級版:
import導包; //定義一個數據庫工具類JdbcUtil,用來簡化數據庫操作出現的重復代碼。 //創建類JdbcUtil包含3個方法: //1) 可以把幾個字符串定義成常量 //2) public static Connection getConnection() 得到數據庫的連接 //3) 在靜態代碼塊中註冊驅動,只需註冊一次即可。無需放在getConnection()方法中 //4) public static void close(Connection conn,Statement stmt,ResultSet rs) 關閉所有打開的資源 //5)public static void close(Connection conn,Statement stmt) 關閉沒有結果集的資源,可以調用上面的方法。 public class JDBCUtils { private static String driver = "com.mysql.jdbc.Driver"; private static String url = "jdbc:mysql:///testdb2"; private static String user = "root"; private static String password = "root"; static{ try { Class.forName(driver); } catch (Exception e) { throw new RuntimeException(e) ; } } public static Connection getConnection() throws Exception{ Connection conn = DriverManager.getConnection(url, user, password); return conn; } public static void close(Connection conn,Statement stmt,ResultSet rs){ if (rs != null) { try { rs.close(); } catch (SQLException e) { } } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { } } } public static void close(Connection conn,Statement stmt){ if (stmt != null) { try { stmt.close(); } catch (SQLException e) { } } if (conn != null) { try { conn.close(); } catch (SQLException e) { } } } }
10.JDBC_SQL語句的封裝:
public class Demo { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); System.out.println("請輸入商品名稱:"); String pname = sc.next();//海爾冰櫃 System.out.println("價格:"); int price = sc.nextInt();//2300 System.out.println("類別ID:"); int cid = sc.nextInt();//1 //1.獲取連接對象 Connection conn = JDBCUtils.getConnection(); //2.獲取SQL執行器 Statement stmt = conn.createStatement(); //3.【封裝SQL語句】 //先想象,封裝後的SQL語句:"insert into product values(null,‘海爾冰櫃‘,2300,1)" String sql = "insert into product values(null,‘" + pname + "‘," + price + "," + cid + ")"; System.out.println(sql); //4.執行SQL語句 int row = stmt.executeUpdate(sql); System.out.println("添加影響的行數:" + row); //5.釋放資源 JDBCUtils.closeAll(null, stmt, conn); } }
11.JDBC_關於SQL註入的問題:
1).什麽是SQL註入:是指在用戶的數據中,包含了一些SQL的格式化符號,例如:)或者(或者,或者‘,如果程序接收後,不加以判斷直接封裝到SQL語句中會導致SQL語句的錯誤。這種現象就叫:SQL註入。 2).SQL註入的登錄演示:import 導包; public class Demo { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); System.out.println("請輸入登錄名:"); //sfasdfg String loginName = sc.nextLine(); System.out.println("輸入密碼:"); //asfsadf ‘ or ‘1=1 //(後者1=1 恒成立,顯示登錄成功,所以有bug) String loginPwd = sc.nextLine(); //1.獲取連接對象 Connection conn = JDBCUtils.getConnection(); Statement stmt = conn.createStatement(); String sql = "select * from users where uname = ‘" + loginName + "‘ and password = ‘" + loginPwd + "‘"; System.out.println(sql); ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ System.out.println("歡迎:" + loginName + " 登錄系統!"); }else{ System.out.println("用戶名或密碼錯誤!!"); } //2.釋放資源 JDBCUtils.closeAll(rs, stmt, conn); } }3).怎樣解決SQL註入的問題: 不用Statement,改用它的子接口:PreparedStatement--預處理的SQL執行器 PreparedStatement:它可以嚴格的區分出"SQL語句"和"數據",不會將數據中的SQL的格式化符號解析為SQL格式化符號,而認為就是數據。
12.JDBC_使用PreparedStatement解決SQL註入的問題:
Scanner sc = new Scanner(System.in); System.out.println("請輸入登錄名:"); String loginName = sc.nextLine(); System.out.println("輸入密碼:"); String loginPwd = sc.nextLine(); Connection conn = JDBCUtils.getConnection(); //1.先封裝SQL語句,數據部分要用?號占位,任何數據類型不需要單引號 String sql = "select * from users where uname = ? and password = ?"; //紅色 就是改過的區別 //2.獲取PreparedStatemet對象 PreparedStatement ps = conn.prepareStatement(sql); //3.填充數據 ps.setString(1, loginName); //這個1代表第一個?號 ps.setString(2, loginPwd); //這個2代表第二個?號 //4.執行 ResultSet rs = ps.executeQuery();//註意:不要再傳SQL語句了,因為之前已經有SQL語句了(ps中已傳入數據了) if(rs.next()){ System.out.println("歡迎:" + loginName + " 登錄系統!"); }else{ System.out.println("用戶名或密碼錯誤!!"); } //2.釋放資源 JDBCUtils.closeAll(rs, ps, conn);
13.JDBC_使用PreparedStatement完成增刪改查(CRUD)--(增刪改查之前一定要確定JDBCUtils工具類 中操作的表格是否在該數據庫下)
public void add() throws Exception{ //1.獲取連接對象 Connection conn = JDBCUtils.getConnection(); //2.獲取預處理對象 String sql = "insert into product values(null,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); //3.填充數據 ps.setString(1, "奔馳"); ps.setInt(2, 440000); ps.setInt(3, 1); //4.執行SQL int row = ps.executeUpdate(); System.out.println("添加影響的行數:" + row); //5.釋放資源 JDBCUtils.closeAll(null, ps, conn); //記得,別忘了關閉資源 } public void update() throws Exception{ //1.獲取連接對象 Connection conn = JDBCUtils.getConnection(); //2.獲取預處理對象 String sql = "update product set pname = ? , price = ? where pid = ?"; //所以的數據都 用? 替換掉(set在表名後) PreparedStatement ps = conn.prepareStatement(sql); //3.填充數據 ps.setString(1, "奔馳E級"); ps.setInt(2, 420000); ps.setInt(3, 9); //4.執行SQL int row = ps.executeUpdate(); System.out.println("修改影響的行數:" + row); //5.釋放資源 JDBCUtils.closeAll(null, ps, conn); } public void delete() throws Exception{ Connection conn = JDBCUtils.getConnection(); String sql = "delete from product where pid = ?"; //刪除沒有 * 號,切記 PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 9); int row = ps.executeUpdate(); System.out.println("刪除影響的行數:" + row); JDBCUtils.closeAll(null, ps, conn); } public void findAll() throws Exception{ //查找所有 ,不需要填充數據 Connection conn = JDBCUtils.getConnection(); String sql = "select * from product"; PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()){ //查詢所有用 while System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } JDBCUtils.closeAll(rs, ps, conn); } @Test public void findById() throws Exception{ Connection conn = JDBCUtils.getConnection(); String sql = "select * from product where pid = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 1); ResultSet rs = ps.executeQuery(); if(rs.next()){ //切記查找一個,需要用if System.out.println(rs.getInt("pid") + "\t" + rs.getString("pname") + "\t" + rs.getInt("price") + "\t" + rs.getInt("cid")); } JDBCUtils.closeAll(rs, ps, conn); }註意點: 查詢所有用while;查詢某個用if. 而且封裝的對象或集合 要放在while或if判斷語句內! 查詢,格式: String sql = "select name, sal from emp where name like ?" String sql = "select * from emp where id = ?"; 刪除,格式: String sql = "delete from emp where id = ?"; 修改,格式: String sql = "update emp set sal = ? where id = ? "; 增加,格式: String sql = "insert into product values(null,?,?,?)";
4.JDBC編程