SpringDataJDBC一对一/一对多关系实现

栏目: Java · 发布时间: 5年前

内容简介:Spring Data JDBC能够支持DDD中聚合概念,实际支持ER中星型模型,在DDD中聚合根实体代表整体概念,映射到数据表中就是星型模型中的主表,整体和部分的关系一般是一对一和一对多关系,其中一代表整体这一方,不会存在多对一或多对多关系,因为整体只能有一个。首先看看一对一关系,一对一关系体现在对象和数据表两个方面,先看看你对象的一对一关系,假设有一个Order订单,其中包含了对地址Address的一对一关系,Order代码如下:..

Spring Data JDBC一对一和一对多关系实现

Spring Data JDBC能够支持DDD中聚合概念,实际支持ER中星型模型,在DDD中聚合根实体代表整体概念,映射到数据表中就是星型模型中的主表,整体和部分的关系一般是一对一和一对多关系,其中一代表整体这一方,不会存在多对一或多对多关系,因为整体只能有一个。

1:1关系

首先看看一对一关系,一对一关系体现在对象和数据表两个方面,先看看你对象的一对一关系,假设有一个Order订单,其中包含了对地址Address的一对一关系,Order代码如下:

@Table("ordersample")
public class Order {
   @org.springframework.data.annotation.Id
   public Integer Id;
    //代表一对一的关系
   public Address address;

..

}

Address的代码如下:

public class Address {
   @org.springframework.data.annotation.Id
   public Integer Id;
   public String street;
   public String zipcode;
}

一对一关系中,对象的类中都必须有一个主键标识,如上面的Id,Order和Address都有一个唯一标识Id,注释都是@org.springframework.data.annotation.Id,注意不是javax.persistence.Id,后者是JPA的主键标识。

那么,对应的数据表结构应该怎样呢?我们可以从运行出错的信息中一窥究竟。

先把仓储接口写好:

public interface OrderRepo extends CrudRepository<Order, Integer>

再写好测试代码:

Order order = new Order();

Address address = new Address();
address.street = "a street";
address.zipcode = "123456789";
order.address = address;

orderRepo.save(order);

试验运行的时候会提示 SQL 出错,数据表结构没有创建:

Table "ORDERSAMPLE" not found; SQL statement:

INSERT INTO ordersample () VALUES () [42102-197]

Order对应的数据表ordersample没有创建,注意这里数据表名称如果不指定ordersample,默认是order会引起冲突,order是保留名称。

ordersample数据表主要是一个自增主键:

CREATE TABLE ordersample (
  id   Integer IDENTITY PRIMARY KEY,
);

在application.properties填入配置:

logging.level.sql=true
database=h2
spring.datasource.schema=classpath*:schema.sql
spring.h2.console.enabled=Debug

这里需要导入schema.sql用来创建数据表结构。将ordersample数据表结构SQL放入schema.sql即可。

再次运行测试程序:

Caused by: org.h2.jdbc.JdbcSQLException: Table "ADDRESS" not found; SQL statement:

INSERT INTO address (street, zipcode, ordersample) VALUES (?, ?, ?) [42102-197]

这里SQL语句已经显示Address对应的address数据表结构:

CREATE TABLE address (
  id   Integer IDENTITY PRIMARY KEY,
  ordersample   Integer,
  street VARCHAR(80),
  zipcode VARCHAR(80)
);

这里的id对应类Address中@Id标注的主键,street和zipcode也是对应类Address的字段,比较特殊的是ordersample,这个显然是一个代表关系的外键,指向ordersample数据表,也就是说,数据表之间表达一对一关系的方式是通过外键引用实现的。

1:N关系

假设订单Order中存在OrderItem:

@Table("ordersample")
public class Order {
   @org.springframework.data.annotation.Id
   public Integer Id;
   //1:1
   public Address address;
   //1:N
   public Collection<OrderItem> items;

类Order中使用集合Collection表示多个OrderItem,OrderItem的代码:

public class OrderItem {
   public String productVO;
   public int qty;

}

注意到,在1:N关系中,多方这里无需使用@Id唯一主键,从DDD角度来看,OrderItem其实是一个值对象,值对象与实体的区别就是没有唯一标识。OrderItem对应的数据表结构:

CREATE TABLE order_item (
  ordersample_key Integer IDENTITY PRIMARY KEY,
  product_vo VARCHAR(80),
  qty INTEGER,
  ordersample INTEGER
);

我们注意到,Spring Data JDBC默认使用ordersample_key作为order_item表的主键,因为OrderItem对象是值对象,但是数据表需要主键,因此使用ordersample_key,同时外键ordersample指向同名的主表ordersample,这是数据表的1:N的方式。

源码

Spring Data JDBC主题


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Concurrency on the JVM

Programming Concurrency on the JVM

Venkat Subramaniam / The Pragmatic Bookshelf / 2011-6-1 / USD 35.00

Concurrency on the Java platform has evolved, from the synchronization model of JDK to software transactional memory (STM) and actor-based concurrency. This book is the first to show you all these con......一起来看看 《Programming Concurrency on the JVM》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码