JAVA--高級基礎開發JDBC

Day03【JDBC】

 第一章JDBC

1.1  JDBC概述

  1. JDBC((Java DataBase Connectivity 數據庫鏈接)是java操做數據庫的標準解決方案,是一種執行SQL 語句的java Api, JDBC 是java訪問數據庫的標準規範,能夠爲不一樣的關係型數據庫提供統一的訪問,它由一組java語言 編寫的接口和類組成。
  2. JDBC 須要鏈接驅動,驅動是兩個設備之間進行通訊的,知足必定數據通訊格式,數據格式由設備提供商規定,設備提供商爲設備提供驅動軟件,經過軟件就能夠與設備進行通訊,咱們以MYSQL爲主,因此須要下載mysql 的驅動程序。
  3. C:\Program Files (x86)\MySQL\Connector J 8.0\mysql-connector-java-8.0.12.jar
  4. Jar 包就是Java 程序最終生成的文件格式。
  5. JDBC規範掌握四個核心對象
  • DriverManager:用於註冊驅動。
  • Connection:表示與數據庫建立的鏈接。
  • Statement:操做數據庫SQL語句的對象。
  • ResultSet:結果集對象

1.2  JDBC原理

  1. Java提供訪問數據庫規範,而生產廠商提供規範的實現類稱爲驅動。
  2. Jdbc是接口,驅動是接口的實現,沒有驅動將沒法完成數據庫的鏈接,從而就不能操做數據庫鏈接,每一個數據庫廠商都須要提供本身的驅動,用來鏈接本身公司的數據庫,也就是說驅動通常使用數據庫廠商提供的。
  3. 入門示例:和API講解。
      1. 準備數據

第一步:以分類表爲例:java

create table category(mysql

cid int primary key auto_increment,sql

cname varchar(20)數據庫

);安全

1.2.2 導入驅動Jar架包

1.在工程中建立lib目錄,存放MYSQL的驅動包。ide

2.選擇MYSQL驅動包,右鍵選擇Add  as Libray 完成Jar包的導入。工具

3.開發的步驟:this

  • 註冊驅動
  • 得到鏈接對象
  • 得到執行SQL語句的對象
  • 執行SQL語句,並返回結果
  • 處理結果
  • 釋放資源

1.2.3  API詳解 註冊驅動

爲何要註冊驅動??url

  1. 就是爲了可以讓java程序和目標數據庫進行交互。

方式一:spa

DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());

通常狀況下,咱們不建議使用這種方式:緣由有兩個: 1是由於致使驅動被註冊兩次。2是強烈依賴數據庫的驅動Jar包。

解決方案:

Class.forName(「 com.mysql.cj.jdbc.Driver」);

1.2.4  API詳解 得到鏈接

  • 須要提供數據庫的URL
  • user  用戶名
  • password 密碼

    URL 的語法規則:

    Jdbc:數據庫名稱://地址:端口號/數據庫名

    Mysql的URL: 示例:

    Jdbc: mysql://localhost:3306/數據庫名稱
  • DriverMannger 驅動管理,提供了一個靜態的方法:
  • static Connection getConnection(String  url,String user,String password); 就能夠根據提供的鏈接參數獲的一個鏈接對象。

private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy";

        user="root";

        password="105104";

}

  // 得到數據庫的鏈接對象 Connection

 Connection  meth=DriverManager.getConnection(url,user,password);

1.2.4 API詳解 獲取Statement對象

  1. Statement 是用來執行SQL語句的,經過Connection對象中的createStatement()方法就能夠獲取對象,返回的就是一個Statement對象。
  2. Statement中經常使用的方法:
  • Int  exeuteUpdate(String sql):是用來執行 insert、update、delete語句的,返回值爲int類型,表示的是影響的行數。
  • ResultSet  executeQuery(String  sql):是用來執行select語句的。主要是查詢。      

1.2.5 處理結果集

ResultSet實際上就是一張二維的表格, 咱們能夠調用boolean next()方法指向某行記錄,當第一次調用next()方法時,使指向第一行記錄的位置。這時就可使用ResultSet提供的getXxx(String str),方法說明:Xxx表示的是數據類型,參數表示的列名;getXxx(int index),Xxx表示數據類型,參數表示列的索引(這裏的索引是從1開始的)。

1.2.5 API詳解,釋放資源

  1. 與IO流同樣,使用後的東西都須要關閉,關閉的順序是先獲得的後關閉,後獲得的先關閉。
  2. Set.close(); State.close(); Con.close():

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

//建立表

public class JDBCdemo1 {

    private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&characterEnconding=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  meth=null;

        Statement  state=null;

        try{

            //1 加載驅動

            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2 得到數據庫的鏈接對象 Connection

              meth=DriverManager.getConnection(url,user,password);

            if(meth!=null){

                System.out.println("鏈接成功");

            }else{

                System.out.println("鏈接失敗");

            }

            // 3 獲取Statement執行SQL語句的對象

             state=meth.createStatement();

            //4準備SQL語句

            String sql="create  table student(id int primary key auto_increment," +

                    "name  varchar(32) not null,gender varchar(32) not null,birthday date)";

            // 5 執行SQL(DDL沒有返回結果)

            int  i=state.executeUpdate(sql);

            System.out.println("表建立成功");

        }catch(ClassNotFoundException  ce){

            ce.printStackTrace();

        }catch(SQLException  ce){

            ce.printStackTrace();

        }finally {

             try{

                 if(state!=null){

                     state.close();

                 }

             }catch (SQLException  ce){

                 ce.printStackTrace();

             }

            try{

                if(meth!=null){

                    meth.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

 

    }

}

package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//添加表信息

public class JDBCdemo2 {

    private static String url;

    private static String user;

    private static String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&characterEnconding=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args){

        Connection meth=null;

        Statement state=null;

        try{

//            //1 加載驅動

//            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2 得到數據庫的鏈接對象 Connection

            meth= DriverManager.getConnection(url,user,password);

            if(meth!=null){

                System.out.println("鏈接成功");

            }else{

                System.out.println("鏈接失敗");

            }

            // 3 獲取Statement執行SQL語句的對象

            state=meth.createStatement();

            //4準備SQL語句

 

            String  sql1="insert  into student(name,gender,birthday)values('李文傑','男','1996-01-05')";

            String  sql2="insert  into student(name,gender,birthday)values('陳天意','男','1997-01-05')";

            String  sql3="insert  into student(name,gender,birthday)values('郭朝旭','男','1993-01-05')";

            String  sql4="insert  into student(name,gender,birthday)values('桑鳳嬌','女','1998-01-05')";

            String  sql5="insert  into student(name,gender,birthday)values('星仔','男','1998-01-05')";

 

            //執行SQL語句

            state.executeUpdate(sql1);

            state.executeUpdate(sql2);

            state.executeUpdate(sql3);

            state.executeUpdate(sql4);

            state.executeUpdate(sql5);

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            //釋放資源

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(meth!=null){

                    meth.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

    }

}

import java.sql.*;

//查詢表中的信息

public class JDBCdemo3 {

    private static String url;

    private static String user;

    private static String password;

    static{

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args){

        Connection  con=null;

        Statement   state=null;

       try{

           // 2 得到數據庫的鏈接對象 Connection

         con=DriverManager.getConnection(url,user,password);

         //3 獲的StateMent執行SQL語句的對象

           state=con.createStatement();

 

         //4 準備SQL 語句

         String  sql="select *  from  student ";

         //5 執行SQL

           ResultSet  set=state.executeQuery(sql);

           while (set.next()){

           //獲取數據

               System.out.println("id"+set.getInt("id"));

               System.out.println("name"+set.getString("name"));

               System.out.println("gender"+set.getString("gender"));

               System.out.println("birthday"+set.getDate("birthday"));

           }

           set.close();

       }catch(SQLException  ce){

           ce.printStackTrace();

       }finally {

 

           try{

               if(state!=null){

                   state.close();

               }

           }catch (SQLException  ce){

               ce.printStackTrace();

           }

           try{

               if(con!=null){

                   con.close();

               }

           }catch (SQLException  ce){

               ce.printStackTrace();

           }

 

       }

    }

} package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//修改表中的信息

public class JDBCdemo4 {

    private  static  String url;

    private  static  String user;

    private  static  String password;

    static {

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  con=null;

        Statement  state=null;

 

        try{

            //1 獲取數據庫的鏈接對象

            con=DriverManager.getConnection(url,user,password);

            //2 獲取Statement執行數據庫語句的對象

            state=con.createStatement();

            // 3準備SQL 語句

            String sql="update student set name='李傑傑',gender='男生' where id=1";

            //4 執行SQL語句

            int i=state.executeUpdate(sql);

            if(i>0){

                System.out.println("修改爲功");

            }else{

                System.out.println("修改失敗");

            }

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(con!=null){

                    con.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

 

    }

}

package day01;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

//JDBC之刪除

public class JDBCdemo5 {

    private  static  String url;

    private  static  String user;

    private  static  String password;

    static{

        url="jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8";

        user="root";

        password="105104";

    }

    public static void main(String[] args) {

        Connection  con=null;

        Statement  state=null;

        try{

            // 1. 獲取數據庫的鏈接對象

            con= DriverManager.getConnection(url,user,password);

            // 2. 獲取Statement 執行數據庫的SQL語句

            state=con.createStatement();

            // 3. 準備SQL語句

            String sql="delete  from  student";

            // 4.執行SQL語句

            int i=state.executeUpdate(sql);

            if(i>0){

                System.out.println("刪除成功");

            }else{

                System.out.println("刪除失敗");

            }

        }catch (SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                if(state!=null){

                    state.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

            try{

                if(con!=null){

                    con.close();

                }

            }catch (SQLException  ce){

                ce.printStackTrace();

            }

        }

    }

}

1.3  JDBC工具類

獲取的數據庫鏈接、關閉數據庫相應的對象釋放資源,這些操做在任何的增、刪、改、查中都會用到,因此以上寫的代碼,增、刪、改、查方法中存在着大量的重複性代碼。爲了提升代碼的可重用性,咱們能夠將重複代碼封裝成一個工具類JdbcUtils。

  • 數據庫鏈接參數封裝
  • 在src根目錄下,新建立一個jdbc.properties

driverClass=com.mysql.cj.jdbc.Driver

url=jdbc:mysql://localhost:3306/ab_wzy?serverTimezone=UTC&character=utf8

user=root

password=105104

//封裝JDBC工具包

import java.io.IOException;

import java.io.InputStream;

import java.sql.*;

import java.util.Properties;

public class JdbcUtils {

    private  static String  url;

    private  static String  user;

    private  static String password;

    private  static Properties P;

    static {

        P=new Properties();

        //讀取屬性文件

        InputStream  input=Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");

        //加載P對象

        try{

            P.load(input);

        }catch(IOException  ce){

            ce.printStackTrace();

        }

 

        //根據鍵獲取值

       url=P.getProperty("url");

       user=P.getProperty("user");

       password=P.getProperty("password");

    }

 

    //獲取數據庫鏈接對象

    public  static Connection  getConnection()throws SQLException {

        Connection con= DriverManager.getConnection(url,user,password);

        return con;

    }

    //關閉數據庫鏈接對象之insert  delete update的操做

    public static  void  close(Connection  con, Statement state)throws SQLException{

        con.close();;

        state.close();

    }

    //關閉數據庫鏈接的對象之 select 查找查詢的操做

    public static  void close(Connection  con, Statement  state, ResultSet  set)throws SQLException{

         set.close();

         state.close();

         con.close();

    }

    //關閉獲取數據庫鏈接對象

    public  static  void  close(Connection  con)throws SQLException{

        con.close();

    }

    // 關閉執行Statement執行SQL 語句的對象

    public static  void close(Statement  state)throws SQLException{

        state.close();

    }

    //關閉結果集對象ResultSet對象

    public static  void close(ResultSet  set)throws SQLException{

        set.close();

    }

}

1.4 綜合實例,用戶登陸

  1. 新建立一張用戶表

create table user(

id int primary key auto_increment,

name varchar(32),

password varchar(50)

);

  1. 實現登陸

 

//案例:用戶登陸

public class jdbc_demo1 {

    public static void main(String[] args) {

        Scanner  input=new Scanner(System.in);

        System.out.println("請輸入用戶名");

        String  name=input.nextLine();

        System.out.println("請輸入密碼");

        String  password=input.nextLine();

        Login(name,password);

    }

    // 用戶登陸的方法

    public  static  void Login(String name,String  password){

        Connection  con=null;

        Statement  state=null;

        ResultSet  set=null;

        //經過工具類來獲取鏈接對象

        try{

            con= JdbcUtils.getConnection();

            //獲取Statement執行SQL語句的對象

            state=con.createStatement();

            //準備登陸的SQL語句。登陸就是從數據庫表中查詢數據

            String  sql="select  * from user  where name='"+name+"'and password='"+password+"'";

            // 執行SQL語句

            set=state.executeQuery(sql);

            if(set.next()){

                System.out.println("登陸成功,歡迎"+name);

            }else{

                System.out.println("登陸失敗");

            }

        }catch(SQLException ce){

            ce.printStackTrace();

        }finally {

            try{

                JdbcUtils.close(con,state,set);

            }catch(SQLException  ce){

                ce.printStackTrace();

            }

 

        }

    }

}

  1. SQL 注入的問題

1  select * from user where name='haha' and password='a' or '1'='1'

2  name=’haha’ and password=’a’ 結果是 false

3  or ‘1’=’1’ 永遠成立。True

至關於select * from user where true;

  • 咱們讓用戶輸入的密碼和 SQL 語句進行字符串拼接,用戶輸入的內容做爲了 SQL 語句語法的一部分,改變了原有 SQL 真正的含義,以上問題稱爲 SQL 注入。要解決 SQL 注入就不能讓用戶輸入的密碼和咱們的 SQL 語句進行簡單的字符串拼接。

1.5  PreparedStatement接口

  1. PreparedStatement 是 Statement 接口的子接口,繼承了父接口中的全部方法,它是一個預編譯的 SQL 語句。
  • PreparedStatement 的執行原理:
  • Statement 對象執行一條 SQL 語句都會先獲得 SQL 語句發送給數據庫,數據庫在進行編譯和執行;若是有 1 萬條 SQL 語句,數據庫須要編譯 1 萬次,執行 1 萬次,效率低。
  • PreparedStatement 會先將 SQL 語句發送給數據庫預編譯,PreparedStatement 會引用預編譯後的結果,能夠屢次傳入不一樣的參數給 PreparedSatement 對象執行。若是有 1 萬條插入語句,數據庫只須要編譯一次,傳入 1 萬次不一樣的參數並執行,減小了 SQL 語句編譯的次數,提供了執行效率。
  • 由於有預先編譯的功能,提升 SQL 的執行效率
  • 能夠有效的防止 SQL 注入的問題,安全性更高。

1.6  Connection 建立 PreparedSatement 對象

  • 方法: PreparedStatement  preareStatement(sql); 指定預編譯的 SQL 語句,SQL 語句中使用佔位符?表示參數,建立一個語句對象。

1.7  PreparedStatement 接口中的方法

  • int executeUpdate(); 執行 DML 語句,也就是insert、delete、update。
  • ResultSet executeQuery();執行DQL語句.用來查詢select的語句。

1.8  PreparedStatement 的做用

  1. preareStatement()會先將 SQL 語句發送給數據庫預編譯,PreparedStatement 會引用預編譯後的結果,能夠屢次傳入不一樣的參數給 PreparedStatement 對象並執行,減小 SQL 編譯次數,提升效率。
  2. 安全性更高,沒有 SQL 注入的隱患
  3. 提升了程序的可讀性

package day03;

 

import day02.JdbcUtils;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.Scanner;

 

//使用reparedStatement接口是Statement的子接口

public class jdbc_demo2 {

    public static void main(String[] args) {

        Scanner input=new Scanner(System.in);

        System.out.println("請輸入用戶名");

        String  name=input.nextLine();

        System.out.println("請輸入密碼");

        String  password=input.nextLine();

        Login(name,password);

    }

    //定義用戶登陸的方法

    public static  void  Login(String  name,String password){

        Connection con=null;

        PreparedStatement  statement=null;

        ResultSet set=null;

        try{

            //根據工具包獲取鏈接對象

            con= JdbcUtils.getConnection();

            //準備登陸的SQL語句

            String  sql="select *  from user where name=? and password=?";

            //獲取PreparedStatement執行的SQL語句的對象

            statement=con.prepareStatement(sql);

            //給佔位符賦值

            statement.setString(1,name);

            statement.setString(2,password);

            //執行SQL語句

            set=statement.executeQuery();

            if(set.next()){

                System.out.println("登陸成功,歡迎"+name);

            }else{

                System.out.println("登陸失敗");

            }

        }catch(SQLException  ce){

            ce.printStackTrace();

        }finally {

            try{

                JdbcUtils.close(con,statement,set);

            }catch(SQLException  ce){

                ce.printStackTrace();

            }

 }

    }

}

1.9 表與類之間的關係

  1. 能夠把整個表看作一個類
  2. 表的一行稱爲記錄,對應類的實例對象
  3.  表中的一行表明類的具體的實例

package day03;

 

import java.io.Serializable;

import java.util.Date;

 

public class Student implements Serializable {

    private static final long serialVersionUID = 8394954963273410188L;

    private int  id;

    private String name;

    private String gender;

    private Date birthday;

    public Student(){

 

    }

    public Student(int id, String name, String gender, Date birthday) {

        this.id = id;

        this.name = name;

        this.gender = gender;

        this.birthday = birthday;

    }

 

    public static long getSerialVersionUID() {

        return serialVersionUID;

    }

 

    public int getId() {

        return id;

    }

 

    public void setId(int id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public String getGender() {

        return gender;

    }

 

    public void setGender(String gender) {

        this.gender = gender;

    }

 

    public Date getBirthday() {

        return birthday;

    }

 

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

 

    @Override

    public String toString() {

        return "Student{" +

                "id=" + id +

                ", name='" + name + '\'' +

                ", gender='" + gender + '\'' +

                ", birthday='" + birthday + '\'' +

                '}';

    }

}

//表與類之間的關係

public class jdbc_demo3 {

    public static void main(String[] args) {

        List<Student>list=finAll();

        for(Student  ss:list){

            System.out.println(ss);

        }

    }

    //查詢表中全部的信息

    public static List<Student> finAll(){

 

        Connection  con=null;

        PreparedStatement  state=null;

        ResultSet  set=null;

        List<Student>list=new ArrayList<>();

        try{

            //獲取鏈接對象

            con= JdbcUtils.getConnection();

            //準備SQL 語句

            String sql="select  *  from  student";

            //獲取PrepareStatement對象

            state=con.prepareStatement(sql);

            set=state.executeQuery();

            //先聲明的對象

            Student  student=null;

            while(set.next()){

        //每次建立的對象,都會把上次對象給覆蓋掉,始終保持只佔用一塊內存空間

               student=new Student();

               student.setId(set.getInt("id"));

               student.setName(set.getString("name"));

               student.setGender(set.getString("gender"));

               student.setBirthday(set.getDate("birthday"));

               list.add(student);

            }

        }catch(SQLException  ce){

            ce.printStackTrace();

        }

        return list;

}

}

2.0  JDBC的事物處理

1 以前咱們使用 MYSQL 的命令來處理事務,JDBC 也支持基於事務的操做。

  1. 準備數據庫

Create  table  common(

Id int primary key auto_increment,

Name varchar(32) not null,

Varchar money(32) not null

)

  1. 方法:
  • void  setAutoCommit(Boolean flag): 參數時 true 或 false,若是設置爲 false,表示關閉自動提交,至關於開啓事務,默認是 true 自動提交。
  • void  commit(); 提交事物
  • void  rollback(); 回滾事物

事物的示例:

package day03;

import day02.JdbcUtils;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

 

//JDBC 事物的處理

public class jdbc_demo5 {

    public static void main(String[] args) {

        Connection  con=null;

        PreparedStatement state=null;

        try{

            //獲取Connection對象

            con= JdbcUtils.getConnection();

            //開啓事物 默認爲fasle

            con.setAutoCommit(false);

            //給李文傑扣錢

            String  sql="update common set  money=money-? where id=?";

            state=con.prepareStatement(sql);

            //給佔位符賦值

            state.setString(1,"500");

            state.setInt(2,1);

            //執行SQL語句

            state.executeUpdate();

            //給郭朝旭加錢

 

            String  sql2="update common set money=money+? where id=?";

            state=con.prepareStatement(sql2);

            //給佔位符賦值

            state.setString(1,"500");

            state.setInt(2,2);

            //執行SQL語句

           int i=state.executeUpdate();

           if(i>0){

               System.out.println("轉帳成功");

           }

            //執行完畢,關閉事物

            con.commit();

 

        }catch(SQLException  ce){

            ce.printStackTrace();

            //若是發生異常,就回滾 rollback

            try{

                con.rollback();

            }catch(SQLException  ces){

                ces.printStackTrace();

            }

            System.out.println("轉帳失敗");

        }finally {

            try{

                JdbcUtils.close(con,state);

            }catch(SQLException  ce){

                ce.printStackTrace();

           }

    }

}

相關文章
相關標籤/搜索