介绍
JPA(Java PersisenceAPI)是SUN官方提出的Java持久化规范;它为Java开发人员提供了一种对象/关系映射工具
来管理Java应用中的关系数据;它的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在
Hibernate、TopLink、JDO等ORM框架各自为营的局面;
JPA包括以下3方面技术:
1 ORM映射元数据
JPA支持XML和JDK5注释两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到
数据库中;
2 Java持久化API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中
解脱出来;
3 查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句
紧密耦合;
提示:JPA不是一种新的ORM框架,它的出现只是用于规范现有的ORM技术,它不能取代现有的Hibernate、
TopLink等ORM框架;相反,在采用JPA开发时,我们仍将使用到这些ORM框架,只是此时开发出来的应用不再依赖
于持久化提供商;应用可以在不修改代码的情况下在任何JPA环境下运行,真正做到低耦合,可扩展的程序设计
。
Hibernate开发JPA依赖的jar包
核心包:hibernate-distribution-3.x.x.GA
注解包:hibernate-annotations-3.x.x.GA
针对JPA的实现包:hibernate-entitymanager-3.x.x.GA
下载:http://sourceforge.net/projects/hibernate/files/?source=navbar
JPA的配置文件
JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件的名称是固定的;
一般使用本地事务;若在一个事务中有连接两个数据库,需要使用外部事务;
数据库设计顺序,看情况,没有具体好坏;
1)先设计数据库,再写实体类;
2)先写实体类,再生成数据库;
配置文件persistence.xml中,配置可以自动生
成表;在生成sessionFactory的时候生成表;
EntityManagerFactory factory =Persistence.createEntityManagerFacto
factory.close(); // 这样就可以生成表了;
查询时注意
JPA的find方法类似于hibernate的get方法;JPA的getReference方法类似于hibernate的load方法,表示延迟初
始化;对于find方法是立即触发的,所以查询不到就会返回null;注意,getReference方法调用时候是先返回代
理对象,并不会直接查询数据库,是在调用对象字段时候出发查询的,如果查询不到记录,调用字段属性就会抛
出异常了;
JPA的getResultList方法类似于hibernate的list方法;
JPA的getSingleResult方法类似于hibernate的uniqueResult方法,在统计时候使用;
更新时注意
实体对象四种状态
1 新建状态
新建对象,通过persist方法(hibernate原先是save方法)保存到数据库;
2 托管状态
从数据库find出来的对象,通过set改变对象属性会同步回数据库;
如果已经find出来的对象,被容器托管着,再次调用find方法是不会查数据库的,可以通过refresh方法去查询
;
3 游离状态
从数据库find出来的对象,中间被EntityManager的clear方法清理后,此时变成游离状态;
对游离状态的set改变属性是不会同步至数据库的;
可以通过merge方法来将游离状态对象更新回数据库;
4 删除状态
托管状态的对象,调用remove方法删除数据库记录;
对象关联
双向一对多(@OneToMany)
Many端,为关系维护端,负责外键的更新(删除时候注意先删除Many端再删除One端);
One端,为关系被维护端,不能更新外键;
级联关系,在One端设置级联关系,采用何种方式影响至Many端;若在Many端设置级联关系,一般只设置REFRESH
与MERGE级联关系,不能设置成REMOVE;
CascadeType.REFRESH:当One端被refresh调用时候触发到Many端;
CascadeType.PERSIST:当One端被persist调用时候触发到Many端;
CascadeType.MERGE:当One端被merge调用时候触发到Many端;
CascadeType.REMOVE:当One端被remove调用时候触发到Many端;
CascadeType.ALL:包含上面所有的级联关系;
加载类型,默认ToMany是延迟加载,ToOne是立即加载;
FetchType.EAGER:立即加载;
FetchType.LAZY:延迟加载;
mappedBy:只能在关系被维护端出现该属性,指向关系维护端对应的字段属性;
optional:设置关系维护端的外键是否可以为空,true可以为空,false不能为空;
@JoinColumn
:指定关系维护端的外键数据库字段名称,默认是Java类的字段名;
双向一对一(@OneToOne),类似双向一对多,mappedBy设置在关系被维护端,外键由关系维护端维护;
双向多对多(@ManyToMany),注意关系维护端的定义;所有关系定义都是在关系维护端来定义的;
@JoinTable(name="关联表名称", inverseJoinColumns=@JoinColumn(name="被维护端外键"),
joinColumns=@JoinColumn(name="维护端外键"))
注意,在关系维护端对被维护端的集合进行增加、删除操作时候,需要重载hashCode与equals方法,通过ID来判
断是否相同,而不是内存引用地址;
对关系被维护端进行级联删除时候,需要先解除关系,然后删除;
复合主键
使用@Embeddable注释表示复合主键的类,必须实现Serializable接口,重新hashCode跟equals方法;
在具体实体类中,使用@EmbeddedId标识是复合主键;
主键生成策略
@GeneratedValue(strategy=GenerationType.XXX)
GenerationType.IDENTITY,自增字段,SqlServer支持,Oracle不支持;
GenerationType.AUTO,JPA自动选择合适的策略,是默认选项;
GenerationType.SEQUENCE,通过序列产生主键,通过@SequenceGenerator注解指定序列名;MySql不支持;
GenerationType.TABLE,通过表产生主键,框架借助由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植;不同的JPA实现商生成的表名是不同的,如OpenJPA生成openjpa_sequence_table表,Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表;这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT;
时间字段标识
@Temporal(TemporalType.XXX),来标识;
TemporalType.DATE:等于java.sql.Date;
TemporalType.TIME:等于java.sql.Time;
TemporalType.TIMESTAMP:等于java.sql.Timestamp;
继承标识,用的比较少,一般不会用到;
InheritanceType.SINGLE_TABLE,整个类分层结构一张表;默认的,需要有一个字段来区分;
InheritanceType.TABLE_PER_CLASS,每个具体类一张表;
InheritanceType.JOINED,每个类一张表,抽象的父类也是单独一张表;
@Column字段属性
columnDefinition
默认值:空 String 。
默认情况下,JPA 使用最少量 SQL 创建一个数据库表列。
如果需要使用更多指定选项创建的列,请将 columnDefinition 设置为在针对列生成DDL 时希望 JPA 使用的SQL 片断。
注意:捕获批注中的 DDL 信息时,某些 JPA 持续性提供程序可以在生成数据库模式时使用此 DDL 。例如,请参阅“ 用于Java2DB 模式生成的 TopLink JPA 扩展” 。
insertable
默认值: true 。
默认情况下,JPA 持续性提供程序假设所有列始终包含在 SQL INSERT 语句中。
如果该列不应包含在这些语句中,请将 insertable 设置为 false 。
length
默认值: 255
默认情况下,JPA 持续性提供程序假设所有列在用于保存 String 值时的最大长度为 255个字符。
如果该列不适合于您的应用程序或数据库,请将 length 设置为适合于您的数据库列的int 值。
name
默认值:JPA 持续性提供程序假设实体的每个持久字段都存储在其名称与持久字段或属性的名称相匹配的数据库表列中。
要指定其他列名,请将 name 设置为所需的 String 列名。
nullable
默认值: true 。
默认情况下,JPA 持续性提供程序假设允许所有列包含空值。
如果不允许该列包含空值,请将 nullable 设置为 false 。
precision
默认值: 0.
默认情况下,JPA 持续性提供程序假设所有列在用于保存十进制(精确数字)值时的精度为 0 。
如果该精度不适合于您的应用程序或数据库,请将 precision 设置为相应的 int 精度。
scale
默认值: 0.
默认情况下,JPA 持续性提供程序假设所有列在用于保存十进制(精确数字)值时的伸缩度为 0 。
如果该伸缩度不适合于您的应用程序或数据库,请将 scale 设置为相应的 int 精度。
table
默认值:JPA 持续性提供程序假设实体的所有持久字段都存储到一个其名称为实体名称的数据库表中(请参阅 @Table )。
如果该列与辅助表关联(请参阅 @SecondaryTable ),请将 name 设置为相应辅助表名称的 String名称,如示例 1-8 所示。
unique
默认值: false 。
默认情况下,JPA 持续性提供程序假设允许所有列包含重复值。
如果不允许该列包含重复值,请将 unique 设置为 true 。设置为 true 时,这相当于在表级别使用@UniqueConstraint 。
updatable
默认值: true 。
默认情况下,JPA 持续性提供程序假设列始终包含在 SQL UPDATE 语句中。
如果该列不应包含在这些语句中,请将 updatable 设置为 false 。