使用APT封装MyBatis的单表操作(一)

背景

原来的项目,经常使用hibernate作为持久层框架。但是随着智能手机兴起等各方面的因素,现在早已经跨入了互联网时代。

在互联网的大环境下,Java也需要与时俱进,现在企业越来越多的都是需要搭建互联网服务器,不是针对某个公司,某个企业,而是针对全国甚至是全球。在这种前提之下,系统的高并发、高性能就的处理能力就变得尤为重要。

hibernate作为曾经orm框架的首选者,在互联网时代却处于非常尴尬的地步。高度的封装给程序员带来了最大化的便利,只需简单几个方法就能实现数据库的各种操作,程序员完全无需关心sql语句的编写,曾经这种高度自动化的封装几乎让hibernate一统天下,但是随着程序对性能的要求越来越高的同时,这种程序员无法干预sql语句的做法,反而不利于sql语句的优化,在某些需要对sql进行高度优化的需求面前,hibernate就显得无能为力。这个时候,MyBatis就进入了大家的视野。

MyBatis使用的是半自动化的封装,对程序员来说sql还是需要手写的,另外对存储过程的良好兼容,让一些对sql语句性能有着高度要求的系统找到了很好的解决方案。为了顺应时代的号召,笔者也开始学着如何使用Mybatis。

问题

使用Mybatis后,发现没有了Hibernate那种单表操作的封装方式(BaseDao的抽取)。也百度了很久,发现除了官方给的逆向 工程,实在是没有一套方便、快捷的单表操作方案,而逆向工程配置有点繁琐,配置文件复杂,而且有些需求问题还需要通过修改源码解决,实在太不友好。查了很久,最后还是打算自己写一套出来。大概的思路,是采用JDK1.6提供的APT接口,自动的生成对应的映射器文件,从而 实现单表的一系列操作。(注意,APT在JDK1.8以后被oracle移除,取代方案还未研究)

图解



APT

APT(Annotation Procession Tools)意思为注解处理工具。主要的作用就是在编译期根据自定义的注解自动的进行某些操作,比如修改代码、生成配置文件等。APT主要运行在编译期,所以不同于反射,APT对运行效率不会造成额外的开销。在一次编译的过程中,APT可能会别调用好几次。对于运行效率要求更高的android开发来说,APT使用的频率更高,但是在JavaEE方面,却很少有听到APT的用武之地。故这里先对APT进行一个简单的演示。

环境:
开发工具-Eclipse
JDK版本-1.7

首先创建一个普通的Java工程。创建一个自定义注解:
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {

    String value() default "Hello";
}
需要注意一点,注解的Retention必须设置为RetentionPolicy.CLASS,表示在编译期可以访问。

接下来需要创建一个类,继承AbstractProcessor类。这个类就是注解处理器。里面定义了一系列工具类方便我们获取或者操作目标类。

@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes({"com.apt.MyAnnotation"})
public class MyProcession extends AbstractProcessor{
    
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return false;
    }
}
这里需要介绍下@SupportedSourceVersion@SupportedAnnotationTypes两个注解:
@SupportedSourceVersion是用于声明当前JDK的版本,这里为JDK7。
@SupportedAnnotationTypes很关键,用于标识当前这个注解处理器会去处理什么哪个注解所标注的类(在案例中,表示被@MyAnnotation所标注的类一旦被编译器编译,则会触发注解处理器)

继承AbstractProcessor类后,则必须重写process方法,该方法就是注解处理器触发时需要执行的方法,我们希望注解处理器帮助我的做什么事情,核心的代码就是写在这个方法中。


接下来编写process方法中的代码:
private Messager messager;

@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
  super.init(processingEnv);
  messager = processingEnv.getMessager();
}        

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		
  //获得所有注解了MyAnnotation的类集合 - 每个类对于APT来说就是一个Element对象
  Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(MyAnnotation.class);
  //循环遍历所有节点(映射接口)
  for(Element ele : elements){
    //输出测试信息
    messager.printMessage(Kind.WARNING, "测试信息!!!!!!" + ele.getSimpleName(), ele);
  }
  return true;
}	
大概含义已经用注解解释的很清楚了,这里需要说下,因为process方法是在编译时运行的,所以不能用System.out.println();输出语句输出信息。这里采用了APT给我们提供的一个信息输出工具类Messager。Messager的获取是在另一个重写方法init中获得的,在init中还可以获得后续我们需要用到的一些工具类。

至此,我们的MyProcession类编写完毕,接下来需要注册一下
在src目录下创建一个如下结构的文件:


  文件内容如下:
com.qf.apt.procession.MyProcession (即AbstractProcessor实现类的全路径

最后将该工程导出成为jar包,APT的工具类就编写完成了。

测试

  将上一步导出的jar包引入到测试工程中:


  设置启用apt(关键)

右键工程 -> Properties -> Java Compiler -> Annotation Processing,如图:


接着设置Annotation Processing下的Factory Path,点击Add JARs...,选中APT生成的jar包。然后点击Advanced...,选中MyProcess类,具体如下图:


启动APT完成后,指定一个类,标注上@MyAnnotation:
 
@MyAnnotation
public class TestAnnotation {

}
ctrl + s 保存该类,会触发Eclipse的自动编译,这时会看到Problems页签下输出测试信息:


说明该类编译时,触发了我们编写的APT方法,至此,一个APT的使用小案例就完成了。



  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值