什么是JPA
JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在HIbernate、TopLink、JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有HIbernate、TopLink、JDO等ORM框架的基础上发展而来的(JPA的开发就是Hibernate的创始人做的),具有易于使用、伸缩性强等优点,从目前的开发社区的反应上看,JPA收到了极大地支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。着眼未来几年的技术走向,JPA作为ORM领域标准化整合者应该不难实现,现有的云计算框架就需要JPA整合,因为各个大公司的产品数据库操作不尽相同,正需要这种规范。
JPA的总体思想和现有的HIbernate、TopLink、JDO等ORM框架大体一致。
总的来说,JPA包括3个方面(之前文章也多少提过):
1、ORM映射元数据
JPA支持XML和JDK5.0注释或者称注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化数据库中。
2、Java持久化API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中解脱出来。
3、查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
这里提示一下:JPA不是一种新的ORM框架,它的出现只是用于规范现有的ORM技术,他不能取代现有的HIbernate、TopLink、JDO等ORM框架。相反,在JPA开发时,我们仍将使用这些ORM框架,知识此时开发出来的应用不在依赖于某一个持久化提供商(实现了JPA规范的框架都是它的产品,包括HIbernate)。应用可以在不修改代码的情况下在任何JPA环境下运行,真正做到低耦合,可扩展的程序设计。
以实现JPA的HIbernate开发为例
这次实例一部分代码我将放在常用工具类中,方便以后直接使用,同时,ORM映射我采用注解方式来做,XML配置自己开发项目使用的太多,是时候换种新的技术实现。
首先是开发JPA依赖的jar包,我把14个常用的jar包上传到了我的资源了,感兴趣的同学自己下载吧,然后就是新建java project项目,JPA规范要求在类路径下的META-INF目录下放置persistence.xml,而且文件名称是固定的,配置模板如下:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <!-- 持久化单元名字name=jpatest1 --> <persistence-unit name="jpatest1" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.max_fetch_depth" value="3" /> <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="123456" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence>
项目开发我们常用的两种开发方式(我们支持后者)
1.先建表,后再根据表来配置编写配置文件和实体bean,使用这种方案的开发人员受到了传统数据库建模的影响,也是大部分人员使用的,但不够oop
2.先编写配置文件和实体bean,然后在生成表,使用这种方案的开发人员采用的是领域建模思想,这种思想相对前一种思想更加oop,但新手来说容易出问题。
persistence.xml中事务配置:
我们知道事务有两种(transaction-type):本地事务(RESOURCE_LOCAL)和全局事务(JTA)
一般我们都是使用本地事务,那什么时候使用全局事务那,就是当对两个连接或者对象同时操作时,需要使用,看下面这个例子,1银行要向2银行转账,这就涉及到1银行的减操作,2银行的加操作:
1.mysql 2.oracle
转账
1>update mysql set amount=amount-xx where id=xxx(mysql);
1>update mysql set amount=amount+xx where id=yyy(oracle);
但问题在于我们创建两个连接connnection,那上面的两条语句分别在不同连接中执行,怎么控制提交,以及如何判断提交结果,这就要求必须使用全局事务。
全局事务的API是由JTA提供的,看代码如何实现,
JTA.getUserTransation().begin();
connection = mysql;
connection2 = oracle;
connection->update mysql set amount=amount-xx where id=xxx(mysql);
connection2->update mysql set amount=amount+xx where id=yyy(oracle);
JTA.getUserTransation().summit();
在这期间,用到二次提交协议,简单的说,就是执行第一条语句时,它会先预提交到数据库,将提交返回的booblean型数据存入list,然后只有在全为true时,才会全局提交,如果其中任意一条出现false,事务都不会真正提交,而是回滚数据,将数据恢复到原来状态。
下面的具体开发代码我将另开文章详解介绍,内容解释就到这了。