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

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

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


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

查看所有标签

猜你喜欢:

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

Spark技术内幕

Spark技术内幕

张安站 / 机械工业出版社 / 2015-9-1

Spark是不断壮大的大数据分析解决方案家族中备受关注的新增成员。它不仅为分布式数据集的处理提供一个有效框架,而且以高效的方式处理分布式数据集。它支持实时处理、流处理和批处理,提供了AllinOne的统一解决方案,使得Spark极具竞争力。 本书以源码为基础,深入分析Spark内核的设计理念和架构实现,系统讲解各个核心模块的实现,为性能调优、二次开发和系统运维提供理论支持;本文最后以项目实战......一起来看看 《Spark技术内幕》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试