知识大全 使用Annotation设计持久层

Posted

篇首语:贵有恒何必三更眠五更起,最无益只怕一日曝十日寒。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 使用Annotation设计持久层相关的知识,希望对你有一定的参考价值。

使用Annotation设计持久层  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

    这篇文章的想法来自于过去的两篇文章 《设计自己的MVC框架》《设计模式之事务处理》链接 代码下载同样在的邮箱里 用户名 sharesources 密码 javafans    本文只是学习性质的文章 我一开始的想法就是修改《设计模式之事务处理》 提供Annotation来提供事务支持 支持到方法级别 通过引入一个 @Transaction标注 如果被此标注的方法将自动享受事务处理 目的是学习下Annotation和加深下对声明式事务处理的理解     Annotation是JDK 引入的新特性 现在越来越多的框架采用此特性来代替烦琐的xml配置文件 比如hibernate ejb  spring等 对Annotation不了解 请阅读IBM网站上的文章 还有推荐javaeye的Annotation专栏 ///subject/Annotation    代码的示例是一个简单的用户管理例子     首先 环境是mysql+jdk +myeclipse +tomcat 在mysql中建立一张表adminusers:
        create table adminusers(id  int( ) auto_increment not  null primary key      name varchar( ) not  null      password varchar( ) not  null      user_type varchar( ));
     然后在tomcat下建立一个数据源 把代码中的strutslet xml拷贝到tomcat安装目录下的 /conf/Catalina/localhost目录里 请自行修改文件中的数据库用户名和密码 以及数据库名称 另外 把mysql的 jdbc驱动拷贝到tomcat安装目录下的mon/lib目录 这样数据源就建好了 在web xml中引用
       <resource ref>         <description>DB Connection</description>         <res ref name>jdbctest</res ref name>         <res type>javax sql DataSource</res type>         <res auth>Container</res auth>     </resource ref>
        我的例子只是在《设计模式之事务处理》的基础上改造的 在那篇文章里 我讲解了自己对声明式事务处理的理解 并利用动态代理实现了一个 TransactionWrapper(事务包装器) 通过业务代理工厂提供两种版本的业务对象 经过事务包装的和未经过事务包装的 我们在默认情况下包装业务对象中的所有方法 但实际情况是 业务对象中的很多方法不用跟数据库打交道 它们根本不需要包装在一个事务上下文中 这就引出了 我们为什么不提供一种方式来配置哪些方法需要事务控制而哪些并不需要?甚至提供事务隔离级别的声明?很自然的想法就是提供一个配置文件 类似spring式的事务声明 既然JDK 已经引入Annotation 相比于配置文件的烦琐和容易出错 我们定义一个@Transaction的annotation来提供此功能     看下Transaction java的代码  
         package  strutslet db;      import java lang annotation Documented;      import java lang annotation ElementType;      import java lang annotation Retention;      import java lang annotation RetentionPolicy;      import java lang annotation Target;      import java sql Connection;     @Target(ElementType METHOD)     @Retention(RetentionPolicy RUNTIME)     @Documented      public @ interface Transaction          //事务隔离级别 默认为read_mitted         public  int level()  default Connection TRANSACTION_READ_MITTED    ;     

  @Transaction 标注只有一个属性level level表示事务的隔离级别 默认为Read_Committed(也是一般JDBC驱动的默认级别 JDBC驱动默认级别一般于数据库的隔离级别一致)  @Target(ElementType METHOD)表示此标注作用于方法级别  @Retention(RetentionPolicy RUNTIME)表示在运行时 此标注的信息将被加载进JVM并可以通过Annotation的 API读取 我们在运行时读取Annotation的信息 根据隔离级别和被标注的方法名决定是否将业务对象的方法加进事务控制 我们只要稍微修改下 TransactionWrapper://TransactionWrapper java

    package  strutslet db; import java lang annotation Annotation; import java lang reflect InvocationHandler; import java lang reflect Method; import java lang reflect Proxy; import java sql Connection; import java sql SQLException; import  strutslet exception SystemException; public  class TransactionWrapper           public  static  Object decorate( Object delegate)           return  Proxy newProxyInstance(delegate getClass() getClassLoader()                 delegate getClass() getInterfaces()   new XAWrapperHandler(                         delegate));           static  final  class XAWrapperHandler  implements  InvocationHandler           private  final  Object delegate;         XAWrapperHandler( Object delegate)               // Cache the wrapped delegate  so we can pass method invocations              // to it              this delegate = delegate;                   public  Object invoke( Object proxy   Method method   Object[] args)                  throws  Throwable               Object result =  null;              Connection con = ConnectionManager getConnection();              //得到Transaction标注             Transaction transaction = method getAnnotation(Transaction class);              //如果不为空 说明代理对象调用的方法需要事务控制              if (transaction !=  null)                   // System out println( transaction  + con toString());                  // 得到事务隔离级别信息                  int level = transaction level();                  try                       if (con getAutoCommit())                         con setAutoCommit( false);                      //设置事务隔离级别                     con setTransactionIsolation(level);                      //调用原始对象的业务方法                     result = method invoke(delegate  args);                     mit();                     con setAutoCommit( true);                   catch ( SQLException se)                       // Rollback exception will be thrown by the invoke method                     con rollback();                     con setAutoCommit( true);                      throw  new SystemException(se);                   catch ( Exception e)                      con rollback();                     con setAutoCommit( true);                      throw  new SystemException(e);                                else                  result = method invoke(delegate  args);                           return result;              
 现在 看下我们的UserManager业务接口 请注意 我们是使用动态代理 只能代理接口 所以要把@Transaction标注是接口中的业务方法(与EJB 中的Remote Local接口类似的道理):
    package  strutslet demo service; import java sql SQLException; import  strutslet db Transaction; import  strutslet demo domain AdminUser; public  interface UserManager       //查询 不需要事务控制      public  boolean checkUser( String name   String password)  throws  SQLException;      //新增一个用户 需要事务控制 默认级别     @Transaction      public  boolean addUser(AdminUser user)  throws  SQLException;
     要把addUser改成其他事务隔离级别(比如oracle的serializable级别) 稍微修改下 @Transaction(level=Connection TRANSACTION_SERIALIZABLE)public boolean addUser(AdminUser user) throws SQLException;     不准备详细解释例子的业务流程 不过是登录和增加用户两个业务方法 看下就明白 阅读本文前最好已经读过开头提过的两篇文章 我相信代码是最好的解释 ) cha138/Article/program/Java/hx/201311/26651

相关参考

知识大全 java反射Annotation

java反射Annotation  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  importja

知识大全 springMVC之annotation优化

springMVC之annotation优化  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!lish

知识大全 Annotation之ElementType.PACKAGE

Annotation之ElementType.PACKAGE  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 Java Annotation入门

基础学习教程:JavaAnnotation入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘

知识大全 Hibernate(jpa)复合主键annotation声明方法

Hibernate(jpa)复合主键annotation声明方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起

知识大全 spring用annotation-autowire配置

  <?xmlversion=encoding=UTF?>  <beansxmlns=  xmlns:xsi=instance  xmlns:p=  xsi:schemaLocati

知识大全 学习JPA——Hibernate Annotation使用实例

学习JPA——HibernateAnnotation使用实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 通过Spring2.5对单元测试的Annotation支持进行TDD开发

通过Spring2.5对单元测试的Annotation支持进行TDD开发  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们

知识大全 Hibernate Annotation中BLOB、CLOB注解写法

HibernateAnnotation中BLOB、CLOB注解写法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一

知识大全 设计.NET应用程序数据访问层五大原则

设计.NET应用程序数据访问层五大原则  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要大多数