随笔-67  评论-522  文章-0  trackbacks-0
    在前两章我为大家详细分析了JAR包的选择和必须的配置文件,那么这一章,我就对例子的层次结构进行说明,并实现除WEB层的功能代码。
    第三部分:建立框架代码

    工程结构

    
    大家可以看到,本例一共分为:daoentityserviceweb四层。另外在这些层次下,还以业务功能再进行分包,这样做是为了方便在以后的功能扩展中,能更好的管理和维护代码。如果将所有类都直接集中在这4个包下面,随着类的增加,会越来越难以维护,而且查找起来也很费劲。
    HibernateDao
    在本例中,我是通过继承Spring提供的HibernateDaoSupport来实现持久层的基类。同时引入泛型参数,封装了一些基本操作方法。

    
    这是HibernateDao的部分代码,引入的这个泛型参数,其实就是实体类(UserRole)。通过传递这个实体类,在构造方法中利用反射特性将它从JVM中取出来。
    
    这里的getClass()方法是获得继承HibernateDao的类(UserDaoRoleDao
    getGenericSuperclass()方法就是通过这些继承了HibernateDao的类,来得到父类(父类就是HibernateDao)的泛型。注意这个方法的返回值为Type,这是一个类型接口。请参考API
    因为在继承HibernateDao 的时候,会给它加一个泛型参数。比如,UserRole实体类。因此超类是参数化类型,所以返回的 Type 对象包含所使用的实际类型参数。这里返回的Type对象是ParameterizedType接口的实现类ParameterizedTypeImpl所以要将返回类型转型为ParameterizedType
    getActualTypeArguments()方法是ParameterizedType接口中的,它的作用就是获得实际类型参数 Type 对象的数组,因为我们这里只定义了一个泛型参数,数组里面也只有一个值,所以需要在数组下标处填0。然后最后一步转型千万别忘记了,因为这个方法返回的可是一个Type数组喔。
    如果对于这部分的说明还有点不理解的话,请到时候有了代码,设个断点跟踪一下,就会全部清楚了。关于java反射,它已经超出本文的范围。大象只对本例中用到的部分进行讲解。
    使用这种写法,是方便我们进行类型转换与类型检查。另外还可以简化某些方法的写法。比如:createCriteria(Criterion... criterions)这个方法。参数是Criterion类型的可变参数,它是用来设置查询条件。如果要进行对象化查询,那么最简单的写法就可以直接写成createCriteria()。另外还有重载的方法,可以根据传入class类型来创建自定义查询。
    dao
    持久层的Dao类是根据实体类定义,一般是一个实体类就会有一个对应的Dao类。当然这要跟业务需求来设计,不是绝对的。另外你也可以为了简便而去掉dao层,将持久化操作与业务逻辑全部写在service层。

    
    这些定义的方法是供service层调用,在业务层,将不会看到一行与持久层有关的代码,降低藕合性是这样做的目的。@Repository注解的作用就是标注这个UserDao是一个持久层组件。还记得前一章讲到的扫描器吗?component-scan 它就是用来将标有@Repository@Service这样的注解类扫描到Spring的容器里,并且同时对标有@Autowired注解的Bean启用了自动注入功能。这就是Spring2.5开始提供的新特性。我们使用注解的方法,就可以告别那繁琐的配置文件定义。
    entity
    关于实体的定义就是使用JPA注解,关于这部分,我以前写过一篇文章专门讲这个,如果有不清楚的朋友可以先参考一下。学习JPA——Hibernate Annotation使用实例
    本例中,我有两点要讲下。
    第一、管理主键的表generator_table去掉原来单独定义的那个ID主键,把g_key设为主键,整个表将只有两个字段,g_keyg_value
    第二、在User实体中,我将角色IDrole_id)与角色实体(Role)做了一个多对一关联。这一点是原来文章中没有讲过的。

    
    请一定注意role_iduser表的字段。我在本例中设定的是一个角色可以对应多个人员,所以这个role_id存的就是roleid的值。fetch = FetchType.LAZY指定采用延迟检索,如果当你取得了User对象,但又不想取Role中的信息,这时,User对象中的role属性是代理状态。Role对象中的值都是空的。只有当你使用role.idrole.name进行取值的时候,hibernate才会去数据库中查找对应的记录,因此在一定程度上降低了资源消耗。不过这里有点要注意,采用延迟检索的时候,需要加上前一篇讲到的OpenSessionInViewFilter过滤器。否则会遇到session关闭的异常。
    service
    
    @Service表示这是业务层组件。在业务层需要对UserDao加上@Autowired注解,大象在这里将业务层的方法名与持久层的方法名定义为一样的,是我的一种习惯,大家可以按自己的想法来做。
    测试
    既然有了这么多代码,那就来测试一下吧,看看有没有问题。
    
    好吧,为了照顾那些坚定的JUnit拥护者,再写一个JUnit测试。本例使用junit-4.4.jar
    
    
    @BeforeClass注解的方法表示在类实例化之前,也就是在类的构造方法执行之前就会执行。而且使用这个注解的方法必须是static void
    @Test标明这是测试方法,方法名不用像以前那样必须按照规则进行命名,可以自由定义。
    上图显示大象使用JUnit方式测试也通过了(如果不会通过我写它干嘛?嘿嘿)。
    假如我将张三改成张四,再来看看测试结果

    
    这个截图可以很明显的说明所有东西。
    这一篇是给大家讲怎么用代码来实现除web层之外的全注解步骤。当然,我主要是讲思路,其实思路比代码重要得多。这一个系列的最后,我会放上所有源码供大家下载。现在这样慢慢分析,是想给大家讲道理。我们应该努力提升自己的境界与层次,而不要只把眼光放在代码上面。下一章将会着重介绍web层,以及struts2的注解插件struts2-convention。那么,我们下次继续。
    
本文为菠萝大象原创,如要转载请注明出处。http://www.blogjava.net/bolo
posted on 2010-04-21 22:34 菠萝大象 阅读(13968) 评论(47)  编辑  收藏 所属分类: Struts2

评论:
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 09:22 | cocoa
源码啊~谢谢,哈哈~
cocoaysj@163.com  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 09:57 | 菠萝大象
@cocoa
源码会有的,现在主要是分析,为什么都这么喜欢要源码呢?难道源码比思路和方法都重要吗?我这个例子其实很简单,根本就没有多少技术含量,主要是给大家分析开发的思路以及各部分的原理。我前面两章分析的那么多,难道还不清楚我的想法?要是贴代码,还不简单,也不用花我这么多精力来写了。哎。。。。我的本意看来没多少人能理解。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 14:17 | testxx
楼主水印做的不错哦  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 16:24 | 菠萝大象
@testxx
用加水印的工具生成的,其实我本来是不想弄这么多图片,但是转帖的人太没道德了,都不注明出处。我实在是没办法才出此下策。请不要见怪。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 18:08 | Gavin.lee
呵呵,进度~~ 质量~~ 大象都要抓好啊,继续革命~  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-22 20:15 | 菠萝大象
@Gavin.lee
太费精力了,而且还吃力不讨好,公司的事情也很多,第四篇估计要等到五一,也有可能五一过后,这个说不准,我还是决定以质量为主。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-26 13:57 | songfantasy
大象加油啊?快点出啊 ?  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-04-26 17:50 | 菠萝大象
@songfantasy
不要急,我正在写,质量很重要,请耐心等一下。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-04-30 20:05 | 三国阿海
@菠萝大象
对质量最重要,慢点没事.等清醒的时候写.  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-04-30 20:17 | 三国阿海
菠萝大象,你在方法的上面也添加一点注释.

每次我都要讲页面上下移动看.  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-04-30 20:21 | 三国阿海
@Service表示这是业务层组件

每层的注解都不一样吗?都是什么东西啊.  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-01 09:10 | 菠萝大象
@三国阿海
这些方法上面没加注释一是它们都很好理解,另一个这不是最终的代码,提供下载的源码里面,我会加上详细的注释。目前这样写是为了行文的需要,这是截取的图片,如果注释太多,图片将会非常大,打开时也比较费时。至于你说不清楚@Service之类的注解,你可以看一下spring相关的资料。以前是用@Component来代替@Repository、@Service的,后来为了更明确的区分才像现在这样写。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-05 09:07 | 瓜瓜
不错,楼主继续加油。。。我会经常来的。。。

你那个签名比较那个啥。。。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-05 09:13 | 瓜瓜
呼叫楼主。。。。。struts.xml的配置怎么没有讲??

re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(二)的时候说是后边讲。。


希望你讲解。。嘿嘿  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-05 10:25 | 菠萝大象
@瓜瓜
准备在第四篇的时候讲,其实也什么可讲的,都注解了,这个配置文件里面的东东少的可怜,我把它和web层以及convention插件放到一起来说。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-05-07 21:00 | fw
如果简单的用jdbcdaosupport, 原本在xml定义一个dao是
<bean id="userDao" class="XXX">
<property name="dateSource" ref="dataSource"/>
</bean>
用注解@Repository标记dao以后,代码里面要如何将dataSource注入这个dao呢?  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-05-07 21:02 | fw
接楼上,除了在xml里面用default-autowire=“byName”,谢谢  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-07 23:20 | 菠萝大象
@fw
dataSource只是一个数据源而已,对于dao来说是执行持久化操作,只要它能够获得连接就行,就像你写的,可以把<property name="dateSource" ref="dataSource"/>换成<property name="jdbcTemplate" ref="jdbcTemplate"/>。所以,我想问的就是,你是否采用orm的方式来做?如果你坚持使用jdbc来实现你的程序,那这篇系列不适合你。这个框架是建立在orm的基础之上,面向的都是对象。如果使用jdbc来做,情况会非常糟糕,完全破坏了设计美学。@Repository注解是由spring容器管理的,你不必去关心这些,它会自动加入到容器中,供你使用。而你只需要关注,JdbcDaoSupport,能否提供数据源连接,答案是肯定的,我刚才试了一下,不改变配置文件,重新写了一个JdbcDao,继承JdbcDaoSupport,里面就一个方法,用来进行测试
public T get(Serializable id){
return (T) this.getJdbcTemplate().query("select * from role where id=?",
new Object[]{id},
new RowMapper(){
public Object mapRow(ResultSet rs, int arg1) throws SQLException {
Role role = new Role();
role.setId(rs.getInt("id"));
role.setName(rs.getString("name"));
return role;
}
}
).get(0);
}
将原来RoleDao的继承类改为JdbcDao<Role>,其它不变,测试通过。但以这种方式实现,我只能说非常的不好,我是坚决不会采用这种方式来做的,也不建议大家使用,如果只是学习,那到可以,因为jdbc是基础,这个不能丢,但是真正的实际开发,是不要采取这种方式,你认为“简单的用jdbcdaosupport”,在我看来,却很复杂,同样的根据ID取对象,使用orm方式,只需要很少的代码就能实现,利用泛型可以达到复用的目的,而用jdbc这种方式,不光代码很多,还无法复用,代码全是死的,后期维护更麻烦。你慢慢体会吧。话说的不中听,请你原谅,突然有感而发。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-05-08 23:32 | fw
@菠萝大象
目前确实我还只是初学用struts2+spring, 对hibernate还没有系统学习过,所以目前还只能用spring jdbc来做数据访问,会通过学习过渡到hibernate的。非常感谢你详细的解释。另外注解驱动dao注册到context这种方式貌似确实没有别的办法设置jdbcTemplate需要的dataSource属性了,只有在xml配置里面添加default-autoware="true"解决了  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2010-05-08 23:34 | fw
笔误 default-autoware="byName" -_-!  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-05-09 10:09 | 菠萝大象
@fw
我回复里面不是说过了吗?不用改任何配置文件,我只是重新写一个JdbcDao类,继承了JdbcDaoSupport,这个类里,就一个get方法,使用JdbcDaoSupport 提供的getJdbcTemplate()。既然你继承了JdbcDaoSupport,这个类里面它提供jdbcTemplate,而且会将dataSource设置进来,你看下JdbcDaoSupport源代码  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-06-21 14:57 |
非常厉害呀 支持 经常关注  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2010-06-21 20:08 | 菠萝大象
@鹰
你太夸奖了,谢谢支持。  回复  更多评论
  
# mybatis结合 2011-01-12 12:40 | 简单
楼主写的很给力,有点像springside的思路。真是英雄所见略同。我想问你和mybatis除了他提供的spring结合方式你有什么好的方式么  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-01-12 23:50 | 菠萝大象
@简单
我参考过springside,springside做的确实很好,不过我对其作了更进一步的封装与处理,原版的基类有点过于简单了。不过这个例子我没有写的很复杂,只是一个入门学习资料。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-01-13 14:34 | 简单
能否加qq交流下。271890026  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-02-17 13:36 | sdfsdf
大象,你的qq多少,我加你,最近在学习spring mvc annotation遇到问题了  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2011-04-19 02:30 | wanglong0109
感觉大象一开始不放出源码的做法是对的,而且很有效。当我看第一篇的时候我就想找源码直接放到MyEclipse里面运行,结果没找到,所以只有自己一边看一边写了,虽然有点麻烦,但是这确实能让我静下心来认真看,学到了不少东西。谢谢大象!  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-05-18 17:00 | 李亮
运行起来 报错啊 没用过这种注解方式不怎么懂 请问如果运行你源码的话 配置文件里需要改动吗
报错“No bean named 'userManager' is defined”  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-05-18 17:08 | 菠萝大象
@李亮
数据库连接的用户名与密码是要根据你自己的来设置,其它的配置不需要改动,我的这个例子是自己做出来的,并经过测试的,你是直接运行我的例子吗?如果你是重新构建的工程请检查代码与配置,另外,确保jar包的完整与版本的一致,因为有很多人遇到过你这样的问题,有的是自己构建工程,用我的示例代码,有的是jar包不对造成程序运行不起来,如果你对这个ssh2以及注解还不熟的话,请先把我的例子运行起来后,逐渐了解了再自己试着做  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-05-19 16:55 | 李亮
@菠萝大象
我一直就是想运行起来再去进一步熟悉 再看整个流程 可总是遇到这样那样的问题。。。汗啊  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-05-19 16:57 | 菠萝大象
@李亮
童鞋加油,很多人都一开始没有成功,最后都成功了,从而可以提高调试能力。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-05-19 17:41 | 李亮
我在努力 下班了 回家搞。。。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-07-06 17:54 | 乾坤
看你这个注解系列好几遍了, 现在终于能看懂了,很好很强大,谢谢  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-10-18 15:54 | sherry
在仿照楼主的例子做测试时,使用的是struts2.1.6+spring3.1.0+hibernate4悲催的是找不到org.hibernate.cache.CacheProvider类,hibernate4中不存在该类...哭ING...  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2011-10-20 09:40 | 菠萝大象
@sherry
hibernate每次大升级,都会有很大的变化,出现这种情况不奇怪,hibernate4我还没用过,写这篇系列的时候是在2010年,用的都是稳定发布版  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2012-02-29 10:58 | Klingon
spring中已经配置自动扫描:
<context:component-scan base-package="cn.test"></context:component-scan>
Action类:
public class ShowAccountAction extends ActionSupport {
private static final long serialVersionUID = 1L;
@Autowired
private transient AccountService accountService;
页面请求:
<s:url action="show-account" var="showAccountUrl">
<s:param name="username" value="%{'j2ee'}"/>
</s:url>
问题:
1.如上代码accountService为空, 也就是说Spring无法注入
2.如果在Action类上加@Controller("show-account")然后
cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
ShowAccountAction showAccount= (ShowAccountAction)cxt.getBean("show-account");
accountService = showAccount.getAccountService();得到非空accountServic,此时也就是说Spring可以注入
3综合1、2说明Action没有被Spring托管
我看过您的Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解,也十分想尝试下注解,请您帮助解决下。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2012-04-26 17:22 | sjm
多对一关联后怎么存User?  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2012-04-27 08:38 | 菠萝大象
@sjm
你是说User与Role关联后,User对象的保存?它里面有什么属性就存什么。你最好将源代码down下来看看,源码在第五篇最下面。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2012-04-27 11:02 | sjm
@菠萝大象
好了,在存User的时候根据id再取一次Role就行了。
大象的博客很强大,学到不少东西。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2012-06-06 17:09 | 王晓军
我理解你。最重要的是思想。有了思想源码便是浮云。@菠萝大象
  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2013-01-23 19:25 | zjg
我想请问一下您啊,这里为什么使用getSession而不是用Spring封装好的getHibernateTemplate啊?两者在什么场合使用呢?  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2013-01-24 08:36 | 菠萝大象
@zjg
这个看你的喜好了,getHibernateTemplate是被spring封装过的,你当然可以选择它来用,而getSession是原生的,并且我喜好用Criteria方式来编写代码,这样感觉代码更简洁些。你可以自己去改的,第五篇最下面提供源码下载。  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2013-02-18 11:21 | 秦时明月
前辈,首先万分感谢你!这文章我是相见恨晚啊!!!
我运行代码时,报错了:Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
请前辈为我解惑,多谢!  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2014-04-17 10:29 | ccc
@菠萝大象
不要伤心,我觉得您写的很入门,很直观,解释得也很好!谢谢。同时我认为你说的很对,开发的思路以及各部分的原理很重要!理解好,动手起来就不难了!  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三) 2014-06-26 17:40 | 休息食客
@菠萝大象
非常理解,在搭建一个系统架构的时候,思路是最重要的,在设计的时候要考虑到代码的复用性,后期维护性,健壮性以及敏捷性开发。写得非常不错,挺你!  回复  更多评论
  
# re: Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(三)[未登录] 2014-07-21 15:56 | lxl
非常感谢~受益匪浅~  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: