10. Oracle Express 11g Release 2
接下来我们将讨论如何将针对 MySQL 5 所做的改动移植到 Oracle Express 11g Release 2 上。
![]() |
10.1. 搭建开发环境
10.1.1. Eclipse 环境
我们将使用以下 Eclipse 环境:
![]() |
上述 Oracle 项目位于 [<examples>/spring-database-config\oracle\eclipse] 文件夹中。
注意:按 [Alt-F5] 可重新生成所有 Maven 项目。
启动 Oracle Express 及其客户端 [OraManager](参见第 23.6 节)。我们将使用 [generic-create-dbproduits] 项目生成:
- 使用 [generic-create-dbproduits] 项目生成 [dbproduits] 数据库;
- 使用 [generic-create-dbproduitscategories] 项目生成 [dbproduitscategories] 数据库;
10.1.2. 创建用户
现在所有操作都在 [OraManager] 中进行。Oracle 数据库管理系统必须正在运行。我们使用 system / system 凭据登录系统管理员(此配置必须已预先完成)。我们将创建两个用户:
- [DBPRODUITS / dbproduits],该用户将作为 [dbproduits] 数据库的所有者;
- [DBPRODUCTSCATEGORIES / dbproducts-categories],该用户将作为 [dbproducts-categories] 数据库的所有者;
![]() |
![]() |
- 在 [6-7] 中,凭据为 [system / system];
![]() |
![]() |
- 在 [14] 中:输入 dbproduits;
- 在 [16] 中,用户已创建,但没有足够的权限登录。我们将通过一个 SQL 脚本 [17-18] 授予其权限;
![]() |
- 在 [19] 中,请输入大写用户名;
我们采用相同的方法创建用户 [DBPRODUITSCATEGORIES / dbproduitscategories]:
![]() | ![]() |
![]() |
10.1.3. 在 Maven 仓库中安装 Oracle JDBC 驱动程序
Oracle JDBC 驱动程序在中央 Maven 存储库中不可用。必须从 Oracle [http://www.oracle.com/technetwork/apps-tech/jdbc-112010-090769.html] 下载:
![]() |
下载完成后,必须将其安装到本地 Maven 仓库中。可通过以下 DOS 脚本 [install.bat] [2] 完成此操作:
"%M2_HOME%\bin\mvn.bat" install:install-file -Dfile=ojdbc6.jar -Dpackaging=jar -DgroupId=com.oracle.jdbc -DartifactId=ojdbc6 -Dversion=1.0
其中 [%M2_HOME%] 应替换为 Maven 安装目录的路径(参见第 23.2 节)。完成此操作后,即可通过以下配置将 JDBC 驱动程序导入 Maven 项目:
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>1.0</version>
</dependency>
10.1.4. 创建 [dbproduits] 数据库
现在我们已拥有用户 [DBPRODUITS / dbproduits],将使用以下凭据连接到 Oracle:
![]() |
![]() |
- 在 [6] 中,输入 dbproduits;
- 在 [9] 中,输入我们将要使用的 [DBPRODUITS] 数据库;
在 [oracle-config-jdbc] 项目的 [ConfigJdbc] 类中,使用的连接参数如下:
public final static String DRIVER_CLASSNAME = "oracle.jdbc.OracleDriver";
public final static String URL_DBPRODUITS = "jdbc:oracle:thin:@localhost:1521:xe";
public final static String USER_DBPRODUITS = "DBPRODUITS";
public final static String PASSWD_DBPRODUITS = "dbproduits";
public final static String URL_DBPRODUITSCATEGORIES = "jdbc:oracle:thin:@localhost:1521:xe";
public final static String USER_DBPRODUITSCATEGORIES = "DBPRODUITSCATEGORIES";
public final static String PASSWD_DBPRODUITSCATEGORIES = "dbproduitscategories";
您必须根据您的 Oracle 配置进行调整。
在 [oracle-config-jpa-eclipselink] 项目中,JPA 实体定义如下:
![]() |
package generic.jpa.entities.dbproduits;
import generic.jdbc.config.ConfigJdbc;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity(name="Produit1")
@Table(name = ConfigJdbc.TAB_PRODUITS)
public class Produit {
// fields
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqProduits")
@SequenceGenerator(name="genSeqProduits",sequenceName="PRODUITS_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_PRODUITS_ID)
private Long id;
@Column(name = ConfigJdbc.TAB_PRODUITS_NOM, unique = true, length = 30, nullable = false)
private String nom;
@Column(name = ConfigJdbc.TAB_PRODUITS_CATEGORIE, nullable = false)
private int categorie;
@Column(name = ConfigJdbc.TAB_PRODUITS_PRIX, nullable = false)
private double prix;
@Column(name = ConfigJdbc.TAB_PRODUITS_DESCRIPTION, length = 100, nullable = false)
private String description;
...
}
- 第 18-19 行:[PRODUITS] 表的主键生成策略为 [strategy=GenerationType.SEQUENCE]。对于 MySQL,我们使用了策略 [ ] [@GeneratedValue(strategy = GenerationType.IDENTITY)]。在 Oracle Express 11g 中,此策略无法使用;
- 第 18 行:我们指定主键将通过数字生成器(通常称为序列)生成;
- 第 19 行:序列生成器(name 属性引用第 18 行中的生成器)将在 [dbproduits] 数据库中创建一个名为 [PRODUITS_SEQUENCE] 的序列。由于我们需要确保 JPA 实现之间的可移植性,因此为序列命名至关重要。 否则,若省略第 19 行,三种 JPA 实现将创建名称各异的序列,导致 JPA2 无法使用 JPA1 创建的数据库;
现在我们可以运行 [generic-create-dbproduits-eclipselink] 配置了:
![]() | ![]() |
运行此配置将创建两个对象:
- 一个表 [PRODUCTS];
- 一个名为 [PRODUITS_SEQUENCE] 的序列
![]() | ![]() |
[PRODUCTS] 表的 DDL 如下:
![]() |
主键 [ID] 不会像在 MySQL 中那样自动递增。不过,[spring-jdbc-03] 项目假设数据库管理系统(DBMS)会负责生成 [PRODUCTS] 表的主键。 我们将创建一个触发器。触发器是数据库管理系统(DBMS)中的一种存储过程,会在特定条件下执行。我们将创建一个触发器,该触发器会在每次插入新数据时,基于 JPA 配置创建的 [PRODUCTS_SEQUENCE] 序列,为插入的产品生成主键。
![]() |
- 在 [6] 中,触发器 [PRODUCTS_ID_TRIGGER] [4] 将在每次插入之前执行;
- 在[7]中,这是一个针对Oracle数据库管理系统(DBMS)的存储过程。它规定待插入行的[ID]字段必须初始化为名为[PRODUITS_SEQUENCE]的生成器生成的下一个值;
![]() |
[dbproduits] 数据库现已准备就绪。请执行以下配置:
- [spring-jdbc-generic-01.IntroJdbc01];
- [spring-jdbc-generic-01.IntroJdbc02];
- [spring-jdbc-generic-03.JUnitTestDao1];
- [spring-jdbc-generic-03.JUnitTestDao2];
它们都必须通过。
10.1.5. 生成 [dbproduitscategories] 数据库
![]() |
接下来我们将运行 [generic-create-dbproduitscategories] 项目,该项目将生成 [dbproduitscategories] 数据库。在此之前,请在 [OraManager] 中使用凭据 [DBPRODUITSCATEGORIES / dbproduitscategories] 进行连接,以便观察 [dbproduitscategories] 数据库所做的更改:
![]() | ![]() | ![]() |
![]() | ![]() |
![]() |
所使用的 JPA 实体具有以下主键生成策略:
[类别]
public class Categorie implements AbstractCoreEntity {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqCategories")
@SequenceGenerator(name="genSeqCategories",sequenceName="CATEGORIES_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_JPA_ID)
protected Long id;
[产品]
public class Produit implements AbstractCoreEntity {
// properties
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqProduits2")
@SequenceGenerator(name="genSeqProduits2",sequenceName="PRODUITS_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_JPA_ID)
protected Long id;
[角色]
public class Role implements AbstractCoreEntity {
// properties
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqRoles")
@SequenceGenerator(name="genSeqRoles",sequenceName="ROLES_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_JPA_ID)
protected Long id;
[用户]
public class User implements AbstractCoreEntity {
// properties
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqUsers")
@SequenceGenerator(name="genSeqUsers",sequenceName="USERS_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_JPA_ID)
protected Long id;
[UserRole]
public class UserRole implements AbstractCoreEntity {
// properties
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="genSeqUsersRoles")
@SequenceGenerator(name="genSeqUsersRoles",sequenceName="USERS_ROLES_SEQUENCE", allocationSize=5)
@Column(name = ConfigJdbc.TAB_JPA_ID)
protected Long id;
与 [dbproduits] 数据库的做法一样,将生成五个序列。JPA 实现会使用这些序列来生成主键。JPA 实现不会像我们之前那样使用触发器,而是通过查询序列来获取下一个主键。我们还将使用触发器生成主键。这些是 [spring-jdbc-04] 项目所必需的。
我们运行 [generic-create-dbproduitscategories-eclipselink] 配置:
![]() | ![]() |
并得到以下结果:
![]() |
然后,我们创建五个触发器,用于为这五个表生成主键:
![]() |
这些触发器与表的关联如下:
分类 | CATEGORIES_ID_TRIGGER | 分类_序列 |
产品 | 产品ID触发器 | PRODUCTS_SEQUENCE |
ROLES | ROLES_ID_TRIGGER | ROLES_SEQUENCE |
USERS | 用户_ID_触发器 | 用户序列 |
USERS_ROLES | USERS_ROLES_ID_TRIGGER | USERS_ROLES_SEQUENCE |
![]() |
[spring-jdbc-04] 项目要求每个表中的 [VERSIONING] 列都必须具有默认值:
![]() | ![]() |
我们对所有五个表都进行了此设置。
现在,运行以下配置:
- [spring-jdbc-generic-04.JUnitTestDao];
- [spring-jpa-generic-JUnitTestDao-hibernate-eclipselink];
两者都应通过。
10.2. 配置 JDBC 层
![]() | ![]() |
[oracle-config-jdbc] 项目配置了以下测试架构的 [JDBC] 层:
![]() |
该项目类似于 MySQL 数据库管理系统 (DBMS) JDBC 层的 [mysql-config-jdbc] 配置项目(参见第 3.3 节)。此处仅列出更改内容:
[pom.xml] 文件引入了 Oracle JDBC 驱动程序:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dvp.spring.database</groupId>
<artifactId>generic-config-jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>configuration generic jdbc</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<!-- dépendances variables ********************************************** -->
<!-- driver JDBC from SGBD -->
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>1.0</version>
</dependency>
<!-- dépendances constantes ********************************************** -->
....
</dependencies>
...
</project>
- 第 18-22 行:Oracle JDBC 驱动程序替换了 MySQL 驱动程序;
第二个改动在 [ConfigJdbc] 类中,该类定义了数据库凭据:
// paramètres de connexion
public final static String DRIVER_CLASSNAME = "oracle.jdbc.OracleDriver";
public final static String URL_DBPRODUITS = "jdbc:oracle:thin:@localhost:1521:xe";
public final static String USER_DBPRODUITS = "DBPRODUITS";
public final static String PASSWD_DBPRODUITS = "dbproduits";
public final static String URL_DBPRODUITSCATEGORIES = "jdbc:oracle:thin:@localhost:1521:xe";
public final static String USER_DBPRODUITSCATEGORIES = "DBPRODUITSCATEGORIES";
public final static String PASSWD_DBPRODUITSCATEGORIES = "dbproduitscategories";
第三项更改涉及 所能支持的参数最大数量:
// max number of parameters of a [PreparedStatement]
public final static int MAX_PREPAREDSTATEMENT_PARAMETERS = 1000;
[JUnitTestPushTheLimits] 测试会为 5,000 种产品生成 SQL 语句,这将生成包含 5,000 个参数的 [PreparedStatement] 对象。MySQL 支持此参数数量,但 Oracle 不支持。我们将该值降至 1,000 后,测试便能正常运行。
10.3. EclipseLink JPA 层配置
![]() | ![]() |
注意:按 [Alt-F5] 可重新生成所有 Maven 项目。
[oracle-config-jpa-eclipseLink] 项目用于配置测试架构的 [JPA] 层:
![]() |
该项目与针对 MySQL 数据库管理系统(DBMS)的 EclipseLink JPA 层的 [mysql-config-jpa-eclipselink] 配置项目(参见第 7.3 节)类似。此处仅列出变更内容:
首先是在 [ConfigJpa] 类中对 [jpaVendorAdapter] Bean 的定义:
// the provider JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
// Note: JPA entities and Eclipselink configuration are in the META-INF/persistence.xml file
EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
eclipseLinkJpaVendorAdapter.setShowSql(false);
eclipseLinkJpaVendorAdapter.setDatabase(Database.ORACLE);
eclipseLinkJpaVendorAdapter.setGenerateDdl(true);
return eclipseLinkJpaVendorAdapter;
}
- 第 7 行:我们告知 JPA 实现,它将与 Oracle 数据库进行交互。随后,JPA 实现将采用 Oracle 的专有数据类型和 SQL。
第二个更改涉及主键生成策略。新策略已在第10.1节中介绍。
10.4. 配置 Hibernate JPA 层
![]() | ![]() |
注意:按 [Alt-F5] 可重新生成所有 Maven 项目。
[oracle-config-jpa-hibernate] 项目与 [mysql-config-jpa-hibernate] 项目(第 6.3 节)类似,采用了与将 [mysql-config-jpa-eclipselink] 移植到 [oracle-config-jpa-eclipselink] 项目(第 10.3 节)时相同的修改方案。
完成这些修改后,[spring-jpa-generic-JUnitTestDao-hibernate-eclipselink] 配置的执行应能成功。
10.5. 配置 OpenJpa JPA 层
![]() | ![]() |
注意:按 [Alt-F5] 可重新生成所有 Maven 项目。
[oracle-config-jpa-openjpa] 项目与 [mysql-config-jpa-openjpa] 项目(第 8.3 节)类似,采用了与将 [mysql-config-jpa-eclipselink] 项目移植到 [oracle-config-jpa-eclipselink] 项目(第 10.3 节)时相同的修改。
完成这些修改后,[spring-jpa-generic-JUnitTestDao-openjpa] 配置的执行应能成功。
![]() | ![]() |














































