学习Hibernate JPA

近年来ORM(Object-Relational Mapping;对象关系映射,即实体对象和数据库表的映射)技术市场人声音鼎沸,异常热闹, Sun在充分吸收现有的优秀ORM框架设计思想的基础上,制定了新的JPA(Java Persistence API)规范。 那么什么是JPA呢?JPA是通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期实体对象持久化到数据库中去。

近年来ORM(Object-Relational Mapping;对象关系映射,即实体对象和数据库表的映射)技术市场人声音鼎沸,异常热闹, Sun在充分吸收现有的优秀ORM框架设计思想的基础上,制定了新的JPA(Java Persistence API)规范。
那么什么是JPA呢?JPA是通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期实体对象持久化到数据库中去。
这里我们要先谈一下什么叫实体(Entity),按照JPA规范,具有ORM元数据的领域对象就叫做实体。它应具备一下条件:
1.必须使用javax.persistence.Entity注解或XML映射文件中有对应的<entity>元素;
2.必须具有一个不带参数的构造函数,类不能声明为final,方法和需要持久化的属性也不能声明为final;
3.如果游离态的实体对象需要以值的方式进行传递(如通过Session bean的远程业务接口传递),则必须实现Serializable接口;
4.需要持久化的属性,起访问修饰符不能是public,它必须通过实体类方法进行访问。
 
下面我们来尝试对一个域对象进行JPA注解,使其成为一个实体类:
@Entity(name=”T_TEST”)
public class Test implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.TABLE)
@Column(name=” id”)
private int testId;

@Column(name=”uname”,length=100)
private String uname;

@Column(name=”password”)
private String password;

@Column(name=”time”)
@Temporal(TemporalType.Date)
private Date loginTime;

省略get/setter方法
}
下面对以上代码中所涉及的 JPA 注解进行一下说明
@Entity :将领域对象标注为一个实体类,表示该类需要持久化到数据库中,默认情况下类名即表名,通过 name 属性显式指定表名,如: name=”T_TEST” 表示将 Test 保存到表 T_TEST 表中。
@Id :对应的属性是表的主键
@GeneratedValue :主键的产生策略,通过 strategy 属性进行指定,默认情况下, JPA 自动选择一个最适合底层数据库的主键生成策略,如 SqlServer 对应的 identity mysql 对应的 auto increment, java.persistence.GenerationType 中定义了几种可以供选择的策略:
1.  :表自动增长字段,Oracle不支持这种方式;Identity
2.  :JPA自动选择合适的策略,是默认选项;AUTO
4.  :通过表产生主键,框架借由表模拟产生主键,使用该策略可以使用更易于数据库的移植。TABLE
 
@Colunm(name=”uname”) :属性对应的表字段。我们并不需要指定表字段的类型,因为 JPA 会根据反射从实体属性中获取类型;如果是字符串类型,我们可以指定字段长度,以便可以自动生成 DDL 语句。
 
@Temporal(TemporalType.DATE) :如果属性是时间类型,因为数据表对时间类型有更严格的划分,所以必须指定具体时间类型,在 java.persistence.TemporalType 枚举中定义了三种时间类型:
Date :等于 java.sql.Date;
Time :等于 java.sql.Time;
TimeStamp :等于 java.sql.Timestamp
 
JPA 对于具有父子关系的类,对于父类必须声明继承实体的映射策略,对于继承实体, java.persistence.InheritanceType 定义了 3 种映射策略:
SINGLE_TABLE :父子类都保存在同一个表中,通过字段值进行区分。
JOINED :父子类相同的部分保存在同一个表中,不同的部门分开存放,通过连接不同的表获取完整数据。
TABLE_PER_CLASS :每一个类对应自己的表,一般不推荐采用这种方式。
下面我们来看看实际的列子是怎么运用的。
父类 Test
@Entity(name=”test”)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)// 指定继承策略
@DiscriminatorColumn(name=”types”,discriminatorType=DiscriminatorType.INTEGER,length=1)// 指定区分字段为 types ,类型为 Integer 长度为 1
@DiscriminatorValue(value=”1”)// 对应具体实体的值
public class Test implements Serializable{
     …..
}
 
子类 Child
@Entity
@DiscriminatorValue(value=”2”)
public class Child extends Test{
    
// 如果我们不希望 JPA 将该属性持久化到数据库,则采用该注解
@Transient
private String tempStr
 
@Lob //lob 类型的字段
@Basic(fetch=FetchType.Lazy) // 采用延迟加载, FetchType.EAGER 不采用
@Column(name=”postattach”,columnDefinition=”LONGTEXT NOT NULL”) 对应字段类型
private String postAttach;
 
}
可以看到通过字段 types 来区分父子类数据,也是相当方便的。至于 JPA 提供的关联关系比如说一对多,多对一,多对多,也有相应的注解进行关联,有兴趣的朋友可以参考相关帮助文档。
 
以上讲述的都是JPA中以注解形式进行持久化,下面我们来看下采用XML元数据的形式,XML元数据信息以orm.xml命名,放置在类路径的META-INF 目录下。
 
<?xml version=”1.0” encoding=”UTF-8”?>
<entity-mappings
xmlns=”http://java.sun.com/xml/ns/persistence/orm” xmlns=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd”
version=”1.0”>
<package>com.test</package>
<entity class=”Test”>
<table name=”test”/>
<attributes>
<id name=”id”>
<column name=”id”/>
<generated-value strategy=”TABLE”/>
</id>
<basic name=”uname”>
<column name=”uname” length=”30”/>
</basic>
<basic name=”logintime”>
<column name=” logintime”/>
<temporal>DATE</temporal>
</basic>
</attributes>
</entity>
<entity-mappings>
可以看到JPA元数据采用XML形式也是相当简单易懂的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值