以前和数据库打交道的标准INTERFACE是JDBC,放SQL语句,执行,就可以有结果。随着近年ORM的兴起,以对象的方式存取数据库大行其道。于是产生了JPA。
也是一套INTERFACE,以ORM的方式提供,由厂商实现,如ECLIPSE LINK,HIBERNATE,OPENEJB等。
ENTITYMANAGERFACTORY:根据配置文件制造ENTITYMANAGER
ENTITYMANAGER:以ORM的方式提供操作数据库的功能
TRANSACTION:事务保证
PERSISTENCE.XML:链接数据库信息,事务类型,重定义JPA的实现厂商等的配置信息
在容器环境下使用:
如果事务是RESOURCE_LOCAL的方式,则合用端需干所有的事情,如构造ENTITYMANAGER,打开事务,关闭事务等。类似于BMT。
以下是在服务器环境中合用RESOURCE_LOCAL型的JPA
事先要在容器中添加数据源。
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<!-- Tutorial "unit" -->
<persistence-unit name="Tutorial" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>myNonJtaDataSource</non-jta-data-source>
<class>org.superbiz.jpa.Account</class>
</persistence-unit>
</persistence>
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceUnit;
public class MyEjbOrServlet
{
@PersistenceUnit(unitName="Tutorial")
private EntityManagerFactory factory;
// Proper exception handling left out for simplicity
public void ejbMethodOrServletServiceMethod()
throws Exception {
EntityManager entityManager = factory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
Account account = entityManager.find(Account.
class, 12345);
account.setBalance(5000);
entityTransaction.commit();
}
}
以下是JTA方式的JPA,容器+EJB+JPA+JTA,容器会在EJB的方法调用前打开一个事务,在方法退出后,提交事务,并且如果是多个数据源的,即有多个ENTITYMANAGER的
可以保证一致性,即全局事务。相当于之前的先调用USERTRANSACTION,BEGIN,COMMIT。
事先要在容器中添加数据源。
persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<!-- Tutorial "unit" -->
<persistence-unit name="Tutorial" transaction-type="JTA">
<jta-data-source>myJtaDataSource</jta-data-source>
<non-jta-data-source>myNonJtaDataSource</non-jta-data-source>
<class>org.superbiz.jpa.Account</class>
</persistence-unit>
</persistence>
EJB
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class MyEjb implements MyEjbInterface {
@PersistenceContext(unitName = "Tutorial")
private EntityManager entityManager;
// Proper exception handling left out for simplicity
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void ejbMethod() throws Exception {
Account account = entityManager.find(Account.class, 12345);
account.setBalance(5000);
}
}
如果是J2SE环境下使用JPA,则又是不一样的。
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="SimplePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.someone.jmail.valueobject.CallActivity</class>
<class>com.someone.jmail.valueobject.Email</class>
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="12345" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="false"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
</properties>
</persistence-unit>
</persistence>
Dao:
public class UserDaoImpl implements UserDao {
public AccountInfo save(AccountInfo accountInfo) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("SimplePU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(accountInfo);
em.getTransaction().commit();
emf.close();
return accountInfo;
}
}