JDBC的入門與進階理解

J什麼是JDBC

Java Database Connectivity java數據庫連接

  • SUN公司提供的訪問數據庫規則、規範,由於數據庫種類較多,並且java語言使用比較廣泛,sun公司就提供了一種規範,讓其他的數據庫去實現底層的訪問規則。我們的java程序只要使用sun公司提供的jdbc驅動即可。

JDBC連接數據庫

package com.itheima.test;
​
import java.sql.*;
​
public class MainTest {
 public static void main (String[] args) throws ClassNotFoundException {
 Connection conn=null;
 Statement st=null;
 ResultSet rs=null;
 try {
 //1.註冊驅動
 //靜態代碼塊----》類加載了就會執行:java.sql.DriverManager.registerDriver(new Driver());
 //因此以下代碼,相當於註冊了兩次
 //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
 Class.forName("com.mysql.jdbc.Driver");//修改
 //2.建立連接 參數一:協議+訪問的數據庫,參數二:用戶名,參數三:密碼
 Connection conn= DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");
 //3.創建statement,跟數據庫打交道,一定需要這個對象
 Statement st = conn.createStatement();
 //4.執行查詢,得到結果集
 String sql="select * from mystudent";
 ResultSet rs=st.executeQuery(sql);
 //遍歷每一條記錄
 while(rs.next()) {
 int id=rs.getInt("id");
 String name=rs.getString("name");
 int age=rs.getInt("age");
 System.out.println("id="+id+"==name="+name+"==age="+age);
 
 }
 rs.close();
 st.close();
 conn.close();
 
 }catch(SQLException e) {
 e.printStackTrace();
 }
 
}
}

釋放資源改進:

另外建一個類,專門進行釋放工作:

public class JDBCutil {
 public static void release(Connection conn,Statement st,ResultSet rs) {
 closeRs(rs);
 closeSt(st);
 closeConn(conn);
 
 }
 
 private static void closeRs(ResultSet rs) {
 try {
 if(rs!=null)
 rs.close();
 }catch(SQLException e) {
 e.printStackTrace();
 
 }finally {
 rs=null;
 }
 }
 
 private static void closeSt(Statement st ) {
 try {
 if(st!=null)
 st.close();
 }catch(SQLException e) {
 e.printStackTrace();
 
 }finally {
 st=null;
 }
 }
 
 private static void closeConn(Connection conn) {
 try {
 if(conn!=null)
 conn.close();
 }catch(SQLException e) {
 e.printStackTrace();
 
 }finally {
 conn=null;
 }
 }
}

使用JDBC使用步驟

  1. 註冊驅動
  2. 建立連接
  3. 創建statement
  4. 執行sql,得到ResultSet
  5. 遍歷結果集
  6. 釋放資源

JDBC工具類構件

  1. 資源釋放工作的整合
  2. 驅動防二次註冊
//靜態代碼塊----》類加載了就會執行:java.sql.DriverManager.registerDriver(new Driver());
 //因此以下代碼,相當於註冊了兩次驅動
 //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
 Class.forName("com.mysql.jdbc.Driver");//修改

3.使用properties配置文件

一般情況下,我們不會在java類文件中寫

 static String url=jdbc:mysql://localhost/student
 static String name=root
 static String password=root

而是將它們單獨寫在資源文件中然後在使用時讀取文件,這樣我們只需要更改資源文件信息即可,不需要找到源java文件

//jdbc.properties
 driverClass=com.mysql.jdbc.Driver
 url=jdbc:mysql://localhost/student
 name=root
 password=root
 //JDBCutil.java
 static String driverClass=null; 
 static String url=null;
 static String name=null;
 static String password=null;
 static {
 try {
 //讀文件
 //1.創建一個屬性配置對象
 Properties properties=new Properties();
 //InputStream is=new FileInputStream("jdbc.properties");
 //使用類加載器讀取SRC底下的資源文件,後面在servlet 對應文件位於src目錄下
 InputStream is =JDBCutil.class.getClassLoader().getSystemResourceAsStream("jdbc.properties");
 //導入輸入流
 properties.load(is);
 //讀取屬性
 driverClass = properties.getProperty("driverClass");
 url= properties.getProperty("url");
 name = properties.getProperty("name");
 password = properties.getProperty("password");
 
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

步驟

  1. 在src底下聲明一個文件xxx.properties
  2. 在工具類裡面,使用靜態代碼塊,讀取屬性

使用單元測試代碼:

步驟

  1. 定義一個類,textxxx,裡面定義方法
  2. 添加junit 支持:右鍵工程》add Library》Junit》選擇版本
  3. 在方法上加上註解@Test,其實就是一個標記
@Test
public void testQuery(){
 ...
}
  1. 將光標點在需要測試的方法名上,然後右鍵Run
  2. 如果光條是綠色,表示代碼運行沒有錯誤

意義

對於不想講測試內容寫在main函數里,可以新建一個方法,講測試代碼放入執行。

即可以測試任何方法的正確性

:如果方法較多,我們可以批量Run,在outline窗口進行操作即可

java對數據庫的增刪改查

查詢:Query

public void textQuery() {
 Connection conn=null;
 Statement st=null;
 ResultSet rs=null;
 try {
 //查詢
 //1.獲取連接對象
 conn = JDBCUtil.getConn();
 //2.根據連接對象,得到statement
 st = conn.createStatement();
 //3.執行sql語句,返回resultset
 String sql = "select * from mystudent";
 rs=st.executeQuery(sql);
 
 //4.遍歷結果集
 while(rs.next()) {
 String sname=rs.getString("sname");;
 String sex=rs.getString("sex");;
 String specialty=rs.getString("specialty");
 String grade=rs.getString("grade");;
 System.out.println(sname+" "+sex+" "+specialty+" "+grade);
 }
 } catch (Exception e) {
 // TODO: handle exception
 e.printStackTrace();
 }finally {
​
 JDBCUtil.release(conn, st, rs);
 }
 }

增添:insert

public void textInsert() {
 Connection conn=null;
 Statement st=null;
 //ResultSet rs=null;
 try {
 //查詢
 //1.獲取連接對象
 conn = JDBCUtil.getConn();
 //2.根據連接對象,得到statement
 st = conn.createStatement();
 //3.執行添加
 String sql = "insert into mystudent values(6,'王明','男','計算機','大一')";
 //影響的行數,如果大於0表名操作成功,否則則失敗
 int result=st.executeUpdate(sql);
 if(result>0) {
 System.out.println("添加成功");
 }else {
 System.out.println("添加失敗");
 }
​
 } catch (Exception e) {
 // TODO: handle exception
 e.printStackTrace();
 }finally {
​
 JDBCUtil.release(conn, st);
 }
 }
​

刪除:delete

 String sql = "delete from mystudent where id=6";
 //影響的行數,如果大於0表名操作成功,否則則失敗
 int result=st.executeUpdate(sql);
 if(result>0) {
 System.out.println("刪除成功");
 }else {
 System.out.println("刪除失敗");
 }

更新:update

String sql = "update mystudent set grade='大二' where id=1";
 //影響的行數,如果大於0表名操作成功,否則則失敗
 int result=st.executeUpdate(sql);
 if(result>0) {
 System.out.println("更新成功");
 }else {
 System.out.println("更新失敗");
 }
​

JDBC Dao模式

  1. 新建一個dao的接口,裡面聲明數據庫訪問規則
  2. 新建一個dao的實現類,具體實現早前定義的規則
  3. 直接使用實現
package dao;
/**
 * 定義操作數據庫的方法
 * */
public interface UserDao {
 /**
 * 查詢所有
 * */
 void Query();//findAll;
 
}
-----------------------------------------------
package dao.impl;
​
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
​
import org.junit.jupiter.api.Test;
​
import dao.UserDao;
import util.JDBCUtil;
​
public class UserDaoImpl implements UserDao{
​
 @Override
 @Test
 public void Query() {
 Connection conn=null;
 Statement st=null;
 ResultSet rs=null;
 try {
 //1.獲取連接對象
 conn = JDBCUtil.getConn();
 //2.創建Statement對象
 st = conn.createStatement();
 //3.
 String sql = "select * from myuser";
 rs = st.executeQuery(sql);
 while(rs.next()) {
 int id=rs.getInt("id");
 String username=rs.getString("username");
 String password=rs.getString("password");
 System.out.println("id="+id+" username="+username+" password="+password);
 }
 
 } catch (Exception e) {
 e.printStackTrace();
 }finally {
​
 JDBCUtil.release(conn, st, rs);
 }
 }
​
}
--------------------------------------------------------------------------------
 package test;
​
import org.junit.Test;
​
import dao.UserDao;
import dao.impl.UserDaoImpl;
​
public class TestUserDaoImpl {
 @Test
 public void TestQuery() {
 UserDao dao=new UserDaoImpl();//接口引用對象
 dao.Query();
 }
}

statement安全問題

statement的執行,其實是拼接sql語句,然後再一起執行。

//前面先拼接sql語句,如果變量裡面帶有了數據庫的關鍵字,那麼一併認為是關鍵字,不認為是普通的字符串
String sql = "select * from myuser where username='"+username+"' and password='"+password+"'";
			rs = st.executeQuery(sql);
			if(rs.next()) {
				System.out.println("登錄成功");
			}else {
				System.out.println("登錄失敗");
			}
public void TestLogin() {
		UserDao dao=new UserDaoImpl();
		dao.login("admin", "10086'or'1=1");
//		SELECT * FROM myuser WHERE username="admin" AND PASSWORD="10088" OR 1=1;
	}

PrepareStatement

該對象就是替換前面的statement對象(預先對sql語句執行語法校驗)

String sql="select * from myuser where username=? and password=?";
//?對應的內容,後面不管傳遞什麼進來,都把它看成是字符串
			 PreparedStatement ps = conn.prepareStatement(sql);
			 //?對應的索引從1開始
			 ps.setString(1, username);
			 ps.setString(2, password);
			 
			 rs=ps.executeQuery();
			 if(rs.next()) {
				 System.out.println("登錄成功");
			 }else {
				 System.out.println("登錄失敗");
			 }

statement 給preparedstatement參數不報錯因為preparedstatement是statement 的子類(體現了多態性)

總結

  1. JDBC入門
  2. 抽取工具類
  3. statement CRUD
  4. Dao模式
  1. PreparedStatement CRUD

預處理sql語句,解決上面statement出現的問題

  1. dao裡面聲明crud,以及登錄方法

登錄方法:成功後返回該用戶的所有信息

查詢:如果是findAll返回一個集合

增加&刪除&更新

返回影響的行數即可 int類型


分享到:


相關文章: