成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 注解入門 自動(dòng)生成SQL語句

J4ck_Chan / 2483人閱讀

摘要:引言在用的時(shí)候發(fā)現(xiàn)能自動(dòng)生成,同時(shí)帶有一些注解,這引起了我的好奇。注解來源于之類的其他語言。關(guān)閉不當(dāng)?shù)木幾g器警告。允許子類繼承父類中的注解。五通過注解反射生成語句接下來,我用一個(gè)例子來解釋注解的作用。

引言

在用hibernate的時(shí)候發(fā)現(xiàn)idea能自動(dòng)生成JavaBean,同時(shí)帶有一些注解,這引起了我的好奇。當(dāng)在學(xué)習(xí)Android的時(shí)候,我發(fā)現(xiàn)XUtils這個(gè)工具包中的DBUtils也能夠使用類似hibernate的注解。于是乎在java編程思想中找了找有關(guān)注解的用法。

一 注解定義

注解(也稱為元數(shù)據(jù))為我們在代碼中添加信息提供了一種形式化的方法,使我們可以在稍后某個(gè)時(shí)刻非常方便的使用這些數(shù)據(jù)。注解來源于C#之類的其他語言。

注解的語法比較簡單,除了@符號(hào)外,它與java的固有語法一致。javaSE5中內(nèi)置了三種注解:

@Override:定義覆蓋超類,當(dāng)覆寫對(duì)應(yīng)不上被覆蓋的方法,編譯器發(fā)出錯(cuò)誤提示。

@Deprecated:當(dāng)使用了該注解,即表示這個(gè)方法已經(jīng)不推薦被使用。

@SuppressWarnings:關(guān)閉不當(dāng)?shù)木幾g器警告。

二 基本語法

我們使用自定義的注解對(duì)一個(gè)方法進(jìn)行注解:

public class Testable{
    public void execute()
    {
        System.out.println("execute...");
    }
    @WETest
    void taskStart()
    {
        execute();
    }
}

在上邊的代碼中,我們對(duì)taskStart方法使用了注解,接下來我們對(duì)WETest注解進(jìn)行定義:

import java.lang.annotation.*;
 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WETest{}
三 定義注解

我們給上邊的注解添加一些內(nèi)容:

import java.lang.annotation.*;
 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface WETest{
    public int id();
    public String Notes() default "there is no Notes";
}

同樣,我們對(duì)Testable類使用最新的注解:

public class Testable{
    @WETest(id=666)
    public void execute()
    {
        System.out.println("execute...");
    }
    @WETest(id=666,Notes="this is a method")
    void taskStart()
    {
        execute();
    }
}

注解就是這么使用的,當(dāng)注解內(nèi)容沒有填寫時(shí),他會(huì)使用默認(rèn)的值,如execute方法,他沒有定義Notes,那么Notes默認(rèn)值為"there is no Notes"。

四 元注解

我們看到注解上邊有兩行內(nèi)容,它們是元注解,專門對(duì)注解的解釋。元注解一共有四種,分別是:

@Target:表示該注解可以用到哪些地方,ElementType,CONSTRUCTOR構(gòu)造器聲明,F(xiàn)IELD域聲明(包括enum實(shí)例),LOCAL_VARIABLE局部變量聲明,METHOD方法,PACKAGE包,PARAMETER參數(shù),TYPE類、接口或enum。

@Retention:表示需要在什么級(jí)別上使用,RetentionPolicy,SOURCE注解會(huì)被編譯器丟掉,CLASS在class文件中可用會(huì)被VM拋棄,RUNTIME在VM運(yùn)行期也會(huì)保留可以通過反射獲取注解信息。

@Documented:將注解包含在Javadoc中。

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

五 通過注解反射生成SQL語句

接下來,我用一個(gè)例子來解釋注解的作用。先編寫一些注解定義:

//DBTable.java            用來生成數(shù)據(jù)表
package annotations;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    public String name() default "";
}
 
//Constraints.java        用來定義約束項(xiàng)
package annotations;
 
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;
}
 
//PrimaryKey.java        將Constraints中的primarykey定義為真,表示為主鍵
package annotations;
 
import java.lang.annotation.*;
 
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrimaryKey {
    Constraints constraints() default @Constraints(primarykey = true);
}
 
//SQLInteger.java         定義列的類型
package annotations;
 
import java.lang.annotation.*;
 
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
    String name() default "";
    Constraints constraints() default @Constraints;
}
 
//SQLString.java        定義列的類型
package annotations;
 
import java.lang.annotation.*;
 
 
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
    int value() default 64;
    String name() default "";
    Constraints constraints() default @Constraints;
}
   接下來寫一個(gè)javabean,使用上述注解:


//User.java
import annotations.Constraints;
import annotations.DBTable;
import annotations.SQLInteger;
import annotations.SQLString;
 
@DBTable(name="user")
public class User {
    @SQLInteger(name="id",constraints = @Constraints(primarykey=true))
    public Integer id;
    @SQLString(value=30)
    public String name;
    @SQLString(name="passwd",constraints=@Constraints(allownull=false))
    public String password;
     
    /*可以不用
    public void setId(Integer id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public String getPassword() {
        return password;
    }*/
}

我們看到注解中可以使用注解,在SQLInteger中我們使用了Constraints注解。

接下來我們寫一個(gè)注解處理器:

//Test.java
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
 
import annotations.Constraints;
import annotations.DBTable;
import annotations.SQLInteger;
import annotations.SQLString;
 
public class Test {
     
    public static String getConstraints(Constraints con)
    {
        String constraints = "";
        if(!con.allownull())
        {
            constraints +=" NOT NULL";
        }
        if(con.primarykey())
        {
            constraints += " PRIMARY KEY";
        }
        return constraints;
    }
 
    public static void main(String[] args) throws ClassNotFoundException {
        Scanner s = new Scanner(System.in);
        String name = s.next();                                    //從控制臺(tái)輸入一個(gè)類名,我們輸入U(xiǎn)ser即可
        Class cl = Class.forName(name);                         //加載類,如果該類不在默認(rèn)路徑底下,會(huì)報(bào) java.lang.ClassNotFoundException
        DBTable dbTable = cl.getAnnotation(DBTable.class);         //從User類中獲取DBTable注解
        if(dbTable == null){                                       //如果沒有DBTable注解,則直接返回,我們寫了,當(dāng)然有
            return;
        }
        String tableName = (dbTable.name().length()<1)?cl.getName():dbTable.name();//獲取表的名字,如果沒有在DBTable中定義,則獲取類名作為Table的名字
        List columnDefs = new ArrayList();
        for(Field field : cl.getDeclaredFields())                  //獲取聲明的屬性
        {
            String columnName = null;
            Annotation[] anns = field.getDeclaredAnnotations();//獲取注解,一個(gè)屬性可以有多個(gè)注解,所以是數(shù)組類型
            if(anns.length < 1)
            {
                continue;
            }
            if(anns[0] instanceof SQLInteger)                //判斷注解類型
            {
                SQLInteger sInt = (SQLInteger)anns[0];
                columnName = (sInt.name().length()<1)?field.getName():sInt.name();//獲取列名稱與獲取表名一樣
                columnDefs.add(columnName+" INT"+getConstraints(sInt.constraints()));//使用一個(gè)方法,自己寫的getConstraints(Constraints constraints)獲取列定義
            }
            if(anns[0] instanceof SQLString)
            {
                SQLString sStr = (SQLString)anns[0];
                columnName = (sStr.name().length()<1)?field.getName().toUpperCase():sStr.name();
                columnDefs.add(columnName + " VARCHAR("+sStr.value()+")"+getConstraints(sStr.constraints()));
            }
        }
        StringBuilder createCommand = new StringBuilder("CREATE TABLE "+tableName+"(");
        for(String columnDef :columnDefs)
        {
            createCommand.append("
    "+columnDef+",");
        }
        String tableCreate = createCommand.substring(0,createCommand.length()-1)+"
);";
        System.out.println(tableCreate);                        //打印出來
    }
 
}

我們可以采用上述方法動(dòng)態(tài)的處理一些數(shù)據(jù),例如創(chuàng)建數(shù)據(jù)表。

六 總結(jié)
注意:注解不支持繼承例如 extends @xxx。
     注解的default默認(rèn)值不可以為null

使用注解可以減少對(duì)xml等外部文件的依賴,使得對(duì)類的定義可以在一處實(shí)現(xiàn),避免了一個(gè)類兩處定義的麻煩。spring和hibernate就采用的這樣的方法。
更多文章:http://blog.gavinzh.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64375.html

相關(guān)文章

  • 【從零入門系列-2】Spring Boot 之 數(shù)據(jù)庫實(shí)體定義實(shí)現(xiàn)

    摘要:文章系列從零入門系列之從零入門系列之程序結(jié)構(gòu)設(shè)計(jì)說明前言本篇文章開始代碼實(shí)踐,系統(tǒng)設(shè)計(jì)從底向上展開,因此本篇先介紹如何實(shí)現(xiàn)數(shù)據(jù)庫表實(shí)體類的設(shè)計(jì)實(shí)現(xiàn)。主鍵由數(shù)據(jù)庫自動(dòng)生成主要是自動(dòng)增長型主鍵由程序控制。 文章系列 【從零入門系列-0】Sprint Boot 之 Hello World 【從零入門系列-1】Sprint Boot 之 程序結(jié)構(gòu)設(shè)計(jì)說明 前言 本篇文章開始代碼實(shí)踐,系統(tǒng)...

    nemo 評(píng)論0 收藏0
  • SpringMVC入門筆記

    摘要:入門筆記簡介是一種基于的實(shí)現(xiàn)了設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)框架,是系開源項(xiàng)目中的一個(gè),和配合使用。配置在中需要添加使用的和映射規(guī)則。入門較快,而掌握起來相對(duì)較難。 SpringMVC入門筆記 1. 簡介 Spring MVC是一種基于Java的實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架 ,是Spring系開源項(xiàng)目中的一個(gè),和IoC配合使用。通過策略接口,Spring...

    zhaochunqi 評(píng)論0 收藏0
  • 【mybatis】(一)mybatis快速入門

    摘要:一定義是一款優(yōu)秀的持久層框架,它支持定制化存儲(chǔ)過程以及高級(jí)映射。別名與類中的屬性名保持一致。接口的名字建議為,與文件保持一致編寫文件,名字與接口名保持一致。 一、定義 MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射...

    MartinDai 評(píng)論0 收藏0
  • 注解的奇妙之旅

    摘要:注解是棄用不再使用的意思。是處理源碼級(jí)別的注解,它會(huì)生成新的字節(jié)碼或其它文件。這個(gè)該怎么實(shí)現(xiàn)呢我們需要在啟動(dòng)之后文件轉(zhuǎn)為字節(jié)碼文件之前,就需要生成對(duì)應(yīng)的和方法,因?yàn)樗辉诰幾g期有效。我們在啟動(dòng)后,會(huì)根據(jù)注解,來創(chuàng)建相應(yīng)的數(shù)據(jù)表。 導(dǎo)讀 模擬hibernate的注解,創(chuàng)建數(shù)據(jù)表的源碼地址:https://gitee.com/zbone/myanno 注解釋義 java開發(fā)人員對(duì)注解,應(yīng)該...

    Markxu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<