文档章节

java注解小实例

trayvon
 trayvon
发布于 2016/03/23 08:37
字数 750
阅读 122
收藏 5

      我希望通过注解来生成一个实体类对应表的的SQL语句。所以写了两个注解类,一个Table标识要生成SQL的实体类,一个Column用来标识要映射到表的字段。一个简单的实体类User和一个注解的工具类GenerateTableUtil。代码只是为了更加了解注解。所以处理注解的工具类GenerateTableUtil非常的不完善,如果你感兴趣可以完善一下注解工具类贴出来分享给大家。

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() default "";
}
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 {
    //一般只有一个值,就使用value。这样在使用注解时就可以像@Column("id")这样使用,否则如果我们使用id就要@Column(id="id")
    //一般可以使用default加上默认值,这里就默认为空,我们可以在处理注解的时候把字段的名字当做value的值
    String value() default "";
}
@Table
public class User {
    
    @Column
    private int id;
    
    @Column
    private String name;
    
    @Column
    private String phone;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    
}
import java.lang.reflect.Field;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class GenerateTableUtil {
    public static void generateSQL(Class<?> clazz)
    {
        Table tableAnnotation = null;
        if(clazz.isAnnotationPresent(Table.class))//检查类上是否有Table注解
          tableAnnotation = clazz.getAnnotation(Table.class);
        else
            return;
        String tableName = tableAnnotation.value();
        if(null ==tableName || tableName.length()==0)
            tableName = clazz.getSimpleName().toUpperCase();
        
        Field[] fields = clazz.getDeclaredFields();
        Map<String,String> cols = new HashMap<String,String>();
        //检查有Column注解的字段,如果有则映射到数据库的字段上
        for(Field field:fields)
        {
            Column columnAnnotation = null;
            if(field.isAnnotationPresent(Column.class))
             {
                columnAnnotation = field.getAnnotation(Column.class);
                String colName = columnAnnotation.value();
                if(null == colName || colName.length()==0)
                    colName = field.getName().toUpperCase();
                Class<?> type = field.getType();
                String jdbcType = "VARCHAR(20)";
                try {
                  //最好不要在这里捕获异常,因为字段转换已经出错了。这里简化了处理如果类型不支持就直接使用默认值
                    jdbcType = getJdbcType(type);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                cols.put(colName, jdbcType);
             }
        }
        System.out.println(joinSQL(tableName,cols));
    }
    
    /**
     * 没有判断所有的数据类型,映射关系不完整
     * @param type java的类型的class
     * @return 数据库的类型
     * @throws Exception 没有构造自己的异常
     */
    private static String getJdbcType(Class<?> type) throws Exception
    {
        if(type.isAssignableFrom(int.class)||type.isAssignableFrom(Integer.class))
            return "INT";
        if(type.isAssignableFrom(String.class))
            return "VARCHAR(20)"; //字符串数据的长度默认为20,不可取只是测试
        if(type.isAssignableFrom(char.class))
            return "CHAR(20)";
        if(type.isAssignableFrom(Date.class))
            return "DATETIME";
        if(type.isAssignableFrom(long.class)||type.isAssignableFrom(Long.class))
            return "BIGINT";
        if(type.isAssignableFrom(float.class)||type.isAssignableFrom(Float.class))
            return "FLOAT";
        if(type.isAssignableFrom(double.class)||type.isAssignableFrom(Double.class))
            return "DOUBLE";
        else
            throw new Exception("数据类型不支持");
    }
    
    /**
     * 根据名字和字段生成SQL语句
     * @param tableName
     * @param fields
     * @return
     */
    private static String joinSQL(String tableName,Map<String,String> fields)
    {
        StringBuffer sb = new StringBuffer("CREATE TABLE ");
        sb.append(tableName);
        sb.append('(');
        Set<Entry<String,String>> entrySet = fields.entrySet();
        for(Entry<String, String> entry:entrySet)
        {
            sb.append(entry.getKey());
            sb.append(" ");
            sb.append(entry.getValue());
            sb.append(',');
        }
        sb.replace(sb.length()-1, sb.length(), ")");
        return sb.toString();
    }
    public static void main(String[] args) {
        generateSQL(User.class);
    }
}


© 著作权归作者所有

下一篇: Zookeeper初遇
trayvon
粉丝 16
博文 129
码字总数 191361
作品 1
程序员
私信 提问
IOC/AOP工具 - jBeanBox

jBeanBox是一个微形但功能较齐全的IOC/AOP工具适用于JAVA7+,利用了Java的初始化块实现的Java配置代替XML。jBeanBox采用Apache License 2.0开源协议。 其他一些IOC/AOP框架的问题: 1)Sprin...

yong9981
2016/07/25
0
14
Spring AOP切点表达式详解

简介 面向对象编程,也称为OOP(即Object Oriented Programming)最大的优点在于能够将业务模块进行封装,从而达到功能复用的目的。通过面向对象编程,不同的模板可以相互组装,从而实现更为...

张旭峰
2018/06/05
0
2
通过 HttpAuthenticationMechanism 执行 Web 身份验证

通过 Java EE 8 中新的注解驱动的 HTTP 身份验证机制执行经典和自定义的 Servlet 身份验证 系列内容: 此内容是该系列 4 部分中的第 # 部分: Java EE 8 Security API 入门,第 2 部分 http...

Alex Theedom
2018/04/02
0
0
springboot原理—一步步分析springboot启动机制(starter机制)

前言 使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程。本文的目的就是一步步分析springboot的启动过程,分析s...

编程SHA
02/15
0
0
迷你版Spring MVC 实现

迷你版Spring MVC 实现 本文参考自 写出我的第一个框架:迷你版Spring MVC ,写这篇文章用于个人学习的记录。 项目建立 首先,建立一个空Maven项目,在java目录下,建立以下包结构。 接下来,...

旺仔没馒头
01/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

八、RabbitMQ的集群原理

集群架构 写在前面 RabbitMQ集群是按照低延迟环境设计的,千万不要跨越WAN或者互联网来搭建RabbitMQ集群。如果一定要在高延迟环境下使用RabbitMQ集群,可以参考使用Shovel和Federation工具。...

XuePeng77
今天
1
0
mac系统下,brew 安装mysql,用终端可以连接,navicat却连接不上?

问题: 1.报错? 2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(../Frameworks/caching_sha2_password.so, 2): image not found 2.自己通过设置,已经把密......

写bug的攻城狮
昨天
2
0
老生常谈,HashMap的死循环

问题 最近的几次面试中,我都问了是否了解HashMap在并发使用时可能发生死循环,导致cpu100%,结果让我很意外,都表示不知道有这样的问题,让我意外的是面试者的工作年限都不短。 由于HashMap...

群星纪元
昨天
5
0
拉普拉斯算子

拉普拉斯算子是二阶微分算子。 我们知道,一维离散信号一阶微分公式如下: 相应的,一维离散信号二阶微分公式如下: 由于图像有x和y两个方向,因此图像信号属于二维离散信号。其在x,y两个...

yepanl
昨天
3
0
记录"正则表达式"

详细请查看我的博客:https://blog.enjoytoshare.club/article/RegularExpression.html 1 写在前面 正则表达式(Regular Expression)在代码中常常简写为regex。正则表达式通常被用来检索、替...

wugenqiang
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部