启动Java Persistence项目
通过JPA和新EJB3.0标准的一些优势,以及注解和标准的编程接口简化应用程序开发,与Hibernate进行比较,显然,如果你不时需要在不同的运行时环境下移植或者部署应用程序,设计和链接到标准的接口就是一个优势。尽管除了可移植性之外,还有许多很好的理由来深入探讨JPA。现在将引导你进行另一个“Hello World”示例,这次用Hibernate Annotations和Hibernate EntityManager。你将重用之前的基础项目架构,以便可以看到JPA与Hibernate的区别之处。
使用Hibernate Annotations
首先利用Hibernate Annotations,用内嵌元数据替代Hibernate XML映射文件。/**
* cn.jbit.jta.entity.Message
* 打印消息 实体类
* 许晶晶
* 2014-3-7
*/
package cn.jbit.jta.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "TBL_MESSAGE")
public class Message {
@Id
@GeneratedValue
@Column(name = "MESSAGE_ID")
private Long id;
@Column(name = "MESSAGE_TEXT")
private String text;
@ManyToOne
@JoinColumn(name = "NEXT_MESSAGE_ID")
private Message nextMessage;
public Message() {
super();
}
public Message(String text) {
super();
this.text = text;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Message getNextMessage() {
return nextMessage;
}
public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}
}
hibernate.cfg.xml中Hibernate配置的一个变化:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- ...Many property settings -->
<!-- List of annotated classes -->
<mapping class="cn.jbit.hibernate.entity.Message" />
</session-factory>
</hibernate-configuration>
还有一个修改的地方是HibernateUtil类
try {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
如果用一个Ant目标导出数据库Schema,那么就在build.xml文件中用<annotationconfiguration>取代<configuration>
注解元数据也可以是全局的,全局的注解元数据被放在名为package-info.java的文件中,它处在一个特定的包目录中。除了列出被注解的类之外,还需要添加包含全局元数据的
把这一步再深入,用使用JPA的代码代替加载和存储消息的原生的Hibernate代码。利用Hibernate Annotations和Hibernate EntityManager,可以创建可移植的和标准兼容的映射和数据访问代码。
特点:
首先,它不能随便被创建。在Eclipse中,package-info文件不能随便被创建,会报“Type name is notvalid”错误,类名无效,Java变量定义规范是:字母、数字、下划线,还有那个不怎么常用的$符号(顺带说下,Java是支持中文名称的变量,习惯挑战的同学可以尝试下,分享一下这方面的经验)。其次,服务的对象很特殊。一个类是一类或一组事物的描述,比如Dog这个类,就是描述旺财的,那package-info这个类是描述啥的呢?它总要有一个被描述或被陈述的对象,它是描述和记录本包信息。
最后,类不能带有public、private访问权限。package-info.java再怎么特殊,也是一个类文件,也会被编译成package-info.class,但是在package-info.java中只能声明默认访问权限的类,也就是友好类。
其实还有几个特殊的地方,比如不可以继承,没有接口,没有类间关系(关联、组合、聚合等等)等。
三个作用:
1)为标注在包上Annotation提供便利;2)声明友好类和包常量;
3)提供包的整体注释说明。
第1个作用说明代码:
package cn.jbit.test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PkgAnnotation {
}
package-info代码:
@PkgAnnotation
package cn.jbit.test;
测试类:
package cn.jbit.test;
import java.lang.annotation.Annotation;
public class Client {
public static void main(String[] args) {
// 可能通过I/O操作或配置项获得包名
String pkgName = "cn.jbit.test";
Package pkg = Package.getPackage(pkgName);
// 获取包内注解
Annotation[] annotations = pkg.getAnnotations();
// 遍历注解数组
for (Annotation a : annotations) {
if (a instanceof PkgAnnotation) {
System.out.println(a);
}
}
}
}
第2个作用说明代码:
package-info类
@PkgAnnotation
package cn.jbit.test;
//声明一个包使用的公共类,强调的是包访问权限
class PkgClass{
public static void test(){
}
}
//包常量,只运行包内访问,适用于分“包”开发
class PkgConst{
public static final String PACKAGE_CONST = "ABC";
}
下面一篇是通过Hibernate EntityManger实现特殊的简化咯。