1. 程式人生 > >Java註解及通過自定義Java註解實現資料庫的操作

Java註解及通過自定義Java註解實現資料庫的操作

在Java程式中通過註解,可以讓程式設計更加簡潔、程式碼更加清晰。因此在Java框架程式碼中,嵌入了大量的註解。

講註解,首先得講註解的概念:Java提供了一種原程式中的元素關聯任何資訊和任何元資料的途徑和方法。

一、註解的分類

1、按照執行機制分為原始碼註解編譯註解執行時註解

(1)原始碼註解:註解只在原始碼中存在,編譯成.class檔案就不存在了

(2)編譯註解:註解在原始碼和.class檔案中都存在,如JDK的三個註解

(3)執行時註解:在執行階段還起作用,甚至影響執行邏輯的註解,如Spring中的@Autowired註解

2、按照來源分為JDK註解第三方的註解元註解自定義註解

(1)JDK自帶註解

        @Override:子類中的方法覆蓋了父類中的方法時,在方法的前面會出現這個關鍵字;

        @Deprecated:表示一個方法過時了,但仍然可以使用,即在呼叫加該註解的方法前加上@Suppvisewarning("deprecation")即可;

        @Suppvisewarning:結合@Depricated理解;

(2)第三方的註解

        如Spring中的@Autowired、@Service和@Repository等;

        如Mybatis中的@InsertProvider、@UpdateProvider和@Options等;

(3)元註解:註解的註解稱為元註解

(4)自定義註解---本節主要講解

 二、自定義註解

1、自定義註解語法要求:

@Target({ElementType.METHOD,                //方法宣告
               ElementType.TYPE,            //類、介面
               ElementType.FIELD,           //欄位宣告
               ElementType.CONSTRUCTOR,     //構造方法宣告
               ElementType.LOCAL_VARIABLE,  //區域性變數
               ElementType.PACKAGE,         //包宣告
               ElementType.PARAMETER})      //引數宣告
@Retention(RetentionPolicy.RUNTIME)    //生命週期,有SOURCE(原始碼)、CLASS(編譯)、RUNTIME(執行時)   
@Inherited                          //允許子類繼承
@Documented                         //生成JavaDoc的時候包含的資訊
public @interface Description{      //@interface定義註解
    
    String desc();                  //方法以無引數、無異常的方式宣告
    
    String author();
    
    int age() default 20;           //使用default為其指定預設值
}
(1)同時注意成員的型別是受限制的,合法的型別:基本型別、String、Class、Annotation、Enumeration。

(2)如果註解只有一個成員時,成員名必須取名為value(),在使用時可以忽略成員名和複製號(=);

(3)如果註解類沒有成員,則稱之為標識註解;

2、註解的使用

@<註解名>(<成員名1>=<成員值1>,<成員名2>=<成員值2>,……)
@Description(desc="Hello", author="Jack", age=18)
public String Demo(){
    return "test";
}

三、自定義註解操作資料庫

資料庫中的表如圖所示:


第一步:建立與資料庫中表對應的實體類,並分別在類和方法上插入自定義的註解


類上的註解


方法上的註解


第二步:寫測試函式

public class Main {

      public static void main(String[] args){

            Student stu1 = new Student();
            stu1.setSno(20110002);//按sno查詢學生

            Student stu2 = new Student();
            stu2.setMajor("IS");//按專業查詢學生
            stu2.setName("lisi");

            Student stu3 = new Student();
            stu3.setName("AAA,HHH,zhangsan,lisi");//按名字查詢其中任意一個學生

            String sql1 = query(stu1);
            String sql2 = query(stu2);
            String sql3 = query(stu3);

            System.out.println(sql1);
            exeQuery(sql1);

            System.out.println(sql2);
            exeQuery(sql2);

            System.out.println(sql3);
            exeQuery(sql3);

      }

    private static String query(Object stu) {
        StringBuilder sb = new StringBuilder();
        //解析註解:
        //1、獲取到class
        Class clazz = stu.getClass();
       
        //2、獲取到table的名字
        boolean exists = clazz.isAnnotationPresent(Table.class);
        if(!exists)
            return null;
        Table table = (Table) clazz.getAnnotation(Table.class);
        String tableName = table.value();
        sb.append("select * from ").append(tableName).append(" where 1=1");
        
        //3、遍歷所有欄位
        Field[] fArray = clazz.getDeclaredFields();
        for(Field field : fArray) {
            //4、處理每個欄位對應的sql
            //4.1拿到欄位名
            boolean fieldExist = field.isAnnotationPresent(Column.class);
            if (!fieldExist){
                continue;
            }
            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();

            //4.2拿到欄位名
            String filename = field.getName();
            String  getMethodName = "get" + filename.substring(0,1).toUpperCase() + filename.substring(1);
            Object filevalue = null;
            try {
                Method getMethod = clazz.getMethod(getMethodName);
                filevalue = getMethod.invoke(stu, null);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //4.3拼裝sql
            if(filevalue == null || ((filevalue instanceof Integer) && ((Integer)filevalue==0)))
                continue;
            sb.append(" and ").append(filename);
            if(filevalue instanceof String) {
                if(((String)filevalue).contains(",")){
                    String[] values = ((String) filevalue).split(",");
                    sb.append(" in(");
                    for(String value : values){
                        sb.append("'").append(value).append("'").append(",");
                    }
                    sb.deleteCharAt(sb.length()-1);
                    sb.append(")");
                }else {
                    sb.append(" = ").append("'").append(filevalue).append("'");
                }
            }else if(filevalue instanceof Integer)
                sb.append(" = ").append(filevalue);
        }

        return sb.toString();
    }

    private static void exeQuery(String sql){
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/learn?useUnicode=true&characterEncoding=utf-8&&useSSL=false&serverTimezone=UTC","root", "admin");
            PreparedStatement statement = conn.prepareStatement(sql);
            ResultSet rs = statement.executeQuery();
            while(rs.next()){
                System.out.println(rs.getString("sno") + "\t" + rs.getString("name") + "\t" + rs.getString("major"));
            }
            statement.close();
            conn.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

執行測試程式得到如下結果:


參考資料:http://www.imooc.com/video/8871