JPA入门(3)--继承2

本文探讨了ORM中针对类层次结构的子类表继承策略,通过为每个子类创建独立的表格来存储特定属性,避免了单一表格策略的冗余问题。文章详细介绍了如何在Java环境下实现这一策略。

 

Separate Table per Subclass

       这个策略为类层次中的每个子类创建一个单独的表格。这些表格的结构只包含子类中独立于类层次中父类的属性。为了用Java实现这个策略,我们只需简单地从根类中移除有关discriminator的元注释,并且更改根类中的继承类型。源码9.13展示了这些。

@Entity(name=”RoadVehicleJoined”)

@Table(name=”ROADVEHICLEJOINED”)

@Inheritance(strategy=InheritanceType.JOINED)

public class RoadVehicle {

...

}

Source 9.13 RoadVehicle with table per subclass strategy.

这次我们使用InheritanceType.JOINED指明为每个子类创建一个表格的策略。在这个策略中为了解决子类中的所有属性,必须使用联接。父类中的Id字段作为代表子类表格的外键。我们使用@Table元注释指明数据库中的不同与类名表格名称,这个用例中用以区别于前一个例子。默认地容器将创建与类名相同的表格。因为我们已经有一RoadVehicle类相应地有一名为ROADVEHICLE的表,所以我们指明用ROADVEHICLEJOINED表格名以之区别。

使用与源码9.12相同的代码,我们来看下运行后生成的表格。表格9.2-9.6展示这些表格。

每个表格都有一ID字段,以用于联接具体有实体。代表根类的表格有一区别字段。默认地该字段的名称为DTYPE,并且字段类型是DiscriminatorType.STRING。这个字段使用与单一表格策略相同的方法赋值。

 Table 9.2 ROADVEHICLEJOINED TABLE

----------------------------------------------------------------------------------

ID              DTYPE        NUMPERWHEELS   MAKE        MODEL

1423656697 Coupe             4                          Bob            E400
1425368051 Motorcycle     2                          NULL          NULL
1424968207 Roadster         4                          Mini            Cooper S

----------------------------------------------------------------------------------

Table 9.3 MOTORCYCLE Table
----------------------------------------
ID  ACCELERTORTYPE
1425368051  1
----------------------------------------
Table 9.4 CAR Table
----------------------------------------
ID  ACCELERTORTYPE
1423656697  0
1424968207  0
----------------------------------------
Table 9.5 COUPLE Table
----------------------------------------
ID  BORINGFACTOR
1423656697  0
----------------------------------------
Table ROADSTER Table
----------------------------------------
ID  COOLFACTOR
1423656697  2
----------------------------------------

现在假设我们想获得所有的Roadster实体。在后台以下SQL语句可能被执行。为了获取子类的所有属性,我们必须使用联接。这种策略不支持多态。如果类层次不是很深,使用这种策略很好。但如果类层次比较很深则不宜使用些策略。

SELECT

rvj.NumWheels, rvj.Make, rvj.Model,

c.AcceleratorType, r.CoolFactor

FROM

ROADVEHICLEJOINED rvj, CAR c, ROADSTER r

WHERE

rvj.Id = c.Id and c.Id = r.Id;

Single Table per Concrete Entity Class

在这种种策略中每个concrete子类都有自己对应的表格。每个表格拥有所代表的实体的所有的属性(包括从父类继承的)。给出原来的源码即source9,1-9.5,我们可以期望以下布局的表格,如Tables 9.7–9.9.在这种策略中每个子类拥有继承自父类的所有属性。这种策略也不支持多态。由于这种策略并不是支持EJB 3.0规范所必须的,所有我们就不深入论文这种方法了。

Table 9.7 Database Table Layout Mapped for Roadster.java

ID NUMPASSENGERS NUMWHEELS MAKE MODEL ACCELERATORTYPE COOLFACTOR

Table 9.8 Database Table Layout Mapped for Coupe.java

ID NUMPASSENGERS NUMWHEELS MAKE MODEL ACCELERATORTYPE BORINGFACTOR

Table 9.9 Database Table Layout Mapped for Motorcycle.java

ID NUMPASSENGERS NUMWHEELS MAKE MODEL ACCELERATORTYPE

 

### Spring Data JPA 入门教程 #### 创建 Maven 或 Gradle 项目结构 为了开始使用 Spring Data JPA,首先需要设置好开发环境。这通常意味着创建一个新的 Maven 或 Gradle 项目,并添加必要的依赖项来支持 Spring Boot 和 Spring Data JPA 功能。 对于 Maven 用户,在 `pom.xml` 文件中加入如下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 而对于 Gradle 用户,则应在 `build.gradle` 中添加相应的行: ```groovy implementation &#39;org.springframework.boot:spring-boot-starter-data-jpa&#39; ``` #### 定义实体类 定义一个简单的 Java 类作为持久化对象模型的一部分。例如,可以基于给定的图书类例子[^3] 来构建自己的实体类。注意这里的注解用于指定表名、字段映射以及关系管理等细节。 ```java @Getter @Setter @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer bookId; private String bookName; private Float price; private Date pubdate; @ManyToOne(fetch = FetchType.LAZY) private Author author; } ``` #### 配置数据源和 JPA 设置 在应用程序属性文件 (`application.properties`) 中提供连接到目标数据库所需的信息。如果希望简化初期的学习过程,可以选择内存型数据库如 H2 数据库来进行练习,这样就不必担心实际部署中的复杂配置问题[^2]。 ```properties spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect ``` #### 编写 Repository 接口 接下来就是实现 DAO (Data Access Object) 层了。按照所提供的代码片段[^4] ,只需继承自 `JpaRepository<T, ID>` 即可获得一组丰富的 CRUD 方法集合而不需要额外编写任何 SQL 查询语句。 ```java @Repository public interface UserRepository extends JpaRepository<User, String> {} ``` 同样地,针对上面提到过的书籍实体也可以建立对应的仓库接口: ```java public interface BookRepository extends JpaRepository<Book, Integer> {} ``` #### 测试功能 完成上述准备工作之后便可以通过 RESTful API 或者命令行工具 POSTMAN 对服务端点发起请求验证各项操作是否正常工作[^1] 。此外还可以利用内置的支持机制快速执行单元测试而不必真的启动整个应用上下文环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值