JAVA注解 实现一个简单的sql语句生成器

注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁。

注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致。Java SE5内置了三种标准注解:

     @Override,表示当前的方法定义将覆盖超类中的方法。

     @Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

     @SuppressWarnings,关闭不当编译器警告信息。
 上面这三个注解多少我们都会在写代码的时候遇到。Java还提供了4中注解,专门负责新注解的创建。

1.@Target(ElementType)  用于制定限定注解的使用范围
ElementType属性详解(jdk java.lang.annotation):
 public enum ElementType{
    TYPE,
    //用于类,接口,枚举但不能是注解
    FIELD,
    //字段上,包括枚举值
    METHOD,
    //方法,不包括构造方法
    PARAMETER,
    //方法的参数
    CONSTRUCTOR,
    //构造方法
    LOCAL_VARIABLE,
    //本地变量或catch语句
    ANNOTATION_TYPE,
    //注解类型(无数据)PACKAGE//Java包
    }   

2.@Retention(RetentionPolicy) 用于制定编译器处理策略
RetentionPolicy属性详解(jdk java.lang.annotation):

publicenumRetentionPolicy{
SOURCE,
//此类型会被编译器丢弃
CLASS,
//此类型注解会保留在class文件中,但JVM会忽略它
RUNTIME
//此类型注解会保留在class文件中,JVM会读取它
}

3.@Documented 用于制定文档化功能
注意使用此注解时必须设置RetentionPolicy为RUNTIME

4.@Inherited 用于指定允许继承


下面介绍一个注解具体使用实例:动态生成sql语句。

首先定义注解,表名注解@Table和列注解@Column

@Target({ElementType.TYPE}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {

    String value(); //可以有多个值,一个值就必须写value,否则会报错
}

@Target({ElementType.FIELD}) //类或接口可用
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {

    String value(); //一个值就必须写value
}   

然后创建与数据库信息对应的Model类,在其中加入注解。

@Table("User")
public class User {

    @Column("id")
    private int id1;

    @Column("userName")
    private String userName1;

    @Column("nickname")
    private String nickname1;

    @Column("age")
    private int age1;

    @Column("city")
    private String city1;

    public int getId1() {
        return id1;
    }

    public void setId1(int id1) {
        this.id1 = id1;
    }

    public String getUserName1() {
        return userName1;
    }

    public void setUserName1(String userName1) {
        this.userName1 = userName1;
    }

    public String getNickname1() {
        return nickname1;
    }

    public void setNickname1(String nickname1) {
        this.nickname1 = nickname1;
    }

    public int getAge1() {
        return age1;
    }

    public void setAge1(int age1) {
        this.age1 = age1;
    }

    public String getCity1() {
        return city1;
    }

    public void setCity1(String city1) {
        this.city1 = city1;
    }
}



@Table("department")
public class Department {

    @Column("id")
    private int id1;

    @Column("name")
    private String name1;

    @Column("leader")
    private String leader1;

    public int getId1() {   
        return id1;
    }

    public void setId1(int id1) {
        this.id1 = id1;
    }

    public String getName1() {
        return name1;
    }

    public void setName1(String name1) {
        this.name1 = name1;
    }

    public String getLeader1() {
        return leader1;
    }

    public void setLeader1(String leader1) {
        this.leader1 = leader1;
    }
}

下面是用于动态生成Sql语句的方法,传入一个加入@Table和@Column注解的Model类对象。功能还不完善,读者有具体需求可自己增加更复杂的sql动态生成功能。

public static String query(Object f){

        StringBuilder sb = new StringBuilder();

        //1.获取到class
        Class c  = f.getClass();
        //2获取到table的名字
        boolean exists = c.isAnnotationPresent(Table.class);
        if(!exists) return null;
        Table t = (Table)c.getAnnotation(Table.class);
        String tableName = t.value();
        sb.append("select * from ").append(tableName).append(" where 1=1");

        //3.遍历所有的字段     
        Field[] fArray = c.getDeclaredFields();
        for(Field field:fArray){

            //4.处理每个字段对应的sql
            //4.1 拿到字段名
            boolean fexists = field.isAnnotationPresent(Column.class);
            if(!fexists) continue;

            Column column = field.getAnnotation(Column.class);
            String columnName = column.value();

            //4.2 拿到字段的值  通过反射
            String fieldName = field.getName();
            String getMethidName = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
            Object fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethidName);
                fieldValue = getMethod.invoke(f);
            } catch (Exception e) {
                e.printStackTrace();
            }   
            if(fieldValue == null || (fieldValue instanceof Integer && (Integer)fieldValue == 0)) continue;
            //4.3 拼装sql
//          System.out.println(fieldValue.toString());  
            if(fieldValue instanceof String) {

                if(((String) fieldValue).contains(",")){

                    sb.append(" and ").append(columnName).append(" in (");
                    String[] args =fieldValue.toString().split(",");
                    for(String str:args){
                        sb.append("\'").append(str).append("\',");
                    }
                    sb.deleteCharAt(sb.length()-1); //删除最后一个逗号
                    sb.append(")");
                }
                else{

                    sb.append(" and ").append(columnName).append("=").append("\'").append(fieldValue.toString()).append("\'");
                }
            }
            else if(fieldValue instanceof Integer){
                sb.append(" and ").append(columnName).append("=").append(fieldValue.toString());
            }
        }

        return sb.toString(); 
    }

接着进行测试:

public static void main(String[] args) {

        User f1 = new User();
        f1.setId1(10);

        User f2 = new User();
        f2.setUserName1("lucy");

        User f3 = new User();
        f3.setCity1("shenzhen,guangzhou,zhuhai");
        f3.setNickname1("wahaha");
        f3.setUserName1("username");

        System.out.println(query(f1));  
        System.out.println(query(f2));
        System.out.println(query(f3));

        Department d1 = new Department();
        d1.setLeader1("大领导");
        d1.setId1(0);

        Department d2 = new Department();
        d2.setId1(2);

        System.out.println(query(d1));
        System.out.println(query(d2));
    }

打印结果:

select * from User where 1=1 and id=10
select * from User where 1=1 and userName='lucy'
select * from User where 1=1 and userName='username' and nickname='wahaha' and city in ('shenzhen','guangzhou','zhuhai')
select * from department where 1=1 and leader='大领导'
select * from department where 1=1 and id=2
阅读更多
博主设置当前文章不允许评论。
换一批

没有更多推荐了,返回首页