原文链接:
http://www.java3z.com/cwbwebhome/article/article8/81137.html
在前两章我为大家详细分析了
JAR
包的选择和必须的配置文件,那么这一章,我就对例子的层次结构进行说明,并实现除
WEB
层的功能代码。
第三部分:建立框架代码
工程结构
大家可以看到,本例一共分为:
dao
、
entity
、
service
、
web
四层。另外在这些层次下,还以业务功能再进行分包,这样做是为了方便在以后的功能扩展中,能更好的管理和维护代码。如果将所有类都直接集中在这
4
个包下面,随着类的增加,会越来越难以维护,而且查找起来也很费劲。
HibernateDao
在本例中,我是通过继承
Spring
提供的
HibernateDaoSupport
来实现持久层的基类。同时引入泛型参数,封装了一些基本操作方法。
这是
HibernateDao
的部分代码,引入的这个泛型参数,其实就是实体类(
User
、
Role
)。通过传递这个实体类,在构造方法中利用反射特性将它从
JVM
中取出来。这里的
getClass()
方法是获得继承
HibernateDao
的类(
UserDao
、
RoleDao
)
getGenericSuperclass()
方法就是通过这些继承了
HibernateDao
的类,来得到父类(父类就是
HibernateDao
)的泛型。注意这个方法的返回值为
Type
,这是一个类型接口。请参考
API
。因为在继承
HibernateDao
的时候,会给它加一个泛型参数。比如,
User
、
Role
实体类。因此超类是参数化类型,所以返回的
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
启用了自动注入功能。这就是
Spring
从
2.5
开始提供的新特性。我们使用注解的方法,就可以告别那繁琐的配置文件定义。
entity
关于实体的定义就是使用
JPA
注解,关于这部分,我以前写过一篇文章专门讲这个,如果有不清楚的朋友可以先参考一下。
学习
JPA——
Hibernate Annotation
使用实例
本例中,我有两点要讲下。
第一、管理主键的表
generator_table
去掉原来单独定义的那个
ID
主键,把
g_key
设为主键,整个表将只有两个字段,
g_key
和
g_value
。
第二、在
User
实体中,我将角色
ID
(
role_id
)与角色实体(
Role
)做了一个多对一关联。这一点是原来文章中没有讲过的。
请一定注意
role_id
是
user
表的字段。我在本例中设定的是一个角色可以对应多个人员,所以这个
role_id
存的就是
role
表
id
的值。
fetch = FetchType.
LAZY
指定采用延迟检索,如果当你取得了
User
对象,但又不想取
Role
中的信息,这时,
User
对象中的
role
属性是代理状态。
Role
对象中的值都是空的。只有当你使用
role.id
或
role.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.java3z.com/cwbwebhome/article/article8/81137.html
分享到:
相关推荐
SSH全注解实例详解,hibernate,struts,spring,转自大象
一个基于SSH注解进行开发的小实例。非常适合初学者。~
ssh注解完整实例源代码 可直接运行 初级使用
适合ssh初学者,分享促进进步
一个ssh2实例和一个ssh2基于注解的实例,可以对比来学习。
ssh注解案例。主要是jar包的齐全,对于初学者是个很好的东西。
SSH2全注解实例,内容比较多,有jar包,用的是mysql5.1
Struts2.1 Spring2.5 Hibernate3.3 全注解实例详解 MyEclipse详细步骤及ssh2_demo(代码 sql语句)
ssh注解整合实例包含jar包,只要建好数据库就可以使用哦
ssh框架的注解形式的登录实例,数据库可以自动生成,下载后导入myeclipse直接可以运行
整合SSH2(全注解)框架,方便初学者下载学习。内附db脚本 实例为oracle数据库、采用Struts2,Spring,Hibernate框架。
SSH环境 注解方式 包含jar 简单实例 直接运行
全注解版SSH增删改查
超级详细的SSH2项目实例详解,并且附带两个项目详解。两种注解实现方式。...在JavaEE企业级开发中,以SSH2框架为核心的应用非常广,大象根据项目实践经验,通过二个实例,详细的为大家讲解如何实现全注解式的开发。
本资源是在“ssh框架搭建实例源码6”基础上实现注解自动注入功能,简化了spring的配置,并解决了按F5刷新页面出现错误的bug。 本资源所需的jar包请到“ssh框架搭建实例源码2”和“ssh框架搭建实例源码”中下载: ...
基于全注解的SSH2框架 有很详细的代码讲解 并且通过日志配置保存数据库以及数据库导入导出excel文件
Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解,包含ssh最新框架的集成,IOC注入,AOP面向切面编程.
Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解(一) 在JavaEE企业级开发中,以SSH2框架为核心的应用非常广,大象根据项目实践经验,通过一个实例,详细的为大家讲解如何实现全注解式的开发。 开发环境 ...
ssh2全注解实例 包含数据库 可直接运行 有详细的注释 简单易懂不错的实例
基于ssh框架实现了对人员的新增和人员的查询全部采用注解的方式来实现编码