第七篇 hibernate项目中使用JPA注解对ORACLE数据库表中主键生成用UUID

     JPA可能很多开发人员都知道,那笔者就在这里简单说一下,JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Jpa是一种规范,而Hibernate是它的一种实现。除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等都是JPA规范的实现者,所以使用Jpa的一个好处是,可以更换实现而不必改动太多代码。以Hibernate为例,它可以使整个Hibernate项目中的实体对象,省去很多的配置文件,这样带来的效果无疑使整个代码更加简介。

    因为笔者工作三年多,这三年中一直用的是Ibaits,所以对于Hibernate的认识还停留在达内培训时候的认识,认识不深,因为自己换了新工作,要用到Hibernate,所以对Hibernate进入了深一步认识,因为觉得对象与表的映射文件太不直观,所以就使用了JPA的注解风格来实现,但是在这测试中就遇到了问题,因为我用的是Oracle数据库,所以在对于主键生成策略这一块,因为JPA主键的生成策略不像Hibernate那么丰富,包括四种生成方式

@Id @GeneratedValue(strategy=GenerationType.IDENTITY) 

private Integer id;

@GeneratedValue的属性strategy指定生成策略,

IDENTITY(自增长方式,如mysql)

SEQUENCE  (序列方式,如oracle)

TABLE (表方式,该方式便于数据库移植,但效率不高,主键的值是从这个表中取得的。)

AUTO (自动方式,该方式会把主键生成交给JPA的实现者来决定,Hibernate会根据底层数据库选择合适的方式,如果用这种方式,可以不写,默认如此)

因为生成方式的限制,笔者一直倾向于使用UUID做为数据库的主键,但是上面的生成策略为类似不支持,就因为这个问题困扰了笔者将近两个小时,我们先看一下JPA对各数据库主键生成的支持:

四种数据库的支持情况如下:

 

数据库名称

支持的id策略

mysql

GenerationType.TABLE

GenerationType.AUTO

GenerationType.IDENTITY

不支持GenerationType.SEQUENCE


oracle

strategy=GenerationType.AUTO

GenerationType.SEQUENCE

GenerationType.TABLE

不支持GenerationType.IDENTITY


postgreSQL

GenerationType.TABLE

GenerationType.AUTO

GenerationType.IDENTITY

GenerationType.SEQUENCE

都支持


kingbase

GenerationType.TABLE

GenerationType.SEQUENCE

GenerationType.IDENTITY

GenerationType.AUTO

都支持


能过上面的信息我们可以看出,JPA对ORACLE支持这块UUID实现类似不可能,接下来为了笔者的这个目的,在网上也找了些资料,终于发现找一种使用JPA可以在ORACLE中使用UUID做为主键的方法,在分享之前,能过两个问题先帮大家正确认识一下Hibernate与JPA的关系吧。

第一个是问如果想用hibernate注解,是不是一定会用到jpa的。网友的回答:“是。如果hibernate认为jpa的注解够用,就直接用。否则会弄一个自己的出来作为补充”,这句话怎么理解呢,

JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由用用服务器厂商来提供实现,JBoss应用服务器底层就以Hibernate作为JPA的实现。
既然JPA作为一种规范——也就说JPA规范中提供的只是一些接口,显然接口不能直接拿来使用。虽然应用程序可以面向接口编程,但JPA底层一定需要某种JPA实现,否则JPA依然无法使用。Sun之所以提出JPA规范,其目的是以官方的身份来统一各种ORM框架的规范,Hibernate就是JPA规范的一个实现者,所以说,使用Hibernate一定会用到JPA。这样我觉得各位读者应该可以理解了吧。

第二个是问,jpa和hibernate都提供了Entity,我们应该用哪个,还是说可以两个一起用?网友回答说“Hibernate的Entity是继承了jpa的,所以如果觉得jpa的不够用,直接使用hibernate的即可”。

这个问题就比较好理解了,因为Hibernate作为JPA的一种实现 ,一定会在JPA的规范上进行扩展 ,对于一些共用的东西可以自己选择,如果JPA规范中没有,不能满足开发人员的需要,就可以使用Hibernate中的。

能过上面的两个问题我想每位读者会对JPA和Hibernate有一个深刻的认识,接下来就和大家分享一下笔者今天使用JPA注解风格开发Hibernate中可以在ORACLE数据库的主键使用UUID的方法。

@Entity
public class Category {
private String id;
@Id
@GenericGenerator(name="uuid_s",strategy="uuid") 
@GeneratedValue(generator="uuid_s") @Column(length=32) 

public String getId() {
return id;
}
//部分代码省略.......
}

在执行插入数据后,通过SQL:select * from category;

执行结果如下

1 8a8188b03eacba79013eacba7d590001 c0
由上面结果我们可以看出,UUID生成的主键已经成功插入到数据库中。

下面是JPA注解中的一些其它类型的配置:

字符串类型:不指定长度时,数据库中长度为255,mysql中映射为varchar(255)

日期类型:

可以直接使用java.util.Date

2011-12-12 在hibernate配置文件中可以用type=”date”

2011-12-12 12:23:12 可以用type=”datestam”(?)

12:23:12可以用type=”time”

在JPA注解方式可以用

@Temporal(TemporalType.DATE)    //还有TIME,TIMESTAMP 
    private Date birth;

枚举类型:

男和女可以用枚举作为实体Bean的属性值类型,那么枚举值保存到数据库后使用枚举值使用索引值(0开始)还是字符值呢。注意保存枚举值时加上非空约束,最好加上长度。

面向对象的方式考虑问题,怎样设置默认值,直接在类的属性里设值。

package com.domin;

public enum Gender { 
    MAN,WOMAN 
}

@Enumerated(EnumType.STRING) @Column(length=5,nullable=true) //ORDINAL为索引方式 
    private Gender gender=Gender.MAN;//设置默认值

大数据字段映射

(1)可以在字符型的属性或字段上加上@Lob

@Lob 
    private String description; 
  在mysql中映射产生的字段的类型是longtext

在oracle中是  CLOB

(2)可以在Byte[]类型的字段上加@Lob

mysql中对应longblob

oracle中不能使用byte[]字段加@Lob的方式直接映射

大数据字段最好再加上延迟加载

@Lob @Basic(fetch=FetchType.LAZY) 
    private Byte[] file;

通过此篇文章,希望各位读者,在开发过程中,遇到不熟悉的框架和技术时,我们可以先去了解其原理,只有原理了解以后,我们才可以对此框架有深的见解,这样在开发起来会走很少弯路,在写此文章之前,笔者对JPA的认识也不全面,通过今天的学习,已经 对JPA和Hibernate有了深的见解。笔者在这里废话一句,你们懂没懂,反正我是懂了.......微笑

因为文章内容为个人手写,难免有些错别字,请大家见谅。如转载请注明出处。http://blog.csdn.net/u010601183


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值