Java注解(Annotation)用法:利用注解和反射机制指定列名导出数据库数据

  闲来没事,想了一个应用的例子:用java如何把数据库的数据根据我们指定的某几列,如第2列,第4列,第6列导出来到Excel里

写代码也是为了应用的,写好的代码更重要的是在于思考。我自己思考了这个示例。

问题:指定列把数据库数据根据列导出到Excel里。

  那么要处理这个问题,它其实是很简单的,但是再简单的问题,也需要去拆分,思考,所谓,麻雀虽小,五脏俱全嘛。

拆分:1. Load DB data; 2. 把数据和指定列映射起来;3. 导出数据到Excel。

  本文把第一步操作省略了,第一步操作就是读取数据库的数据,然后把它映射到Entity上去,也就是下面代买的Student.java,我们假设这一步已经成功。

以下三个类重点实现第二步,第三步,只要把已经map好的数据,导出到Excel,可以利用apache poi,详见前一篇文章:java POI创建Excel示例(xslx和xsl区别 )

  第二步的实现我之前想着是直接把类的get方法用case的方式跟传进去的参数一一匹配,然后每次写数据的时候执行那个方法来获取当前要导出的列的数据。

如下:

1 public static Object getStudentInfo(Student student, int index) {
2     switch(index) {
3     case 1 :
4         return student.getName();
5     case 2 :
6         return student.getSex();
7     ...
8     }
9 }

可是这样看起来太傻逼了,于是接着想有没有比较合理的方式实现呢?

后来想到了用注解和java的反射机制来实现。

现在java注解用途越来越广泛了,如Google的Guice,一轻量级的IOC框架,大有跟Spring抗衡的趋势。

我就用注解来标注get方法获取的数据在数据库中对应列的索引,然后,根据传进去的列数组匹配get方法,再利用java的反射,执行方法体获取列的数据。具体代码如下。

MapValue是一个Annotation,里面只有一个index()方法,用来标注方法的索引。

 1 package com.cnblogs.rolf.dao;
 2 
 3 
 4 import java.lang.annotation.ElementType;
 5 import java.lang.annotation.Retention;
 6 import java.lang.annotation.RetentionPolicy;
 7 import java.lang.annotation.Target;
 8 /**
 9  * 放在方法上的注解,这个注解可以映射方法的索引
10  * @author 草原战狼
11  *
12  */
13 @Target(value = {ElementType.METHOD})
14 @Retention(RetentionPolicy.RUNTIME)
15 public @interface MapValue {
16     /**
17      * 标注方法的索引
18      * @return 方法索引值
19      */
20     int index() default 0;
21 }
View MapValue Code

Student类是用来map到数据库的实体类,上面的get方法用MapValue标注了它在数据库中表列的顺序。

 1 package com.cnblogs.rolf.entity;
 2 
 3 import com.cnblogs.rolf.dao.MapValue;
 4 
 5 /**
 6  * Student 相当于一个表的实体类,我们可以假想它是从数据库读出来映射出来的一张表信息
 7  * STUDENT_COLUMN_NAMES: 这张表的类名
 8  * @author 草原战狼
 9  *
10  */
11 public class Student {
12     public static String[] STUDENT_COLUMN_NAMES = {"Name", "Sex", "Age", "Height", "Weight", "Grade"};
13     private String name;
14     private String sex;
15     private int age;
16     private int height;
17     private int weigth;
18     private int grade;
19     
20     public Student(String name, String sex, int age, int height, int weight, int grade) {
21         this.name = name;
22         this.sex = sex;
23         this.height = height;
24         this.weigth = weight;
25         this.age = age;
26         this.grade = grade;
27     }
28     public Student() {
29         
30     }
31     
32     @MapValue(index = 1)
33     public String getName() {
34         return name;
35     }
36     public void setName(String name) {
37         this.name = name;
38     }
39     @MapValue(index = 2)
40     public String getSex() {
41         return sex;
42     }
43     public void setSex(String sex) {
44         this.sex = sex;
45     }
46     @MapValue(index = 3)
47     public int getAge() {
48         return age;
49     }
50     public void setAge(int age) {
51         this.age = age;
52     }
53     @MapValue(index = 4)
54     public int getHeight() {
55         return height;
56     }
57     public void setHeight(int height) {
58         this.height = height;
59     }
60     @MapValue(index = 5)
61     public int getWeigth() {
62         return weigth;
63     }
64     public void setWeigth(int weigth) {
65         this.weigth = weigth;
66     }
67     @MapValue(index = 6)
68     public int getGrade() {
69         return grade;
70     }
71     public void setGrade(int grade) {
72         this.grade = grade;
73     }
74 }
View Student Code

TestMain是测试的类,里面还有两个方法,这两个方法是用来处理实体类和要导出列数组的匹配。

 1 package com.cnblogs.rolf;
 2 
 3 import java.lang.reflect.InvocationTargetException;
 4 import java.lang.reflect.Method;
 5 
 6 import com.cnblogs.rolf.dao.MapValue;
 7 import com.cnblogs.rolf.entity.Student;
 8 /**
 9  * 可以应用在从数据库导出数据,根据指定要导出的列,导出到Excel, Word等。这个只是中间的环节
10  * @author 草原战狼
11  *
12  */
13 public class TestMain {
14     public static void main(String[] args) {
15         Student student = new Student("XiaoMing", "Male", 20, 175, 135, 2);
16         int[] indexs = {34,2,5,3,0,1,2,4,6};
17         System.out.println(student.getAge());
18         String[] names = Student.STUDENT_COLUMN_NAMES;
19         String printColumns = getColumnName(names, indexs);
20         String pringStudentInfo = getStudentInfo(student, indexs);
21         System.out.println(printColumns);
22         System.out.println(pringStudentInfo);
23     }
24     /**
25      * 接收一张表的实体类和外面传进来的要导出的列的索引顺序,比如要导出第2列,第4列,那么可以传入{2,4}
26      * 返回获取到的指定列的值
27      * @param student 表的实体类
28      * @param indexs 要导出的列的索引
29      * @return 指定列的值
30      */
31     public static String getStudentInfo(Student student, int[] indexs) {
32         String studentInfo = "";
33         Method[] methods = Student.class.getMethods();
34         for(int index : indexs) {
35             for(Method method : methods) {
36                 MapValue mapValue = method.getAnnotation(MapValue.class);
37                 if(mapValue == null){
38                     continue;
39                 }else {
40                     if(index == mapValue.index()) {
41                         Object value = null;
42                         try {
43                             value = method.invoke(student);
44                         } catch (IllegalAccessException
45                                 | IllegalArgumentException
46                                 | InvocationTargetException e) {
47                             System.out.println("parameters number is wrong.");
48                             e.printStackTrace();
49                         }
50                         studentInfo += value.toString() + ", ";
51                         break;
52                     }
53                 }
54             }
55         }
56         return studentInfo;
57     }
58     /**
59      * 根据指定的索引导出列的名称
60      * @param names 整张表所有列的名称
61      * @param indexs 要导出的列的索引
62      * @return 导出的列的名称
63      */
64     public static String getColumnName(String[] names, int[] indexs) {
65         String result = "";
66         for(int index : indexs) {
67             if(index > names.length || index < 1) {
68                 continue;
69             }
70             result += names[index - 1] + ", ";
71         }
72         return result;
73     }
74 }
View TestMain Code

测试的结果:

Sex, Weight, Age, Name, Sex, Height, Grade, 
Male, 135, 20, XiaoMing, Male, 175, 2, 

草原战狼淘宝小店:http://xarxf.taobao.com/ 淘宝搜小矮人鞋坊,主营精致美丽时尚女鞋,为您的白雪公主挑一双哦。谢谢各位博友的支持。

 

====================================================================================

 

======================    以上分析仅代表个人观点,欢迎指正与交流   =========================

 

======================    草原战狼博客,转载请注明出处,万分感谢   =========================

 

====================================================================================

posted @ 2014-03-14 16:59  草原战狼  阅读(4420)  评论(0编辑  收藏  举报
草原战狼淘宝小店

No one indebted for others,while many people don't know how to cherish others.

No one indebted for others,while many people don't know how to cherish others.

Don‘t cry because it is over, smile because it happened.

Don‘t try so hard, the best things come when you least expect them to.