自定义注解应用

该博客介绍了一个替代Hibernate的持久层架构项目,通过注解实现类与数据库表的映射,允许对字段进行检索并自动生成SQL。文章详细展示了如何定义用户类,创建注解,以及如何拼接SQL查询语句,最后给出了方法调用和输出结果的示例。

需求背景

项目说明

    项目取自一个公司的持久层架构,用来代替 Hibernate 的解决方案,核心代码就是通过注解来实现的。

项目需求

  需求1:有一张用户表,字段包括用户ID,用户名,呢称,年龄,性别,所在城市,邮箱,手机号。
  需求2:方便对每个字段或字段的组合条件进行检索,并打印出SQL。
  需求3:使用方式要足够简单,见代码示例。

需求实现

实现思路:

1、定义用户类
2、通过类注解和字段注解的方式,实现l数据库表名与字段所对应
3、通过注解拿到表名和字段名
4、通过反射拿到对应字段的值
5、拼接sql语句字符串

具体如下:
1、定义用户类,生成getter和setter方法

@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;
    @Column("mobile")
    private String mobile;

    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;
    }
    public String getMobile() {
        return mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}

2、自定义注解修饰类和字段

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}

3、拼接sql语句

private static String query(Object obj) {
        StringBuffer sb = new StringBuffer();
        //1.获取到class
        Class c = obj.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[] fieldArray = c.getDeclaredFields();
        for (Field field : fieldArray) {
            //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 fileName = field.getName();
            String getMethodName = "get" + fileName.substring(0, 1).toUpperCase() + fileName.substring(1);
            Object fieldValue = null;
            try {
                Method method = c.getMethod(getMethodName);
                fieldValue = (Object) method.invoke(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //4.3拼装sql
            if (fieldValue == null || (fieldValue instanceof Integer && (Integer) fieldValue == 0)) {
                continue;
            }
            sb.append(" and ").append(columnName);
            if (fieldValue instanceof String) {
                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();
    }

4、方法调用

 public static void main(String[] args) {
        Filter f1 = new Filter();
        f1.setId(10);

        Filter f2 = new Filter();
        f2.setUserName("lucy");

        Filter f3 = new Filter();
        f3.setEmail("liu@qq.com,wangli@yahu.com,23432423@qq.com");

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

    }

5、控制台打印
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值