JDBC部分

JDBC

JAVA Database Connectivity java 數(shù)據(jù)庫連接

  • 為什么會出現(xiàn)JDBC

SUN公司提供的一種數(shù)據(jù)庫訪問規(guī)則、規(guī)范, 由于數(shù)據(jù)庫種類較多,并且java語言使用比較廣泛,sun公司就提供了一種規(guī)范,讓其他的數(shù)據(jù)庫提供商去實(shí)現(xiàn)底層的訪問規(guī)則。 我們的java程序只要使用sun公司提供的jdbc驅(qū)動(dòng)即可。

使用JDBC的基本步驟

  1. 注冊驅(qū)動(dòng)

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

  2. 建立連接

    //DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
    //2. 建立連接 參數(shù)一: 協(xié)議 + 訪問的數(shù)據(jù)庫 , 參數(shù)二: 用戶名 , 參數(shù)三: 密碼。
    conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

  3. 創(chuàng)建statement

    //3. 創(chuàng)建statement , 跟數(shù)據(jù)庫打交道,一定需要這個(gè)對象
    st = conn.createStatement();

  4. 執(zhí)行sql ,得到ResultSet

    //4. 執(zhí)行查詢 , 得到結(jié)果集
    String sql = "select * from t_stu";
    rs = st.executeQuery(sql);

  5. 遍歷結(jié)果集

    //5. 遍歷查詢每一條記錄

     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);
             
     }
    
  6. 釋放資源

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { } // ignore 
        rs = null;
    }

    ...

JDBC 工具類構(gòu)建

  1. 資源釋放工作的整合
  1. 驅(qū)動(dòng)防二次注冊
DriverManager.registerDriver(new com.mysql.jdbc.Driver());

Driver 這個(gè)類里面有靜態(tài)代碼塊,一上來就執(zhí)行了,所以等同于我們注冊了兩次驅(qū)動(dòng)。 其實(shí)沒這個(gè)必要的。
//靜態(tài)代碼塊 ---> 類加載了,就執(zhí)行。 java.sql.DriverManager.registerDriver(new Driver());


    最后形成以下代碼即可。

    Class.forName("com.mysql.jdbc.Driver"); 
  1. 使用properties配置文件

    1. 在src底下聲明一個(gè)文件 xxx.properties ,里面的內(nèi)容吐下:

      driverClass=com.mysql.cj.jdbc.Driver
      url=jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=GMT%2B8&amp
      name=root
      password=root

    2. 在工具類里面,使用靜態(tài)代碼塊,讀取屬性

代碼如下

    static{

        try {
            //1. 創(chuàng)建一個(gè)屬性配置對象
            Properties properties = new Properties();
            InputStream is = new FileInputStream("jdbc.properties"); //對應(yīng)文件位于工程根目錄
             
            //使用類加載器,去讀取src底下的資源文件。 后面在servlet  //對應(yīng)文件位于src目錄底下
            //InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
            //導(dǎo)入輸入流。
            properties.load(is);
            
            //讀取屬性
            driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
            name = properties.getProperty("name");
            password = properties.getProperty("password");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

?

數(shù)據(jù)庫的CRUD sql

  • insert(增)

      1.INSERT INTO t_stu (NAME , age) VALUES ('wangqiang',28)
    
    
      2.INSERT INTO t_stu VALUES (NULL,'wangqiang2',28)
    
    
    
      // 1. 獲取連接對象
          conn = JDBCUtil.getConn();
          // 2. 根據(jù)連接對象,得到statement
          st = conn.createStatement();
          
          //3. 執(zhí)行添加
          String sql = "insert into t_stu values(null , 'aobama' , 59)";
          //影響的行數(shù), ,如果大于0 表明操作成功。 否則失敗
          int result = st.executeUpdate(sql);
          
          if(result >0 ){
              System.out.println("添加成功");
          }else{
              System.out.println("添加失敗");
          }
    
  • delete(刪)

    DELETE FROM t_stu WHERE id = 6

    // 1. 獲取連接對象
        conn = JDBCUtil.getConn();
        // 2. 根據(jù)連接對象,得到statement
        st = conn.createStatement();
        
        //3. 執(zhí)行添加
        String sql = "delete from t_stu where name='aobama'";
        //影響的行數(shù), ,如果大于0 表明操作成功。 否則失敗
        int result = st.executeUpdate(sql);
        
        if(result >0 ){
            System.out.println("刪除成功");
        }else{
            System.out.println("刪除失敗");
        }
  • query(查)

    SELECT * FROM t_stu

        // 1. 獲取連接對象
        conn = JDBCUtil.getConn();
        // 2. 根據(jù)連接對象,得到statement
        st = conn.createStatement();

        // 3. 執(zhí)行sql語句,返回ResultSet
        String sql = "select * from t_stu";
        rs = st.executeQuery(sql);

        // 4. 遍歷結(jié)果集
        while (rs.next()) {
            String name = rs.getString("name");
            int age = rs.getInt("age");

            System.out.println(name + "   " + age);
        }
  • update(改)

    UPDATE t_stu SET age = 38 WHERE id = 1;

    // 1. 獲取連接對象
        conn = JDBCUtil.getConn();
        // 2. 根據(jù)連接對象,得到statement
        st = conn.createStatement();
        
        //3. 執(zhí)行添加
        String sql = "update t_stu set age = 26 where name ='qyq'";
        //影響的行數(shù), ,如果大于0 表明操作成功。 否則失敗
        int result = st.executeUpdate(sql);
        
        if(result >0 ){
            System.out.println("更新成功");
        }else{
            System.out.println("更新失敗");
        }

使用單元測試,測試代碼

  1. 定義一個(gè)類, TestXXX , 里面定義方法 testXXX.

  2. 添加junit的支持。

    右鍵工程 --- add Library --- Junit --- Junit4

  3. 在方法的上面加上注解 , 其實(shí)就是一個(gè)標(biāo)記。

    @Test
    public void testQuery() {
    ...
    }

  4. 光標(biāo)選中方法名字,然后右鍵執(zhí)行單元測試。 或者是打開outline視圖, 然后選擇方法右鍵執(zhí)行。

Dao模式

Data Access Object 數(shù)據(jù)訪問對象

  1. 新建一個(gè)dao的接口, 里面聲明數(shù)據(jù)庫訪問規(guī)則
    /**
     * 定義操作數(shù)據(jù)庫的方法
     */
    public interface UserDao {
    
        /**
         * 查詢所有
         */
        void findAll();
    }
  1. 新建一個(gè)dao的實(shí)現(xiàn)類,具體實(shí)現(xiàn)早前定義的規(guī)則
    public class UserDaoImpl implements UserDao{

    @Override
    public void findAll() {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //1. 獲取連接對象
            conn = JDBCUtil.getConn();
            //2. 創(chuàng)建statement對象
            st = conn.createStatement();
            String sql = "select * from t_user";
            rs = st.executeQuery(sql);
            
            while(rs.next()){
                String userName = rs.getString("username");
                String password = rs.getString("password");
                
                System.out.println(userName+"="+password);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.release(conn, st, rs);
        }
    }

}
  1. 直接使用實(shí)現(xiàn)

    @Test
    public void testFindAll(){
    UserDao dao = new UserDaoImpl();
    dao.findAll();
    }

Statement安全問題

  1. Statement執(zhí)行 ,其實(shí)是拼接sql語句的。 先拼接sql語句,然后在一起執(zhí)行。
    String sql = "select * from t_user where username='"+ username  +"' and password='"+ password +"'";

    UserDao dao = new UserDaoImpl();
    dao.login("admin", "100234khsdf88' or '1=1");

    SELECT * FROM t_user WHERE username='admin' AND PASSWORD='100234khsdf88' or '1=1' 

    前面先拼接sql語句, 如果變量里面帶有了 數(shù)據(jù)庫的關(guān)鍵字,那么一并認(rèn)為是關(guān)鍵字。 不認(rèn)為是普通的字符串。 
    rs = st.executeQuery(sql);

PrepareStatement

該對象就是替換前面的statement對象。

  1. 相比較以前的statement, 預(yù)先處理給定的sql語句,對其執(zhí)行語法檢查。 在sql語句里面使用 ? 占位符來替代后續(xù)要傳遞進(jìn)來的變量。 后面進(jìn)來的變量值,將會被看成是字符串,不會產(chǎn)生任何的關(guān)鍵字。
        String sql = "insert into t_user values(null , ? , ?)";
         ps = conn.prepareStatement(sql);
         
         //給占位符賦值 從左到右數(shù)過來,1 代表第一個(gè)問號, 永遠(yuǎn)你是1開始。
         ps.setString(1, userName);
         ps.setString(2, password);

?

總結(jié):

  1. JDBC入門

  2. 抽取工具類 ###

  3. Statement CRUD ###

    演練crud

  4. Dao模式 ###

    聲明與實(shí)現(xiàn)分開

  5. PrepareStament CRUD ###

    預(yù)處理sql語句,解決上面statement出現(xiàn)的問題

作業(yè):

1. dao里面聲明 增刪查改, 以及登錄的方法


    登錄方法 :

        要求,成功后返回該用戶的所有信息。 字段不限。

    查詢:

        如果是findAll. 肯定是返回一個(gè)集合  List<User>

    增加 & 刪除 & 更新

        返回影響的行數(shù)即可  int類型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文內(nèi)容 1.什么是JDBC以及為什么要使用JDBC 2.JDBC核心API的講解 3.使用JDBC核心API進(jìn)行...
    Vincilovfang閱讀 1,367評論 0 11
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,036評論 0 11
  • 4.旅游景點(diǎn) 說到匹茲堡的旅游景點(diǎn),就不得不說市中心和Schenley park。其實(shí)痞子堡并不是一個(gè)旅游城市,但...
    LynnWorks閱讀 544評論 0 0
  • 想你時(shí), 覺得你離我很近, 微笑著站在那里。 想你時(shí), 又覺得你離我很遠(yuǎn), 好似相隔千山萬水。 雖然你不言, 我亦...
    簡JN閱讀 401評論 14 25
  • 想認(rèn)真談戀愛,到底該開什么樣的車? 1. 最近看到一篇文章, 意思是說如果要想認(rèn)真談戀愛, 要開一輛恰當(dāng)?shù)能?,而?..
    誠摯宇閱讀 148評論 0 0

友情鏈接更多精彩內(nèi)容