大junjun的java小屋

          成長之路

          常用鏈接

          統計

          最新評論

          Java注解annotation用法和自定義注解處理器(轉載)

          轉自: http://computerdragon.blog.51cto.com/6235984/1210969

          前言:
          在J2EE中,注解使得開發更加便利,省去了生成XML文件的過程,在Hibernate實體聲明中,可以簡簡單單的用幾個注解就可以免去生成一個XML的文件操作。這里就主要論述一下annotation的用法和自定義注解處理器。當在創建描述符性質的類或接口時,有大量重復性的工作時候,就可以利用注解來實現。

          基本語法:

            Java目前包括三種標準注解和四種元注解。元注解主要負責注解其他注解的。

            三種標準注解:

          @Override,表示當前的方法定義覆蓋了父類中的方法。必須要有相同的方法簽名即(方法名,參數類型,參數順序,參數個數)都一樣。否則在編譯過程中發出錯誤提示。

          @Deprecated,對不應該再使用的方法添加注解,當使用這個方法的時候,會在編譯時候顯示提示信息。

          @SuppressWarnings,關閉不當的編譯器報警信息

          四種元注解:

            @Target,表示該注解可以用什么地方。

          如CONSTRUCTOR,構造器聲明;FIELD,域聲明;METHOD,方法聲明;TYPE,類,接口或enum聲明

            @Retention,表示需要在什么級別保存該注解信息。

             如SOURCE,注解將被編譯器丟棄;CLASS,注解在class文件可用,但會被VM丟棄

          RUNTIME,VM將在運行期間也保留注解,可以使用反射機制讀取注解信息

            @Documented,將此注解包含到Javadoc中。

            @Inherited,允許子類繼承父類的注解。

          定義注解:

          自定義注解是以@interface為標志的。如同一個接口的定義,這里面定義的每個方法名,就是使用注解時候的元素名,方法的返回值就是元素的類型,可以利用default來聲明默認值,不過對于非基本類型,不能設置為null為默認值,一般對于字符串使用空字符串作為其默認值。

          如下所示:


          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          package whut.annotation;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          //定義一個注解
          @Target(ElementType.METHOD)//定義該注解將應用于什么地方,方法或者域
          @Retention(RetentionPolicy.RUNTIME)//定義該注解在哪一個級別可用
          public @interface UseCase {
              //注解元素,可以指定默認值,在使用注解的時候,可以直接給元素賦值如id=5
              public int id();
              public String description() default "no description";
               //利用枚舉來設置參數類型
               public enum ParameterType { STRING, SHORT, INT, BOOL, LONG, OBJECT };
               // 默認值,在使用注解的時候,只需要為元素賦值
               public ParameterType type() default ParameterType.STRING;
          }

          使用注解:

          在類中任意的域值前,或者方法前等直接@注解名,如@UseCase(id=5),使用注解的過程中,必須對于沒有設置默認值的元素進行賦值操作,對于每個元素進行按照名-值對的方式賦值。如果在注解定義中有名為value的元素,并且它是唯一需要賦值的,可以直接在括號里給出value所需要的值。

              注解是不能繼承的。

          下面是一個基本的利用非apt實現的注解處理器模型。

          這個模型可以注解實體,進行數據庫的映射建表操作。是最最基本的操作。

          注解定義:將四個注解名是在不同的文件中。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)
          @Retention(RetentionPolicy.RUNTIME)
          //定義字段的約束
          public @interface Constraints {
              boolean primaryKey() default false;
              boolean allowNull() default true;
              boolean unique() default false;
          }
          ////////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.TYPE)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          //定義表名的注解
          public @interface DBTable {
              public String name() default "";
          }
          ///////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          public @interface SQLInteger {
                String name() default "";
                //嵌套注解的功能,將column類型的數據庫約束信息嵌入其中
                Constraints constraints() default @Constraints;
          }
          ///////////////////////////////
          package whut.annotationDB;
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
          @Target(ElementType.FIELD)//類,接口或enum
          @Retention(RetentionPolicy.RUNTIME)
          public @interface SQLString {
              int value() default 0;
              String name() default "";
              //注解元素中引用別的注解,
              Constraints constraints() default @Constraints;
          }

          實體使用注解:這里是運用了運行時候處理注解,所以RetentionPolicy.RUNTIME

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          package whut.annotationDB;
          @DBTable(name="MEMBER")
          public class Member {
              //在使用注解過程中,如果有元素是value,并且只有value需要賦值,
              //則只需要在()中將值寫入
              @SQLString(30)
              private String firstName;
              @SQLString(50)
              private String lastName;
              @SQLInteger
              private Integer age;
              @SQLString(value=30,constraints=@Constraints(primaryKey=true))
              private String handle;
              public String getFirstName() {
                  return firstName;
              }
              public void setFirstName(String firstName) {
                  this.firstName = firstName;
              }
              public String getLastName() {
                  return lastName;
              }
              public void setLastName(String lastName) {
                  this.lastName = lastName;
              }
              public Integer getAge() {
                  return age;
              }
              public void setAge(Integer age) {
                  this.age = age;
              }
              public String getHandle() {
                  return handle;
              }
              public void setHandle(String handle) {
                  this.handle = handle;
              }
          }

          具體的非apt實現的注解處理器:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121
          122
          123
          124
          125
          126
          127
          128
          129
          package whut.annotationDB;
          import java.lang.annotation.Annotation;
          import java.lang.reflect.Field;
          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.util.ArrayList;
          import java.util.List;
          public class TableCreator {
              public Connection getConnection() {
                  String user = "root";
                  String password = "";
                  String serverUrl = "jdbc:mysql://localhost:3306/carrent?user=root&password=";
                  try {
                      Class.forName("com.mysql.jdbc.Driver");
                      Connection con = DriverManager.getConnection(serverUrl, user,
                              password);
                      return con;
                  } catch (Exception e) {
                      e.printStackTrace();
                      return null;
                  }
              }
              //實現創建表
              public static void main(String[] args) {
                  TableCreator tc = new TableCreator();
                  tc.executeCreateDB(Member.class);
              }
              public void executeCreateDB(Class<?> entity) {
                  String sqlStr = explainAnnotation(entity);
                  Connection con = getConnection();
                  PreparedStatement psql = null;
                  if (con != null && !sqlStr.equals("error")) {
                      try {
                          psql = con.prepareStatement(sqlStr);
                          psql.execute();
                      } catch (SQLException e) {
                          e.printStackTrace();
                      } catch (Exception e) {
                          e.printStackTrace();
                      } finally {
                          try {
                              if (psql != null)
                                  psql.close();
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
                          try {
                              if (con != null)
                                  psql.close();
                          } catch (SQLException e) {
                              e.printStackTrace();
                          }
                      }
                  } else
                      System.out.println("failure to...");
              }
              // 真正的處理器,Class<?>必須用這個表明
              public String explainAnnotation(Class<?> entity) {
                  // 獲取指定類型的注解
                  DBTable dbtable = entity.getAnnotation(DBTable.class);
                  if (dbtable == null) {
                      System.out.println("No DBTable annotation in class"
                              + entity.getName());
                      return "error";
                  } else {
                      String tableName = dbtable.name();// 獲取注解name值,即表名稱
                      // 當沒有設置name值,直接利用類的名作為表名
                      if (tableName.length() < 1)
                          tableName = entity.getName().toUpperCase();// 轉換大寫
                      // 準備處理字段注解
                      List<String> columnsDefs = new ArrayList<String>();
                      // 獲取該類的所有字段
                      for (Field field : entity.getDeclaredFields()) {
                          String columnName = null;
                          // 獲取該字段所有的注解
                          Annotation[] anns = field.getDeclaredAnnotations();
                          // Annotation[] anns=field.getAnnotations();
                          // 當有注解的時候
                          if (anns.length >= 1) {
                              // 判斷注解的類型
                              if (anns[0] instanceof SQLInteger) {
                                  SQLInteger sInt = (SQLInteger) anns[0];
                                  // 當沒有name時候,將字段大寫為列名
                                  if (sInt.name().length() < 1)
                                      columnName = field.getName().toUpperCase();
                                  else
                                      columnName = sInt.name();
                                  columnsDefs.add(columnName + " INT"
                                          + getConstraints(sInt.constraints()));
                              }
                              if (anns[0] instanceof SQLString) {
                                  SQLString sString = (SQLString) anns[0];
                                  // 當沒有name時候,將字段大寫為列名
                                  if (sString.name().length() < 1)
                                      columnName = field.getName().toUpperCase();
                                  else
                                      columnName = sString.name();
                                  columnsDefs.add(columnName + " VARCHAR("
                                          + sString.value() + ")"
                                          + getConstraints(sString.constraints()));
                              }
                          }
                      }
                      StringBuilder createDB = new StringBuilder("CREATE TABLE "
                              + tableName + "(");
                      for (String cols : columnsDefs)
                          createDB.append(" " + cols + ",");
                      // 移除最后一個,號
                      String tableSQL = createDB.substring(0, createDB.length() - 1)
                              + ");";
                      // 輸出創建表的過程
                      System.out.println("Table Creation SQL is:\n" + tableSQL);
                      return tableSQL;
                  }
              }
              // 返回指定的約束
              public String getConstraints(Constraints con) {
                  String constras = "";
                  if (!con.allowNull())
                      constras += " NOT NULL";
                  if (con.primaryKey())
                      constras += " PRIMARY KEY";
                  if (con.unique())
                      constras += " UNIQUE";
                  return constras;
              }
          }


          posted on 2013-08-21 11:12 李俊 閱讀(134) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 临高县| 巫溪县| 右玉县| 金门县| 沅陵县| 姚安县| 满城县| 昌宁县| 清流县| 隆安县| 沙坪坝区| 郸城县| 彭水| 霸州市| 上饶县| 弥渡县| 绥江县| 临桂县| 洛宁县| 保康县| 蒙阴县| 通许县| 中阳县| 刚察县| 凯里市| 凤台县| 积石山| 西安市| 南康市| 达日县| 青阳县| 延庆县| 潜江市| 南投市| 上饶市| 岚皋县| 本溪市| 定边县| 中宁县| 红桥区| 双辽市|