一个EntityManager 实例是一个数据库连接,此实例也提供了对数据库级别的操作功能。一般一个应用程序需要多个EntityManager 实例与数据库进行交互。
EntityManagerFactory 实例则是用来创建EntityManager 实例的。一般对于一个应用程序,与一个数据库的交互需要一个EntityManagerFactory 实例管理EntityManager 实例连接池或者sockets。
更新数据时需要事务管理,这是由EntityTransaction 实例管理的,EntityManager提供获取EntityTransaction 的方法。
EntityManager也提供检索操作。
每种实现了JPA规范的框架,都实现了以上这些接口,JPA规范使得代码的可移植性更强。
JPA的启动类Persistence,提供了一个静态工厂方法来创建EntityManagerFactory的实例。
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("myDbFile.odb");
也可以把持久化单元的配置信息封装到一个Map中,作为方法的参数:
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.persistence.jdbc.user", "admin");
properties.put("javax.persistence.jdbc.password", "admin");
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
"objectdb://localhost:6136/myDbFile.odb", properties);
当一个 EntityManagerFactory实例被创建时,就会打开数据库文件,如果数据库还不存在,那么会自动创建一个库文件。
当应用程序停止时,也要主动关闭EntityManagerFactory ,emf.close();
,factory会关闭到库文件。
方法createEntityManagerFactory需要一个持久化单元的name作为参数,但是也可以用数据库文件的url来指定要连的库,格式如下:objectdb:xx,或者xxx.odb,或者xxx.objectdb。
如果以嵌入模式访问ObjectDB数据库,并且文件的扩展名是.odb或者.objectdb,那么url不需要指定协议objectdb:,如果文件的扩展名不是以上两种,那么url必须指定协议objectdb:。
而在客户机-服务器模式下,url格式必须是objectdb://host:port/库文件的path,path是库文件相对于服务器数据根目录的路径。port默认是6136.
客户端要连接到数据库,还需要用户名、密码,还可以指定是否清空删除原来的库,这些可以作为url的参数。
EntityManagerFactory emf = Persistence.createEntityManagerFactory(
"objectdb://localhost/myDbFile.odb;user=admin;password=admin"); //也可以将参数封装到Map里,
EntityManagerFactory emf = Persistence.createEntityManagerFactory("objectdb:myDbFile.tmp;drop");
drop参数只在库文件扩展名是.tmp或者.temp的情况下才能生效,这时为了避免数据丢失的风险,不过这也是可以配置的。
可以通过如下方式直接获取并使用 EntityManager:
EntityManager em = emf.createEntityManager();
try { // TODO: Use the EntityManager to access the database
}
finally { em.close(); }
EntityManager 实例是从EntityManagerFactory 中获取的,最后也要调用close方法释放资源,归还到factory中去。
facotry也定义了另一方法来实例化EntityManager,这一方法类似factory的第二种实例化方法,接收一个封装了属性的Map类型的参数。这种方式允许应用程序以不同于factory的用户的另一用户身份获取EntityManager即数据库连接。
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.persistence.jdbc.user", "user1");
properties.put("javax.persistence.jdbc.password", "user1pwd");
EntityManager em = emf.createEntityManager(properties);
对数据库的数据的更新操作都必须在活动事务内进行。在JPA规范里,定义了接口EntityTransaction 来做事务管理。每个EntityManager实例都持有一个EntityTransaction的实例,可以通过以下方式获得和使用:
try {
em.getTransaction().begin();
// Operations that modify the database should come here.
em.getTransaction().commit();
}
finally {
if (em.getTransaction().isActive())
em.getTransaction().rollback();
}
调用begin()方法则进入一个活动事务,调用commit()方法或者rollback()方法则结束事务。在这中间操作的所有数据都被存储在内存中,并且关联到此事务,知道事务结束。如果事务被回滚,则对数据库的所有更新都会被丢弃。但是内存中的数据并不受回滚的影响,也不会回退到更新之前的状态。