反射获取由注解信息构进行sql查询

java注解学习笔记
一、jdk中的注解
jdk中都属于编译时注解,在编译前就会提示错误,总共有两种注解:

@Deprecated 注解
表示方法已过时
@Suppress Warning注解:忽略由Deprecated注解造成的警告
二、java第三方注解
这里只列举了Spring和Mybatis中常见的几个

Spring中的注解
@Autowired注解
@Service注解
@Repository注解
Mybatis中的注解
@InsertProvider
@UpdateProvider
@Options
三、注解的分类
源码注解
编译时注解
运行时注解
元注解:给注解进行注解
@Target(ElementType.XXXX)
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
  取值(ElementType)有:
    1. CONSTRUCTOR:用于描述构造器
    2. FIELD:用于描述域即类成员变量
    3. LOCAL_VARIABLE:用于描述局部变量
    4. METHOD:用于描述方法
    5. PACKAGE:用于描述包
    6. PARAMETER:用于描述参数
    7. TYPE:用于描述类、接口(包括注解类型) 或enum声明
最常用的TYPE(描述类)、METHOD(描述方法)、FIELD(描述成员变量)
@Retention(RetentionPolicy.RUNTIME)
Inherited :是一个标记注解。
@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
Documented :是一个标记注解,表示可用于javadoc工具的文档化
四、自定义注解
成员类型是受限的,合法的类型包括原始类型及String, Class, Annotation, Enumeration
同一个类文件只能被同一个类加载器对象加载一次

最简化的注解定义:

@Target({ ElementType.TYPE})   //定义在类上的注解
@Retention(RetentionPolicy.RUNTIME)     //运行时注解
@Inherited   //可被继承
@Documented   //可用于文档化
public @interface UdfAnnotation {
    String value();
}

五、代码实操
通过反射机制获取由注解标记的信息并构建sql查询语句


/**
 * Person实体类,通过Table和Column注解标记表名和列明
 */
@Table("person")
public class Person {

    @Column("id")
    private String id;

    @Column("name")
    private String name;

    @Column("age")
    private Integer age;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Column自定义注解
 */
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Table自定义注解,用于标记表名
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    public String value();
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 测试类,用于从注解中获取信息并构建sql语句
 */
public class Test {

    public static void main(String[] args){

        Person p1 = new Person();
        p1.setId("1");

        Person p2 = new Person();
        p2.setName("kevin,lily");

        Person p3 = new Person();
        p3.setAge(10);

        String q1 = query(p1);
        String q2 = query(p2);
        String q3 = query(p3);

        System.out.println(q1);
        System.out.println(q2);
        System.out.println(q3);
    }

    public static String query(Object obj){
        StringBuilder sql = new StringBuilder();

        try {
            Class c = Class.forName("com.example.demo.bases.reflect.project.Person");
            if (c.isAnnotationPresent(Table.class)){
                Table table = (Table)c.getAnnotation(Table.class);
                String tableName = table.value();
                //System.out.println(tableName);
                sql.append("select * from ").append(tableName).append(" where 1=1");

                Field[] fields = c.getDeclaredFields();
                for(Field field : fields){
                    String columnName = ((Column)field.getAnnotation(Column.class)).value();
                    //System.out.println("列名:"+columnName);

                    // 得到方法名,并利用invoke通过方法名获取到参数值
                    String methodName = "get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
                    //System.out.println("方法名:"+methodName);
                    Method method = c.getDeclaredMethod(methodName);
                    Object mValue = method.invoke(obj);
                    //System.out.println("方法值:"+mValue);

                    if (mValue instanceof Integer){
                        sql.append(" and ").append(columnName).append("=").append(mValue);
                    }
                    if (mValue instanceof String){
                        if (((String) mValue).contains(",")){
                            String[] values = ((String)mValue).split(",");
                            for (String value : values){
                                sql.append(" and ").append(columnName).append("=").append("'").append(value).append("'");
                            }
                        }else{
                            sql.append(" and ").append(columnName).append("=").append("'").append(mValue).append("'");
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return sql.toString();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值