zoukankan      html  css  js  c++  java
  • java注解,通过反射解析注解,模仿hibernate,获取sql语句。

    常用注解:

    自定义注解,标准格式:

    1,target:注解作用域

    2,Retention:声明周期

    运行子类继承,但是子类继承只能作用到类注解,字段注解,是继承不了的。

    使用注解:通过下面这种方式,为注解的成员赋值,使用的时候会通过成员名,找到这些值,去使用这些值。

    如果注解只有一共成员,该成员必须命名为value,这样使用注解的时候方便:如:@注解(“值1”),相当于@注解(value=“值1”);

    解析注解:

    解析注解主要用到反射的方式,在下面的例子中可以看到。 

    主要代码如下:

            //1,获取到class
            Class c=f.getClass();
            //2,获取到table的名字
            boolean exists=c.isAnnotationPresent(Table.class);//判断该类Filete是否是包含注解Table
            if(!exists)
            {
                return null;
            }
            Table t=(Table) c.getAnnotation(Table.class);//取出Filete这个类的Table注解
            String tableName=t.value();//获取该注解的值

    使用注解模仿hibernate获取sql的方法。

    1,定义两个注解,Table和column

    package com.Annotation;
    
    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 Table {
        String value();
    }

    package com.Annotation;
    
    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 Column {
        String value();
    }

    2,定义一个数据库模型类:并分别在类名和字段名上加上注解,分别跟表名和字段名关联

    package com.Annotation;
    
    @Table("user")
    public class Filter {
        @Column("id")
        private int id;
        @Column("user_Name")
        private String userName;
        @Column("age")
        private int age;
        @Column("city")
        private String city;
        @Column("email")
        private String email;
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String getEmail() {
            return email;
        }
        public void setemail(String email) {
            this.email = email;
        }
    }

    3,通过set字段值,来定义查询条件,定义一共querey方法,同注解,反射获取sql。

    package com.Annotation;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Test {
    
        public static void main(String[] args) {
    
            Filter f1=new Filter();
            f1.setAge(10);//查询id为10的用户
            
            Filter f2=new Filter();
            f2.setCity("大连");//查询城市为大连的用户
            
            Filter f3=new Filter();
            f3.setCity("liu@sina.com,zh@sina.com,8888@163.com");
            //查询邮箱为上面的用户
            
            String sql1=query(f1);
            String sql2=query(f2);
            String sql3=query(f3);
            System.out.println(sql1);
            System.out.println(sql2);
            System.out.println(sql3);
        }
        private static String query(Filter f)
        {
            StringBuffer sb=new StringBuffer();
            //1,获取到class
            Class c=f.getClass();
            //2,获取到table的名字
            boolean exists=c.isAnnotationPresent(Table.class);//判断该类Filete是否是包含注解Table
            if(!exists)
            {
                return null;
            }
            Table t=(Table) c.getAnnotation(Table.class);//取出Filete这个类的Table注解
            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 fExis=field.isAnnotationPresent(Column.class);
                if(!exists)
                {
                    continue;
                }
                Column column=field.getAnnotation(Column.class);//获取该字段上的column注解
                String columnName=column.value();
                
                //4,2,拿到字段的值
                String filedName=field.getName();
                String getMethoudName="get"+filedName.substring(0,1).toUpperCase()+
                        filedName.substring(1);
                Object fieldValue = null;//为了让各种类型的返回值都能接收,定义Object类型
                try {
                    Method getMethod=c.getMethod(getMethoudName);
                    fieldValue=getMethod.invoke(f);//调用f的对应字段的get方法
                } catch (Exception e) {
                    e.printStackTrace();
                } 
                
                //4,3,拼装sql
                if(fieldValue==null||
                        (fieldValue instanceof Integer && (Integer)fieldValue==0))
                {
                    continue;
                }
                sb.append(" and ").append(filedName);
                if(fieldValue instanceof String)    //如果字符串是Int类型,加上单引号
                {
                    if(((String) fieldValue).contains(",")) //包含,,表示是子查询
                    {
                        String []values=((String) fieldValue).split(",");
                        sb.append("in(");
                        
                        for(String v:values)
                        {
                            sb.append("'").append(v).append("'").append(",");
                        }
                        sb.deleteCharAt(sb.length()-1);//去掉最后一个逗号
                        sb.append(")");
                    }
                    else    //否则是普通查询
                    {
                        sb.append("=").append("'").append(fieldValue).append("'");
                    }
                }
                else if(fieldValue instanceof Integer)
                {
                    sb.append("=").append(fieldValue);
                }
            }
            return sb.toString();
        }
    }

    运行结果:

  • 相关阅读:
    cf492D Vanya and Computer Game
    cf492C Vanya and Exams
    cf492A Vanya and Cubes
    bzoj2038 [2009国家集训队]小Z的袜子(hose)
    bzoj3781 小B的询问
    bzoj1858 [Scoi2010]序列操作
    bzoj1060 [ZJOI2007]时态同步
    算法学习心得
    bzoj1054 [HAOI2008]移动玩具
    bzoj3437 小P的牧场
  • 原文地址:https://www.cnblogs.com/alsf/p/8309768.html
Copyright © 2011-2022 走看看