1. 程式人生 > >《Java基礎與案例開發詳解》(六)

《Java基礎與案例開發詳解》(六)

註解

定義:是用來為程式元素(類、方法、成員變數)設定說明和解釋的一種元資料。

註解標記是可以在編譯、類載入、執行的時候讀取。

註解表現形式

Java註解採用“@”標記形式,後面跟上註解型別名稱。

註解型別和註解的區別:

註解型別是某一型別註解的定義,類似於類,註解是某一註解型別的一個具體例項,類似於該類的例項。

Java中預定的註解

  1. Override是一個限定重寫方法的註解型別,這個註解只能用於方法。我們讀知道在Java中繼承,必須重寫父類的方法,如果我們在重寫的時候,不小心將方法搞錯了,這時編譯是不會提醒我們的,所以容易出現錯誤,但是我們在上述繼承中,如果我們在子類重寫的方法上加上這個註解,那麼在出現上述名字錯誤的時候,編譯時就會報錯。
  2. Deprecated這個註解是用來標識已過時的成員的註解型別,不建議使用。
  3. SupperWarnings是抑制編譯器警告的註解型別,常常會出現在使用List的集合新增元素,沒有規定泛型時,就會有警告。這是如果新增SupperWarnings(“nochecked”),就會消除警告。他有個屬性value值,用來指定印製的警告型別名。

自定義註解

public @interface MyAnnotation {//就是在interface前面加了一個@
    String value();//定義一個屬性
    //在這裡有一個不成文的約定,如果在使用註解時沒有顯式指定屬性名,缺指定了屬性值,而這個註解型別又有一個名叫value的屬性,就直接賦值,如果沒有,就編譯出錯。
} 使用如下: @MyAnnotation("ada")

註解預設值

    public @interface MyAnnotation {
    enum Status{one,two,three}//定義了一個列舉型別
    String value();//定義一個屬性
    Status status() default Status.one;//給這個屬性值賦了預設值
}

使用:

    @MyAnnotation("adasd")//這裡預設是有status的值,可以不顯示寫出來

對註解進行註解

上面我們只是討論自定義註解型別,下面四種專門用在註解上的註解型別。

  1. Target
  2. Retention
  3. Documented
  4. Inherited
Target

target的意思是目標,這個目標就是Java的程式元素,如類、介面、成員方法,如果規定了一個註解的程式元素,那麼這個註解只能作用於這些程式元素上。

程式元素型別

這裡寫圖片描述

@Target({ElementType.METHOD,ElementType.TYPE})//說明這個註解只能註解在方法和類、介面、列舉上,
//在其他地方編譯會報錯
public @interface MyAnnotation {
    enum Status{one,two,three}//定義了一個列舉型別
    String value();//定義一個屬性
    Status status() default Status.one;//給這個屬性值賦了預設值
}
Retention

主要是用來設定註解是否儲存在class檔案中,Java編譯器中處理Java類中的註解,有以下三種方式:

  • 編譯器處理完後,不保留註解到編譯後的類檔案中。
  • 將註解保留在編譯後的類檔案中,但是在執行時忽略它。
  • 將註解保留在編譯後的類檔案中,並在第一次載入類的時候讀取它。

這裡寫圖片描述

需要注意的是,如果採用是class,那麼這個註解類會編譯成一個獨立的class類,但是由於執行時忽略,所以用反射讀不出來資料。但是採用runtime是可以的。

Documented

這個註解和文件有關,所以要求我們在定義Documented的註解必須設定Retenttion的值採用的是runtime。

Inherited

繼承是Java的特性,那麼在註解上,父類的註解,會被子類繼承嗎,預設是不可以的,但是如果新增Inherited就可以啦,定義在父類的註解,有Inherited這個註解,那麼繼承的子類,讀具備這個特性。

獲取註解資訊

在前面我們已經學習過了反射,可以通過反射來獲取註解的資訊,在使用的時候,需要明確一點,反射是在執行時獲取資訊,因此,要使用必須將註解申明成@Retention(RetentionPolicy.RUNTIME)

測試程式碼如下:

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
    String value1() default "laoqiang";

}


獲取註解資訊

@MyAnnotation1
public class Test26 {
   public static void main(String[] args) {
    //Test26.class是直接獲取Test26的class物件
    //getAnnotation是根據如果存在這種型別的註解就返回。   
    //getAnnocations是根據該元素返回所有註解
    Annotation a = Test26.class.getAnnotation(MyAnnotation1.class);
    if(a!=null) {
        MyAnnotation1 m = (MyAnnotation1) a;//將註解強轉為自定義註解,
        //就方便下面讀取註解的屬性的值,如果不強轉的話,只可以獲取它的註解型別
        System.out.println("註解的型別:"+m.annotationType().getName()+"註解的值:"+m.value1());
    }
    Method m = null;
    try {
        m = Test26.class.getMethod("show");//這裡是獲取指定方法的例項,所以當你要
        //獲取建構函式,欄位的註解,就在這裡做出變化,獲取對應的物件的例項
        Annotation[] annotations = m.getAnnotations();//獲取所有的註解
        for(Annotation a1:annotations) {
            MyAnnotation1 m1 = (MyAnnotation1) a1;
            System.out.println("註解型別:"+a.annotationType().getName()+"註解的值:"+m1.value1());
        }
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}
   @MyAnnotation1(value1="method")
   public static void show(){
        System.out.println("asdasda");
    }
}

Jdbc

Jdbc是Java語言用於訪問資料庫的應用程式設計介面,可以通過它訪問各類資料庫。對應的類庫主要分佈在java.sql和javax.sql。

資料庫常用的類

  1. DriverManger,是JDBC的管理層。
  2. Connection介面,是特定的資料庫的連線。通過DriverManager類的靜態方法的getConnection()方法來獲取。
  3. Statement物件勇敢與將sql語句傳送到資料庫中,執行對資料庫的資料的檢索或者更新,有兩個子介面:CallableStatement和PreparedStatement。
  4. PreparedStatement介面:Statement主要用來執行靜態的SQL語句,如果有些操作只是與SQL語句中某些引數有所不同,其餘的SQL子句相同,則使用PrepareStatement來提高效率。使用PrepareStatement方法建立好一個預先編譯的SQL語句:其中引數會變動的部分會先用“?”作為佔位符,等到需要真正指定引數執行時,在是喲個相對的setXXX指定值的時候,?才有真正的引數值。
  5. ResultSet包含符合SQL語句條件中的所有行,並且提供get()方法來獲取當前行中的不同列,並且有next方法來移動到ResultSet的下一行,使下一行成為當前行。通過Statement的相關方法來獲取ResultSet物件,通常使用比較多的是executeQuery,執行給定的查詢SQL語句,該語句返回單個ResultSet物件;executeUpdate執行給定的SQL語句,該語句可能為insert、update、delete,返回執行成功的條數,返回-1是失敗。

獲取對應查詢結果列的方法:

這裡寫圖片描述

資料庫的使用

    private  static final String  URL = "jdbc:mysql://localhost:3306/test";
    private static Connection c = null;
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;
    //mysql的url:jdbc:mysql://localhost:3306/test
    //oracle的url:jdbc:oracle:thin:@localhost:1521:sid/test
    //需要注意的是最後的test你你要連結的資料庫的資料庫的名字

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //mysql驅動:com.mysql.jdbc.Driver
            //oracle驅動:oracle.jdbc.driver.OracleDriver
             c = (Connection) DriverManager.getConnection(URL, "root", "123456");
             ps = (PreparedStatement) c.prepareStatement("select name from student");
             rs = ps.executeQuery();
            while(rs.next()) {
            String name =   rs.getString(1);//根據列的序號來獲取資訊需要注意是從1開始。
            System.out.println(name+"\n");
            }


        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(ps!=null) {
                try {
                    ps.cancel();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(c!=null) {
                try {
                    c.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    //注意點
    // 在使用jdbc來連線mysql和oracle資料庫的時候要保證它們的服務時開啟
    //資料庫資源使用完畢要及時的關閉

資料庫的封裝與增刪改查

public class DbUtil {
    private  static final String  URL = "jdbc:mysql://localhost:3306/test";
    private static Connection c = null;
    public static Connection getConnection() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            c = (Connection) DriverManager.getConnection(URL, "root", "123456");

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return c;
   }
   public static void closeConnection() {
       if(c!=null) {
           try {
            c.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       }
   }

   public static void closePrepareStatement(PreparedStatement ps) {
       if(ps!=null) {
           try {
            ps.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       }

   }

   public static void closeResultSet(ResultSet rs) {
       if(rs!=null) {
           try {
            rs.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       }

   }



}

//增刪改查

private static Connection c = null;
     public static void main(String[] args) {
        c =  DbUtil.getConnection();
        //insertStudent();
        //selectStudent();
        //updateStudent();
        deleteStudent();


    }

    public static  void insertStudent() {
        PreparedStatement ps = null;
        try {
             ps= (PreparedStatement) c.prepareStatement("insert into student(name,age) value(?,?)");
             ps.setString(1, "laohe");//注意這裡設定值的序號是按佔位符的順序,從1開始
             ps.setInt(2, 23);
             int count = ps.executeUpdate();
             if(count!=-1) {
             System.out.println("scuess");
            }else {
                System.out.println("fail");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            DbUtil.closeConnection();
            DbUtil.closePrepareStatement(ps);
        }
    }

    public static  void deleteStudent() {
        PreparedStatement ps = null;
        try {
             ps= (PreparedStatement) c.prepareStatement("delete from student where id=?");
             ps.setInt(1, 2);
            int count = ps.executeUpdate();
            if(count!=-1) {
                System.out.println("scuess");
            }else {
                System.out.println("fail");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            DbUtil.closeConnection();
            DbUtil.closePrepareStatement(ps);
        }

    }

    public static  void updateStudent() {
        PreparedStatement ps = null;
        try {
             ps= (PreparedStatement) c.prepareStatement("update student set name ='laohe' where id=?");;
             ps.setInt(1, 2);
            int count = ps.executeUpdate();
            if(count!=-1) {
                System.out.println("scuess");
            }else {
                System.out.println("fail");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            DbUtil.closeConnection();
            DbUtil.closePrepareStatement(ps);
        }
    }


        public static  void selectStudent() {
            PreparedStatement ps = null;
             ResultSet rs =null;
            try {
                 ps= (PreparedStatement) c.prepareStatement("select name,age from student");
                 rs = ps.executeQuery();
                 while(rs.next()) {
                     String name = rs.getString(1);
                     int age = rs.getInt(2);
                     System.out.println("name:"+name+"\t\t\t"+"age:"+age);

                 }

            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                DbUtil.closeConnection();
                DbUtil.closePrepareStatement(ps);
                DbUtil.closeResultSet(rs);
            }


    }

//增刪改查是最起初也是最重要的,任何負責的專案也是從它開始,看到這裡還是希望讀者,謹記:千里之行始於足下,共勉。