转自http://www.pben.cn/read.bbscs?action=topic&id=8a8a8a8f167682800116799663fc0d33&bid=33&fcpage=4&fcaction=index&tagId=0
英文版网址
:
http://appfuse.org/display/APF/Persistence
中文版
-------
本教程讨论了如何建立数据库中的表,并编写
Java
代码进行访问数据表
.
一个数据库对象(数据表)将被建立起来,并使用一些类对它进行持久化操作和查询(保存、查询、删除)。按照
Java
的说法,这个对象被称为普通传统的
Java
对象
(POJO)--
(实际上是指:普通
JavaBeans
)
.
,基本上就是对应数据库里的一张表
.
在
AppFuse 1.x
中,典型的做法是创建一个
DAO
和使用
JUnit
单元测试,对这个
POJO
进行持久化。然而,在
2.x
里,以为你准备好了基本的具有
CRUD
方法的
DAO
和管理类(
there is a Generics-based DAO and Manager that will CRUD all objects for you
)。仅在需要定制或需要深入探索时才需要建立自己的
DAO
类
.
AppFuse
使用
Hibernate
作为默认的持久化层。
Hibernate
是一个关联
Java
对象和数据库表的对象
/
关系框架
(Object/Relational (O/R) Framework)
,有助于更容易地对数据库对象执行
CRUD
操作
(Create, Retrieve, Update, Delete).
iBATIS
和
JPA
持久化框架的另外的选择是
iBATIS
或者
JPA .
在
AppFuse
中使用
iBATIS
参见教程
using iBATIS
,用
JPA
参见
教程
-using JPA.
|
为了能在
AppFuse
项目框架下建立对象及其对应的数据表,请继续读完下面的教程内容。
译者注:
JPA
规范允许开发人员将
Java
类批注为实体,这些实体可以保存到一个数据存储库中,在实际的
Java
源代码中提供其他元数据信息。
JPA
同样允许开发人员和应用程序部署人员在外部
XML
文件中指定同样的对象关系映射数据。开发人员和部署人员可以选择在特定情况中使用
XML
文件覆盖源代码内的批注或使用
XML
映射完全覆盖任意源代码批注。
开发人员喜欢源代码内的批注,因为元数据与它所描述的代码位于同一位置。在较大的项目中,应用程序部署团队与开发团队可能不会总是同一组人员,在这种情况中,使用外部描述的对象关系映射元数据覆盖源代码内的批注有优势。选择外部定义的对象关系映射数据而不是源代码内批注的其他原因包括:风格偏好(普遍选择外部配置而不是代码内配置)、经常更改批注值,以及更改配置而不需要重新编译源代码。
1.
创建
POJO
并加上
JPA
批注
2.
使用
Maven
根据
Java
对象建立数据库表
首先,建立一个要持久化的对象。
以建立对象
"Person"
为例,
(
基本原型(
basic archetypes
)的源码位于
src/main/java/**/model
目录;
模块化原型(
modular archetypes
)的源码位于
core/src/main/java/**/model
目录下
)
,它由一个
id,
一个
firstName
和一个
lastName
组成
(
也称为属性
)
。
至于推荐的包命名规范,参加
FAQ
,在本教程里,使用
"org.appfuse.tutorial"
作为顶级包名
.
package org.appfuse.tutorial.model;
import org.appfuse.model.BaseObject;
public class Person extends BaseObject {
private Long id;
private String firstName;
private String lastName;
/* 使用常用的IDE创建getters 和setters 方法:*/
}
继承
BaseObject
是可选的
,
但是推荐作为一个良好实践原则来强制建立
toString()
,
equals()
和
hashCode()
方法
.
如果计划把这些对象用于用户对话(
user's session
)或通过
web service
暴露出来,最好还要实现
java.io.Serializable
.
|
为方便生成
toString()
,
equals()
和
hashCode()
方法
,
可以使用插件
Commonclipse.
更多参考资料参见
Lee Grey's site.
另外也可使用
Eclipse
插件
Commons4E
来完成
.
当自动生成或手工编写
equals()
和
hashCode()
方法时,不要把对象的主键(
primary key
)也包含进去,具体原因参见
Hibernate
的
Equals and Hascode .
IntelliJ
用户
如果使用
IntelliJ IDEA,
可以自动生成
equals()
和
hashCode(),
但
toString()
不行
.
可以使用插件
ToStringPlugin
来帮助创建
.
|
现在
POJO
建好了,下面需要添加
JPA annotations
了
.
这些批注是
Hibernate
用于实现对象
→
表和属性
(
变量
)
→
列的
映射
.
If you're new to Hibernate and Annotations, you might want to read An Introduction to Hibernate 3 Annotationsby John Ferguson Smart.
|
首先
,
添加一个
@Entity
批注,声明本对象与哪张表相关联
.
其中的
"name"
是可选的,如果没指定就默认使用
class
名
.
要确认是使用
javax.persistence.*
来实现批注(
annotations
),而不是
Hibernate.
@Entity
public class Person extends BaseObject {
如果为
@Entity
批注指定了
name
值
(
如:
@Entity(name="person")
),
它将用于
HQL
查询的别名,如果没指定将使用这个类的简短命名(
short name
),如
Person
.
如果仅想改变生成的对应的表名,可使用带用
”name”
值的
@Table
批注来实现
.
|
为指定主键
(primary key)
需要添加
@Id
批注,
@GeneratedValue
批注用于指定主键值的生成策略(
generation strategy
)
.
@Id @GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return this.id;
}
至于其他的域(属性),一般不必进行批注,除非以下情况:
1)
不需要持久化
(
使用批注
@Transient
)
;
2)
需要修改列名或其他属性
.
改变列名使用批注
@Column
.
以下是在
getFirstName()
和
getLastName()
方法里使用
@Column
批注的例子:
@Column(name="first_name", length=50)
public String getFirstName() {
return this.firstName;
}
...
@Column(name="last_name", length=50)
public String getLastName() {
return this.lastName;
}
域级批注
也可以使用域级的
JPA
批注来代替
getters
方法
.
然而,要知道,一旦添加了域级别的批注,方法级别的批注将被不再起作用(
method-level annotations will be ignored
)
.
|
如果是用基本原形(
basic archetypes
),就打开文件
src/main/resources/hibernate.cfg.xml
(
模块化原形,打开
core/src/main/resources/hibernate.cfg.xml
),
使用以下
XML
语句注册
Person
对象
:
<mapping class="org.appfuse.tutorial.model.Person"/>
保存文件,从命令行运行以下命令:
mvn test-compile hibernate3:hbm2ddl.
模块化原形要注意,在
"core"
目录下运行这个命令。
Mvn
会在创建包含
"person"
表的数据库模式(
database schema
),建表语句如下:
create table person (id bigint not null auto_increment, first_name varchar(50), primary key (id)) type=InnoDB;
现在已经创建了一个
POJO
,并据以生成了相关的数据表(
schema
)
,
那该如何来持久化对象呢?
AppFuse
附带了
GenericDao
的实现,用于对任何对象进行
CRUD
操作
.
除了这个基于
Generics
的类外
,
还可以使用
UniversalDao
来做同样的事情
.
二者的主要区别在于,使用
UniversalDao
需要设置特别的类型(
specified type
),然而却不必定义新的
Spring beans,
可见是有利有弊的
.
在这里,将学习使用
GenericDao
来编程
.
请选择下面的持久化框架,以便继续进行
:
1
:
Hibernate
2:Ibatis
3:JPA
如果无法分辨那个更适用你的项目,请看这篇文章:
Hibernate vs. iBATIS