您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java中JDBC怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
JDBC
Java DataBase Connectivity,java數據庫連接,為了降低操作數據的難度,java提供jdbc,按照java面向對象特點,對操作進行了很多封裝。
JDBC提供了很多接口,然后不同數據庫廠商去實現這個接口,到底底層如何去實現,不同的數據庫不一樣,不同的數據庫廠商需要提供接口實現類(驅動類、驅動程序 Driver、驅動)
我們連接不同的數據庫,我們只需要使用不同的驅動即可。
J:Java:提供訪問數據庫的規范(接口),
DBC:接口的實現,廠商去實現這個接口。
JDBC是一種用于執行SQL語句的java api.
版本號
1.1.1 Major. Minor. Build
Major:項目由架構、大規模的變化
Minor:有新功能的時候
Build:編譯版本
JDBC開發
Java程序使用第三方提供工具框架,都需要導入jar包
可以通過以下網址搜索找到mysql的相關jar包
https://mvnrepository.com/
下載好jar包后,在于src同級的目錄下,建立一個lib文件夾,添加jar包,并添加依賴
代碼實現
通過一個簡單的案例來實現JDBC的使用
import java.sql.*; public class Demo02 { public static void main(String[] args) throws ClassNotFoundException, SQLException { //1注冊驅動 Class.forName("com.mysql.jdbc.Driver"); //2建立連接 String url = "jdbc:mysql://localhost:3306/mydb01"; String usernName = "xxx"; //登錄數據庫的賬號 String password = "xxxx"; //登錄數據庫的密碼 Connection conn = DriverManager.getConnection(url, usernName, password); //3獲取執行sQL語句的對象 Statement statement = conn.createStatement(); //4獲取數據庫返回的結果 String sql = "delete from emp where empno = " +"7499"; String sqlUpdate = "update emp set sal = "+10000+" where empno = " +"7369"; String sqlInsert = "INSERT INTO emp VALUES(2018,\"boss\",\"king\",NULL,\"2018-8- 8\",15000,10000,10);"; //5處理數據集 int i = statement.executeUpdate(sql); int s = statement.executeUpdate(sqlUpdate); int ins = statement.executeUpdate(sqlInsert); System.out.println(i + "行受到影響----刪除"); System.out.println(s + "行受到影響----更新"); System.out.println(ins + "行受到影響----插入"); //6關閉連接 statement.close(); conn.close(); } }
使用JDBC的順序
(1)注冊數據庫驅動
(2)和數據庫建立連接
(3)獲取執行SQL語句的對象
(4)獲取數據庫返回的結果
(5)處理數據集(邏輯代碼)
(6)釋放資源,關閉連接
常用類
Connection
通過配置文件可以創建一個connect對象
Statement
通過connect對象獲取操作數據庫的Statement對象,
通過它來實現對數據庫增刪改查操作。
executeQuery():查,返回數據集
executeUpdate():增刪改,返回int的數據,影響的行數
ResultSet
數據集,可以理解就是一個集合。
取出數據:
通過下標:從1開始
通過字段名:SQL語句中select后面跟的字段,有可能和數據庫一樣,也可能不一樣
JDBC的優化
平時開發和項目上線之后使用的數據庫是不一樣的,不是同一個
這也就是我們說的,開發環境不一樣
開發環境不一樣,使用的數據庫也就不一樣,那么上面的數據庫中配置的三要素就要進行修改
而這種修改是人工操作的,人工操作就有存在了失誤,而修改之后的.java文件,也要重新編譯,這也可能出現錯誤
假設項目上線,需要以下四個步驟:
測試環境-->修改配置 -->重新編譯-->生產環境
如果想要避免上述出現的失誤的情況,就要繞開中間的兩個步驟
解決的方法就是,配置文件,添加配置文件,將要修改的配置信息存放到配置文件中,每次讀取信息從配置文件中讀取
而配置文件的位置是固定的,也不會重新編譯,這樣就可以降低風險
java中用IO流也可以讀取配置文件,通過一個專有的類Properties也可以讀寫配置文件
IO讀取配置文件
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.sql.*; import java.util.Properties; public class IoReadProp { public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException { //1注冊驅動 Class.forName("com.mysql.jdbc.Driver"); String[] para = read(); //2建立連接 String url = para[0]; String usernName = para[1]; String password = para[2]; Connection conn = DriverManager.getConnection(url,usernName,password); //3獲取執行sQL語句的對象 Statement statement = conn.createStatement(); //4獲取數據庫返回的結果 String sql = "select * from emp"; ResultSet resultSet = statement.executeQuery(sql); //5處理數據集 try { while (resultSet.next()){ //.getXXX方法中的參數 1,字段名 2.字段的下標 int empno = resultSet.getInt("empno"); String ename = resultSet.getString("ename"); String job = resultSet.getString(3); Date date = resultSet.getDate(5); System.out.println("empno:"+empno+", ename:"+ename+", job:"+job+", date:"+date); } } catch (Exception e){ e.printStackTrace(); } finally { //6關閉連接 resultSet.close(); statement.close(); conn.close(); } } public static String [] read()throws IOException { FileReader fr = new FileReader( "E:\\javalearning\\src\\jdbc\\jdbc.properties" ); //創建 寫入 緩沖區 BufferedReader bufferedReader = new BufferedReader( fr ); String [] str = new String[3]; for(int i =0 ;i < 3;i++){ str[i] = bufferedReader.readLine().split("=")[1].replace(";","").trim(); } bufferedReader.close(); fr.close(); return str; } }
Properties讀取配置文件
import java.io.*; import java.sql.*; import java.util.Iterator; import java.util.Properties; public class PropReadProp { public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException { //1注冊驅動 Class.forName("com.mysql.jdbc.Driver"); //用戶數組存放數據庫信息 String[] para = new String[3]; //讀取配置文件 int i = 0; Properties prop = new Properties(); FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties"); InputStream in = new BufferedInputStream(fileInputStream); prop.load(in); Iterator<String> it = prop.stringPropertyNames().iterator(); while (it.hasNext()) { para[i] = prop.getProperty(it.next()); i++; } in.close(); //2建立連接 String url = para[0]; String usernName = para[1]; String password = para[2]; Connection conn = DriverManager.getConnection(url, usernName, password); //3獲取執行sQL語句的對象 Statement statement = conn.createStatement(); //4獲取數據庫返回的結果 String sql = "select * from emp"; ResultSet resultSet = statement.executeQuery(sql); //5處理數據集 try { while (resultSet.next()) { //.getXXX方法中的參數 1,字段名 2.字段的下標 int empno = resultSet.getInt("empno"); String ename = resultSet.getString("ename"); String job = resultSet.getString(3); Date date = resultSet.getDate(5); System.out.println("empno:" + empno + ", ename:" + ename + ", job:" + job + ", date:" + date); } } catch (Exception e) { e.printStackTrace(); } finally { //6關閉連接 resultSet.close(); statement.close(); conn.close(); } } }
分層DAO
Data Access Object數據訪問對象是一個面向對象的數據庫接口
會建立一個包:dao,里面的類都是用來操作數據庫的。
通常情況下,有幾張表,就有幾個DAO
分層Entity、bean、pojo
實體,也就是一個一個類,該類里面只有屬性,和對應set.get方法
往往一個表一個實體,實體的屬性和表的字段有沒有關系,名字一般一樣,類型相對應
使用逆向工程,通過表導出實體。
Utils 工具類
代替我們去操作一系列的連接關閉等操作
案例:
目錄結構如下,
EmpDAO代碼如下:
package jdbc.dao; import jdbc.entity.Emp; import jdbc.utils.JDBCUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class EmpDAO { /** * 根據員工id獲取員工信息 */ public Emp getEmpById(Integer id){ Connection connection =null; Statement statement = null; ResultSet rs = null; Emp emp = null; try { connection = JDBCUtils.getConnection(); statement = connection.createStatement(); rs = statement.executeQuery("select * from emp where empno='"+id+"'"); while (rs.next()){ emp = new Emp(); int empno = rs.getInt("empno"); emp.setEmpno(empno); String ename = rs.getString("ename"); emp.setEname(ename); String job = rs.getString(3); emp.setJob(job); String hiredate = rs.getString(5); emp.setHiredate(hiredate); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(connection,statement,rs); } return emp; } public Emp getEmpById(String id){ Connection connection =null; Statement statement = null; ResultSet rs = null; Emp emp = null; try { connection = JDBCUtils.getConnection(); statement = connection.createStatement(); rs = statement.executeQuery("select * from emp where empno="+id); while (rs.next()){ emp = new Emp(); int empno = rs.getInt("empno"); emp.setEmpno(empno); String ename = rs.getString("ename"); emp.setEname(ename); String job = rs.getString(3); emp.setJob(job); String hiredate = rs.getString(5); emp.setHiredate(hiredate); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(connection,statement,rs); } return emp; } }
entity中的Emp代碼如下
package jdbc.entity; public class Emp { //emp表中的相關屬性 private Integer empno; private String ename; private String job; private String mgr; private String hiredate ; private double sal; private double comm; private Integer deptno; public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getMgr() { return mgr; } public void setMgr(String mgr) { this.mgr = mgr; } public String getHiredate() { return hiredate; } public void setHiredate(String hiredate) { this.hiredate = hiredate; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public double getComm() { return comm; } public void setComm(double comm) { this.comm = comm; } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } //默認輸出方法 @Override public String toString() { return "Emp{" + "empno=" + empno + ", ename='" + ename + '\'' + ", job='" + job + '\'' + ", mgr='" + mgr + '\'' + ", hiredate='" + hiredate + '\'' + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + '}'; } }
utils中的JDBCUtils代碼如下
package jdbc.utils; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Iterator; import java.util.Properties; public class JDBCUtils { private static final String URL ; private static final String USERNAME ; private static final String PASSWORD ; static{ String [] parp = null; try { parp = PropRead(); } catch (IOException e) { e.printStackTrace(); } URL = parp[0]; USERNAME = parp[1]; PASSWORD=parp[2]; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 創建連接 */ public static Connection getConnection() throws SQLException { Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); return conn; } public static void close(Connection co , Statement state, ResultSet rs){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(state !=null){ try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } if(co !=null){ try { co.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void close(Connection co , Statement state){ if(state !=null){ try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } if(co !=null){ try { co.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 讀取配置文件 * @return * @throws IOException */ public static String [] PropRead()throws IOException { String[] para = new String[3]; int i = 0; Properties prop = new Properties(); FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties"); InputStream in = new BufferedInputStream(fileInputStream); prop.load(in); Iterator<String> it = prop.stringPropertyNames().iterator(); while (it.hasNext()) { para[i] = prop.getProperty(it.next()); i++; } in.close(); return para; } }
測試代碼如下:
package jdbc; import jdbc.dao.EmpDAO; import jdbc.entity.Emp; import java.util.Scanner; public class Main { public static void main(String[] args) { EmpDAO empDAO = new EmpDAO(); System.out.println("請輸入ID"); Scanner scanner = new Scanner( System.in ); String value = scanner.nextLine(); Emp emp = empDAO.getEmpById (value); Emp emp1 = empDAO.getEmpById (7900); System.out.println(emp); System.out.println(emp1); } }
這樣就簡單實現了一個分層的使用JDBC的案例
SQL注入攻擊
根據上述案例,我們可以輸入一個員工的id來查找該員工
但是有一個問題,你如何去規定用戶的輸入,下面給大家看一個現象
我的數據庫在中并沒有123456789這個id的人,那么為什么還會有結果呢?
就是因為我們的sql語句是根據字符串拼接生成的,當你輸入的數據中包含sql關鍵字時,會被當成sql語句去執行
注意:這是很危險的!
不友好的用戶可以根據這個漏洞對你的數據庫進行修改,甚至刪除你的數據庫!
解決方法:PreparedStatement類
PreparedStatement是statement的子類
解決原理:
SQL語句不在拼接,而是通過預處理,也就是說,用戶輸入的任何內容,都只能作為值,不解析特殊字符。
修改之后打代碼如下:
public Emp getEmpById2(String id){ Connection connection =null; PreparedStatement statement = null; ResultSet rs = null; Emp emp = null; try { connection = JDBCUtils.getConnection(); String sql = "select * from emp where empno=?"; statement = connection.prepareStatement(sql); statement.setString(1,id); rs = statement.executeQuery(); while (rs.next()){ emp = new Emp(); int empno = rs.getInt("empno"); emp.setEmpno(empno); String ename = rs.getString("ename"); emp.setEname(ename); String job = rs.getString(3); emp.setJob(job); String hiredate = rs.getString(5); emp.setHiredate(hiredate); } } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(connection,statement,rs); } return emp; }
再次測試:結果如圖
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java中JDBC怎么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。