2012年9月25日星期二

Coherence_009:Coherence入门指南之九:与JPA集成

运行环境:JDeveloper 11.1.2.2.0 + Coherence3.7.1 + Oracle Database 10g Express Edition 10.2.0.1。

JPA是数据持久化的标准,Coherence可以作为数据的缓存,如果二者可以结合,岂不完美?
集成的方式有两种:
(1)Coherence在上层,JPA在下层,通过Coherence Cache API 访问和操作数据。
(2)JPA在上层,Coherence在下层,通过Java Persistence API访问和操作数据。
本文介绍的是第一种。

1. 创建JPA
(1)选择Entities from Tables
 (2)选择JPA Entities
  (2)使用默认的Persistence Unit:ConherenceProject
每一个 Persistence Unit定义了JPA Entities、Persistence Provider以及数据库连接信息。
 (3)连接数据库

 (4)选择Employees表
 (5)设置package路径和其它属性,使用默认设置即可

(5)修改persistence.xml
这是改动前的persistence.xml,是JDeveloper帮我们自动生成的。
<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
             version="2.0">
  <persistence-unit name="CoherenceProject">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>java:/app/jdbc/jdbc/HRConnDS</jta-data-source>
    <class>com.oracle.coherence.handson.jpa.Employees</class>
    <properties>
      <property name="eclipselink.target-server" value="WebLogic_10"/>
      <property name="javax.persistence.jtaDataSource" value="java:/app/jdbc/jdbc/HRConnDS"/>
    </properties>
  </persistence-unit>
</persistence>

这是改动后的persistence.xml,为了简单起见,这里我直接使用了JDBC URL的方式连接数据库。
<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
             version="2.0">
    <persistence-unit name="CoherenceProject">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.oracle.coherence.handson.jpa.Employees</class>
        <properties>
            <property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
            <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
            <property name="eclipselink.jdbc.user" value="hr"/>
            <property name="eclipselink.jdbc.password" value="hr"/>
        </properties>
    </persistence-unit>
</persistence>

2. 添加必要的Library
(1)这是添加完成后的样子
(2)在Coherence Library中,添加coherence-jpa.jar
(3)新增Oracle JDBC Library中,添加ojdbc6-g.jar

3.  集成JPA
(1)创建一个XML文件:jpa-cache-config.xml
Coherence是如何与JPA集成的呢?答案就在jpa-cache-config.xml文件中。

<?xml version="1.0" encoding="UTF-8" ?>
<cache-config>
    <caching-scheme-mapping>
        <cache-mapping>
            <!-- Set the name of the cache to be the entity name  -->
            <cache-name>Employees</cache-name>
            <!-- Configure this cache to use the scheme defined below  -->
            <scheme-name>jpa-distributed</scheme-name>
        </cache-mapping>
    </caching-scheme-mapping>
    <caching-schemes>
        <distributed-scheme>
            <scheme-name>jpa-distributed</scheme-name>
            <service-name>JpaDistributedCache</service-name>
            <backing-map-scheme>
                <read-write-backing-map-scheme>
                    <!-- Define the cache scheme -->
                    <internal-cache-scheme>
                        <local-scheme/>
                    </internal-cache-scheme>
                    <cachestore-scheme>
                        <class-scheme>
                            <class-name>com.tangosol.coherence.jpa.JpaCacheStore</class-name>
                            <init-params>
                                <!-- This param is the entity name
                                     This param is the fully qualified entity class
                                     This param should match the value of the persistence unit name in persistence.xml
                                -->
                                <init-param>
                                    <param-type>java.lang.String</param-type>
                                    <param-value>{cache-name}</param-value>
                                </init-param>
                                <init-param>
                                    <param-type>java.lang.String</param-type>
                                    <param-value>com.oracle.coherence.handson.jpa.{cache-name}</param-value>
                                </init-param>
                                <init-param>
                                    <param-type>java.lang.String</param-type>
                                    <param-value>CoherenceProject</param-value>
                                </init-param>
                            </init-params>
                        </class-scheme>
                    </cachestore-scheme>
                </read-write-backing-map-scheme>
            </backing-map-scheme>
            <autostart>true</autostart>
        </distributed-scheme>
    </caching-schemes>
</cache-config>

(2)修改DefaultCacheServer Profile,增加Java Option:-Dtangosol.coherence.cacheconfig=jpa-cache-config.xml

(3)修改NoLocalStorage Profile,增加Java Option:-Dtangosol.coherence.cacheconfig=jpa-cache-config.xml

4.  代码
(1)Employees.java
这是JPA Entity类,是JDeveloper自动帮我们生成的。
其中定义了很多JPA 批注,用于定义如何从数据库读取和存储Employees对象。

(2) RunEmployeeExample.java 测试类
package com.oracle.coherence.handson.jpa;


import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

import java.math.BigDecimal;

public class RunEmployeeExample {
    public RunEmployeeExample() {
    }

    public static void main(String[] args) {
        BigDecimal empId = new BigDecimal(190); // emp 190 - Timothy Gates

        NamedCache employees = CacheFactory.getCache("Employees");

        Employees emp = (Employees)employees.get(empId);

        System.out.println("Employee " + emp.getFirstName() + " " + emp.getLastName() + ", salary = $" +
                           emp.getSalary());

        // give them a 10% pay rise
        emp.setSalary(emp.getSalary().multiply(new BigDecimal(1.1)));

        employees.put(empId, emp);

        Employees emp2 = (Employees)employees.get(empId);

        System.out.println("New Employee details are " + emp2.getFirstName() + " " + emp2.getLastName() +
                           ", salary = $" + emp2.getSalary());
    }
}
说明:
当调用get()获取数据时,首先访问Coherence缓存,如果有则直接得到,如果没有再通过JPA从数据库中获取。
当调用put()修改数据时,Coherence使用JPA持久化数据到数据库。

5.  运行
(1)选择运行DefaultCacheServer Profile,作为存储数据的Cache。
(2)选择NoLocalStorage Profile,并运行 RunEmployeeExample ,会发现employeeId=190的员工的工资涨了10%,进入数据库中查看,发现数据也修改了。

Project 下载:CoherenceApp(Lab9).7z

1 条评论:

BeeTruth 说...

有缘千里来相会, 无缘对面不相逢。

感恩您在部落格的分享。

难得找到同行分享 :) 赞!

有空请来我的网站看看吧!

一个关于人生的分享, 一个以慈善为关怀方式的集聚点。

http://beetruth.niceboard.com

感恩您! :) 中秋节快乐 :)