此主题
涉及到 加下有这么四个包 :
一 :在org.appfuse下有这么一个类Constants.java,它是一个存储常量的类,
如果我们在程序中有一些常量需要改变名称,而这个常量分布在不同的类里,如果我们要修改它,就是一项很大的工程。而且重新编译也会遇到很多问题。我们通过建立一个常量类,如果我们需要修改,只需要在这里修改。然后把这个类编译其他代码不需要改变。
他里边的属性都是静态的,例如 :
public
static
final
String BUNDLE_KEY
=
" ApplicationResources
" ;
二 :在org.appfuse.dao下有四个接口。
1
Dao
2
LookupDao
3
RoleDao
4
UserDao
1 :Dao:
1
List getObjects(Class clazz)
返回数据库中与此类对应的表的所有值
2
Object getObject(Class clazz, Serializable id)
返回与此类对应的表的主键值为id的数据
3
void
saveObject(Object o)
保存此对象
4
void
removeObject(Class clazz, Serializable id)
根据id值(主键)删除此对象
后三个接口继承了第一个接口。
2 :LookupDao:
1
List getRoles()
返回role表中的所有数据
3 : RoleDao:
1
Role getRoleByName(String rolename)
2
List getRoles(Role role)
3
void
saveRole(Role role)
4
void
removeRole(String rolename)
4 :UserDao:
1
User getUser(Long userId);
2
UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException
3
List getUsers(User user)
4
void
saveUser(User user)
5
void
removeUser(Long userId)
三 : org.appfuse.dao.hibernate 此包下有四个类
:
1
BaseDaoHibernate
extends HibernateDaoSupport
implements Dao
2
LookupDaoHibernate
extends BaseDaoHibernate
implements LookupDao
3
RoleDaoHibernate
extends BaseDaoHibernate
implements RoleDao
4
UserDaoHibernate
extends BaseDaoHibernate
implements UserDao, UserDetailsService
1 : BaseDaoHibernate:
1
List getObjects(Class clazz)
返回数据库中与此类对应的表的所有值
2
Object getObject(Class clazz, Serializable id)
返回与此类对应的表的主键值为id的数据
3
void
saveObject(Object o)
保存此对象
4
void
removeObject(Class clazz, Serializable id)
根据id值(主键)删除此对象
后三个类继承了第一个类。
2 :LookupDaoHibernate :
1
List getRoles()
返回role表中的所有数据
3 :RoleDaoHibernate :
1
Role getRoleByName(String rolename)
2
List getRoles(Role role)
3
void
saveRole(Role role)
4
void
removeRole(String rolename)
4 :UserDaoHibernate :
1
User getUser(Long userId);
2
UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException
3
List getUsers(User user)
4
void
saveUser(User user)
5
void
removeUser(Long userId)
他继承接口UserDetailsService并实现了它的唯一方法loadUserByUsername(String
username).
5 :还有一个名为applicationContext-hibernate.xml的文件。
它是spring的配置文件。里边定义了与hibernate相关的的六个bean:
1
sessionFactory
2
transactionManager
3
dao
4
loopupDao
5
userDao
6
roleDao.
此文件只是整个spring配制文件的一部分。它配置了与hibernate相关的一些配置.
spring它是一种j2ee架构级框架,有人把它叫做胶水代码,通过它可以把项目的不同部分组合在一起,(有点类似于工厂类的作用),但是它有以下优点.
1
.它可以把不同的开发框架整合在一起.
2
.通过xml来配置组件之间调用关系.不需要硬编码.组件之间是松偶合的.
3
.它是面向接口编程的,调用getBean()方法得到的都是接口.
4
.提供aop支持.可以方便的进行面向方面编程.
5.1 : sessionFactory有三个属性:
1
: <
property name
= "
dataSource "
ref =
" dataSource
" />
dataSource:它指明此SessionFactory所依赖的数据源,数据源的相关定义在名为dataSource的bean中.
2
: <
property name
= "
mappingResources
" >
..
mappingResources定义了hibernate映射文件,这些映射文件指明类与数据库中表的对应关系.
3
: <
property name
= "
hibernateProperties
" >
.
hibernateProperties指明数据库类型.
5.2 : transactionManager : 事务管理bean
transactionManager 用来管理数据库事务.它只有一个属性sessionFactory.指明此事务bean依赖的sessionFactory.
<
bean id =
" transactionManager
"
class =
"
org.springframework.orm.hibernate3.HibernateTransactionManager
" >
< property name
= "
sessionFactory "
ref =
" sessionFactory
" />
</
bean >
5.3 : dao
名为dao的bean的具体实现类为org.appfuse.dao.hibernate.BaseDaoHibernate.它依赖sessionFactory,
<
bean id =
" dao
"
class =
"
org.appfuse.dao.hibernate.BaseDaoHibernate "
>
< property name
= "
sessionFactory "
ref =
" sessionFactory
" />
</
bean >
需要注意的是在程序中如果要调用这个bean 得到的是BaseDaoHibernate的接口.
Dao dao
= (Dao)ctx.getBean(
" dao
" );
LookupDao,userDao,roleDao与dao类似.
四 :org.appfuse.model 此包下有5个类。
除了LabelValue外其他几个都是与数据库中的表相关的pojo对象。
此包中的LabelValue和struts包中的org.apache.struts.utils.LabelValueBean除了类名之外,其他都一样。
address,Role和User这三个类都是从BaseObject继承下来的。
1 :BaseObject:
public
abstract
class
BaseObject
implements Serializable
它是一个抽象类,里边有3个抽象方法toString(),equals(Object o), hashCode().
2 :Address:
public
class
Address
extends BaseObject
implements Serializable
它继承BaseObject实现Serializable. 在类的上方有Xdoclet的struts标记
@struts.form include
- all
= "
true "
extends
= "
BaseForm "
表示它是一个form继承于BaseForm。
它有五个与地址相关的属性,每个属性有对应的get和set方法.而每个get方法的前面有Xdoclet的hibernate标记.
@hibernate.property column
= "
address "
not -
null =
" false
" length
= "
150 "
表明类的此属性与数据库表之间的对应关系以及数据库此字段的特性,如长度,是否为空等 。
@struts.validator type
= "
required "
表示此字段做为struts 的form字段需要验证。验证类型为required.在getPostalCode()前边有
:
@struts.validator type
= "
required "
@struts.validator type
= "
mask "
msgkey
= "
errors.zip "
@struts.validator
- var name
= "
mask "
value =
" ${zip}
"
它的意思为在struts的form中此字段验证规则为required,而且还要和自定义的zip规则相匹配。如果出错,提示错误信息,注意address这个类并没有和数据库中的一个具体的表对应,它作为user表的一部分.俗称
:组件映射。
3 :User :
public
class
User
extends BaseObject
implements Serializable, UserDetails
它继承BaseObject实现Serializable和UserDetails接口。
在它的类的声明前面有XDoclet标记:
@struts.form include
- all
= "
true "
extends
= "
BaseForm "
@hibernate.
class table
= "
app_user "
具体含义同上。
这个类需要注意的是以下几点:
3.1 :
1
Address address
=
new Address();
2
3
/** */
/**
4
* @hibernate.component
5
*/
6
public Address getAddress()
{
7
return address;
8
}
把address作为它的一个属性address类的属性最终映射成表User的字段。
3.2 :
1
protected String password;
2
3
/** */
/**
4
* @hibernate.property column="password" not-null="true"
5
*/
6
public String getPassword()
{
7
return password;
8
}
3.3 :
1
/** */
/**
2
* @hibernate.set table="user_role" cascade="save-update" lazy="false"
3
* @hibernate.collection-key column="user_id"
4
* @hibernate.collection-many-to-many class="org.appfuse.model.Role" column="role_id"
5
*/
6
public Set getRoles()
{
7
return roles;
8
}
3.4。它继承实现了接口UserDetails的getAuthorities()方法 :
1
/** */
/**
2
*
@see
org.acegisecurity.userdetails.UserDetails#getAuthorities()
3
*/
4
public
GrantedAuthority[] getAuthorities()
{
5
return
(GrantedAuthority[]) roles.toArray(
new GrantedAuthority[
0 ]);
6
}
返回roles强制转换为类型为GrantedAuthority的数组。
此外它还继承实现了UserDetails的
1
getUsername()
2
getPassword()
3
isEnabled()
4
isAccountNonExpired()
5
isAccountNonLocked()
6
isCredentialsNonExpired()
3.5。它继承实现了BaseObject的equals(),hashCode(),toString().
4 :Role:
public
class
Role
extends BaseObject
implements Serializable, GrantedAuthority
它继承BaseObject实现Serializable和GrantedAuthority接口。
因为appfuse使用了基于spring 的acegi安全框架,所以要实现GrantedAuthority的唯一方法: getAuthority()
在此类的前边有两条Xdoclet标记:
@struts.form
extends =
" BaseForm
"
@hibernate.
class table
= "
role "
第1条表示它是一个struts的form.
第2条表示此类与数据库中的一个名为role的表对应。
它有如下属性。
private Long id;
private String name;
private String description;
类似于address它的每个属性的get方法前边都有一些与struts或hibernate相关的XDoclet标记。需要注意的是以下几点:
4.1 :
/** */
/**
* @hibernate.id column="id" generator-class="increment" unsaved-value="null"
*/
public Long getId()
{
return id;
}
4.2 :
public String getAuthority()
{
return getName();
}
实现GrantedAuthority的 getAuthority()方法就是返回 getName();
五 :appfuse 涉及到的 hibernate配置文件
1 :appfuse的hibernate配置文件中主键生成方式 选择了 :
<
generator
class =
" native
" ></
generator >
它表示 :根据底层数据库的能力选择identity,
sequence 或者hilo中的一个。
2 :User.hbm.xml 中 有这样的配置 :
<
version name
= "
version "
column =
" version
" type
= "
java.lang.Integer
" />
对应表 app_user中 对应 有 一个 version 字段 (int 11) ;
含义 :
<version>元素是可选的,表明表中包含附带版本信息的数据。
这在你准备使用 长事务(long transactions)的时候特别有用。
版本号必须是以下类型:long,
integer, short, timestamp或者calendar。
3 :关于多对多 User.hbm.xml 与 Role.hbm.xml
首先 User.java中 有 :
protected Set roles = new HashSet();
public Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
public void addRole(Role role) {
getRoles().add(role);
}
/** *//**
* Convert user roles to LabelValue objects for convenience.
*/
public List getRoleList() {
List userRoles = new ArrayList();
if (this.roles != null) {
for (Iterator it = roles.iterator(); it.hasNext();) {
Role role = (Role) it.next();
// convert the user's roles to LabelValue Objects
userRoles.add(new LabelValue(role.getName(),
role.getName()));
}
}
return userRoles;
}
在User.hbm.xml中 有 下列配置 :
<set name="roles" table="user_role" lazy="false" cascade="save-update">
<key column="user_id"></key>
<many-to-many class="org.appfuse.model.Role" column="role_id" outer-join="auto"/>
</set>
在Role.java 没有任何相关属性。在 Role.hbm.xml中没有任何相关配置 。
详细说明一下 User.hbm.xml中相关的属性含义
:
3.1 : cascade(级联)
(可选): 指明哪些操作会从父对象(User)级联到关联的对象(Role)。 本例中当
save或update时 级联。
cascade="all|none|save-update|delete|all-delete-orphan"
3.2 : lazy
(可选 - 默认为 proxy):
默认情况下,单点关联是经过代理的。
lazy="true"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche
lazily)(需要运行时字节码的增强)。
lazy="false"指定此关联总是被预先抓取。
本例中 关联是被 预先抓取 的。
3.3 : outer-join(可选 - 默认为auto):
即外连接抓取
3.4 : fetch (可选 - 默认为 select):
在外连接抓取(outer-join
fetching)和序列选择抓取(sequential select fetching)两者中选择其一。
3.5 : optimistic-lock (可选 - 默认是 true):表明更新此组件是否需要获取乐观锁。
换句话说,当这个属性变脏时,是否增加版本号(Version)
3.6 :
<property name="enabled" type="yes_no" column="account_enabled"></property>
这里面 数据库 的 account_enabled 字段 类型 是 :char(1)的。
User.java类中 enable 属性是 boolean型的 :
protected boolean enabled;
|