反射+自定义注解 实现(数据库语句的生成)

由于在前面写自定义注解的时候,实在不好写demo演示,当然也说了学完一些反射之后,再来写一个demo,那就趁着今天周末有空,写一个 传入Class,自动生成数据库语句的demo吧

1.首先看使用吧 

String userSql = SqlSentence.create(User.class); //数据库语句创建的调用实例
结果:create table UserTable(id integer primary key autoincrement,userName varchar(8),info text,password varchar(16))

2.看User类

public class User {

    @SqlField(length = 8)
    private String userName; //生成的数据语句是 userName varchar(8)
    @SqlField
    private int password; //生成的数据语句是 password varchar(16) 因为默认长度是16
    @SqlField(type = "text")
    private String info; //生成的数据语句是 info text
    private int age; //没有申明@SqlField注解 不生成
    private String sex; //没有申明@SqlField注解 不生成

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getPassword() {
        return password;
    }

    public void setPassword(int password) {
        this.password = password;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public int getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

3.看自定义注解类SqlField

/**
 * 配置数据库语句字段
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface SqlField {

    /**
     * 字段的类型
     * @return varchar
     */
    String type() default "varchar";

    /**
     * 字段的长度
     * @return 16
     */
    int length() default 16;
}

4.看SqlSentence类

public class SqlSentence {

    private SqlSentence() { /* cannot be instantiated */ }

    private final static String VARCHAR = "varchar";

    /**
     * @param clz class
     * @return sqlite sentence
     */
    public static <T> String create(Class<T> clz) {
        if (clz == null) {
            return null;
        }
        try {
            Object instance = Class.forName(clz.getName()).newInstance();
            Class<?> aClass = instance.getClass();
            Field[] fields = aClass.getDeclaredFields();
            StringBuilder sb = new StringBuilder();
            for (Field field : fields) {
                field.setAccessible(true); 
                if (field.isAnnotationPresent(SqlField.class)) { //判断是否存在此注解
                    SqlField sqlField = field.getAnnotation(SqlField.class); //获取此注解
                    String fieldName = field.getName();
                    String type = sqlField.type();
                    int length = sqlField.length();
                    if (type.contains(VARCHAR)) {
                        sb.append(fieldName).append(" " + VARCHAR + "(").append(length).append("),");
                    } else { //用户自定义类型
                        sb.append(fieldName).append(" ").append(type).append(",");
                    }
                }
            }
            int length = sb.toString().length();
            if (length > 1) { //使用生成的字符串长度判断是否存在注解 
                sb = sb.deleteCharAt(sb.toString().length() - 1); //删除字符串的最后一个字符
                return "create table " + clz.getSimpleName() + "Table" + "(id integer primary key autoincrement," + sb + ")";
            } else {
                throw new NullPointerException("No @SqlField annotations are configured on a field");
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}

 
 
 好了,一个简单的反射+自定义注解实现生成数据库语句的demo就ok了,如果对Android开发有所了解的人,可以看一看我在

Android系列中所写的Sqlite数据库SDK,这是一个完全运用到反射+自定义注解去写的一个小框架,当然如果在Android系列中
没有这篇文章,说明我暂时还木有更新上去。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来解答你的问题。 首先,我们需要定义一个自定义注解来标识我们需要从配置文件中加载的属性。我们可以定义一个名为`@ConfigProperty`的注解: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ConfigProperty { String value() default ""; } ``` 接下来,我们需要编写一个配置类来加载配置文件中的属性。这个类需要使用反射来动态地设置属性值。我们可以使用`@ConfigurationProperties`注解来指定配置文件的位置,然后使用`@Value`注解来注入属性值。 ```java @ConfigurationProperties("example") public class Config { @Value("${example.names}") @ConfigProperty("names") private String[] names; // getter and setter methods } ``` 在上面的代码中,我们使用了`@ConfigurationProperties`注解来指定配置文件的位置为`example`。然后,我们使用`@Value`注解来注入`example.names`属性的值,并使用`@ConfigProperty`注解来标识这个属性对应的字段名为`names`。 最后,我们需要编写一个配置类来将配置文件中的属性加载到我们的配置类中。我们可以使用`@ImportResource`注解来指定配置文件的位置,并使用`@Import`注解来导入我们的配置类。 ```java @Configuration @ImportResource("classpath:application.properties") public class AppConfig { @Bean public Config config() { Config config = new Config(); for (Field field : Config.class.getDeclaredFields()) { ConfigProperty annotation = field.getAnnotation(ConfigProperty.class); if (annotation != null) { String propertyName = annotation.value(); if (propertyName.isEmpty()) { propertyName = field.getName(); } String[] propertyValue = environment.getProperty(propertyName).split(","); field.setAccessible(true); field.set(config, propertyValue); } } return config; } } ``` 在上面的代码中,我们使用了`@ImportResource`注解来指定配置文件的位置为`classpath:application.properties`。然后,我们编写了一个`config()`方法来加载配置文件中的属性。我们首先获取`Config`类中所有标记了`@ConfigProperty`注解的字段,然后使用`environment.getProperty()`方法获取属性值,并使用反射动态地设置属性值。 这样,我们就可以在配置文件中使用数组来配置属性了。例如,我们可以在`application.properties`文件中添加以下内容: ``` example.names=John,Doe ``` 然后,在我们的代码中使用`Config`类来获取这些属性值: ```java @Autowired private Config config; public void someMethod() { System.out.println(Arrays.toString(config.getNames())); } ``` 输出结果应该为`[John, Doe]`。 希望这个回答能够帮助到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值