手把手教你写一个java的orm(三)

 

使用反射解析class

上一篇我们完成了class到表映射关系的建立,但是这个并不能被代码正确处理,我们还需要让程序能够正确的识别这些映射关系。

这一篇主要讲的是建立一个从class到表的模型,使我们在class上添加的注解能够正确的被识别并处理。这里主要用到的是java中的反射相关的知识。不了解的同学请自行百度一下,不是很难~,另外这一篇也会稍微的提到一点反射的用法。

现在开始。

我们主要的需求是根绝我们添加的注解,生成各种类型的sql语句,所以我们首先要能够获取添加在java类名,属性,方法上的注解,并获取注解中的值。所以第一步:

获取特定的注解

  1. 获取class上的注解

    在Java的Class中提供了.getAnnotation(annotationClass)的方法,

    这里我在这个方法的基础上包了一层,主要是使用断言做了一些验证,在验证不通过的时候抛出我认识的异常信息。下面的方法都是如此处理的。

    /**  * 获取类上的注解  *  * @param clz  * @param annotationClass  * @param <T>  * @return  */ public static <T extends Annotation> T getAnnotation(Class<?> clz, Class<T> annotationClass) {     Assert.notNull(clz, CLASS_NOT_NULL);     Assert.notNull(annotationClass, ANNOTATIONCLASS_NOT_NULL);     return clz.getAnnotation(annotationClass); }
  2. 获取属性上的注解

    /**  * 获取属性上的注解  *  * @param field  * @param annotationClass  * @param <T>  * @return  */ public static <T extends Annotation> T getAnnotation(Field field, Class<T> annotationClass) {     Assert.notNull(field, FIELD_NOT_NULL);     Assert.notNull(annotationClass, ANNOTATIONCLASS_NOT_NULL);     return field.getAnnotation(annotationClass); }

这里我们获取注解的方法就写完了,可以通过这些方法获取我们需要的注解,并通过获取到的注解拿到其中的值。

大致是这样的:(这里的User.class)可以看 上一篇。

//代码(获取class上的注解) @Test public void getClassAnnotation() {     Table annotation = EntityUtils.getAnnotation(User.class, Table.class);     System.out.println(annotation.name()); } //输出结果 user //代码(获取field上的注解) @Test public void getFieldAnnotation() throws NoSuchFieldException {     Class userClass = User.class;     //getDeclaredField和getField是有一定区别的,这里用getDeclaredField     Field field = userClass.getDeclaredField("createDate");     Column annotation = EntityUtils.getAnnotation(field, Column.class);     System.out.println(annotation.name()); } //输出结果 create_date

这样就可以获取到我们在class上添加的注解,以及注解中的值了。下面是第二步

获取Id以及Column

这里依然是通过反射实现,主要就是获取到这个class中的所有的属性(只属于这个class的,不包括父类)后,循环遍历一遍,根据每个属性上不同的注解加以区分就好了。这里为了简单,我定义了几个方法:

  1. boolean isTable(Class aClass)

    是不是添加了@Table

  2. boolean isColumn(Field field)

    是不是添加了@Column

  3. boolean isId(Field field)

    是不是添加了@Id

这几个方法的具体代码我就不贴出来了,很简单的。下面是取出一个class中所有属性的代码:

for (Field field : clz.getDeclaredFields()) {     if (isColumn(field)) {         //执行需要的操作。     } }

在这个遍历个过程中我们可以新建一个类,里面用来存放表和class的各种对应关系。比如:

  1. class属性名称与表字段名称的对应。
  2. 表中的id是class中哪一个属性。
  3. 表的字段名称对应的是class里的那个个属性。
  4. 等等~~

关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信