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

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

内容简介: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主题


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

查看所有标签

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

产品心经:产品经理应该知道的60件事(第2版)

产品心经:产品经理应该知道的60件事(第2版)

闫荣 / 机械工业出版社 / 2016-4 / 69.00

本书第一版出版后广获好评,应广大读者要求,作者把自己在实践中新近总结的10个关于产品的最佳实践融入到了这本新书中。这"10件事"侧重于深挖产品需求和产品疯传背后的秘密,配合之前的"50件事",不仅能帮产品经理打造出让用户尖叫并疯传的产品,还能帮助产品经理迅速全方位提升自己的能力。 本书作者有超过10年的产品工作经验,在互联网产品领域公认的大咖,这本书从产品经理核心素养、产品认知、战略与规划、......一起来看看 《产品心经:产品经理应该知道的60件事(第2版)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具