当前位置 > it书童 > java > 正文

SpringDataJPA 中的一对多关系

java it书童 2020-11-19 22:05:14 0赞 0踩 28阅读 0评论

表关系建立

我们采用的示例为客户和联系人。

客户:指的是一家公司,我们记为A。

联系人:指的是A公司中的员工。

在不考虑兼职的情况下,公司和员工的关系即为一对多。

在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表。在数据库中建立一对多的关系,需要使用数据库的外键约束。

什么是外键?指的是从表中有一列,取值参照主表的主键,这一列就是外键。

在实体类中,由于客户是少的一方,它应该包含多个联系人,所以实体类要体现出客户中有多个联系人的信息

创建两个实体类

联系人实体类

@Entity
@Table(name = "cst_linkman")
public class LinkMan {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "lkm_id")
    private Long lkmId; //联系人编号(主键)
    @Column(name = "lkm_name")
    private String lkmName;//联系人姓名
    @Column(name = "lkm_gender")
    private String lkmGender;//联系人性别
    @Column(name = "lkm_phone")
    private String lkmPhone;//联系人办公电话
    @Column(name = "lkm_mobile")
    private String lkmMobile;//联系人手机
    @Column(name = "lkm_email")
    private String lkmEmail;//联系人邮箱
    @Column(name = "lkm_position")
    private String lkmPosition;//联系人职位
    @Column(name = "lkm_memo")
    private String lkmMemo;//联系人备注

    /**
     * 配置联系人到客户的多对一关系
     *     使用注解的形式配置多对一关系
     *      1.配置表关系
     *          @ManyToOne : 配置多对一关系
     *              targetEntity:对方的实体类字节码
     *      2.配置外键(中间表)
     *
     * * 配置外键的过程,配置到了多的一方,就会在多的一方维护外键
     *
     */
    @ManyToOne(targetEntity = Customer.class,fetch = FetchType.LAZY)
    @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
    private Customer customer;

    // ... 
}

客户实体类

@Entity
@Table(name="cst_customer")
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="cust_id")
    private Long custId;
    @Column(name="cust_address")
    private String custAddress;
    @Column(name="cust_industry")
    private String custIndustry;
    @Column(name="cust_level")
    private String custLevel;
    @Column(name="cust_name")
    private String custName;
    @Column(name="cust_phone")
    private String custPhone;
    @Column(name="cust_source")
    private String custSource;

    //配置客户和联系人之间的关系(一对多关系)
    @OneToMany(mappedBy = "customer",cascade = CascadeType.ALL)
    private Set<LinkMan> linkMans = new HashSet<>();

    // ...
}

映射的注解说明

@OneToMany:建立一对多的关系映射,属性:

  • targetEntityClass:指定多的多方的类的字节码

  • mappedBy:指定从表实体类中引用主表对象的名称。

  • cascade:指定要使用的级联操作

  • fetch:指定是否采用延迟加载

  • orphanRemoval:是否使用孤儿删除

@ManyToOne:建立多对一的关系,属性:

  • targetEntityClass:指定一的一方实体类字节码

  • cascade:指定要使用的级联操作

  • fetch:指定是否采用延迟加载

  • optional:关联是否可选。如果设置为false,则必须始终存在非空关系。

@JoinColumn:用于定义主键字段和外键字段的对应关系,属性:

  • name:指定外键字段的名称

  • referencedColumnName:指定引用主表的主键字段名称

  • unique:是否唯一。默认值不唯一

  • nullable:是否允许为空。默认值允许。

  • insertable:是否允许插入。默认值允许。

  • updatable:是否允许更新。默认值允许。

  • columnDefinition:列的定义信息。

一对多操作

添加数据

@Test
@Transactional
@Rollback(false)
public void testAdd() {
    // 创建一个客户
    Customer customer = new Customer();
    customer.setCustName("baidu");

    // 创建一个联系人
    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("xiaoli");

    // 配置联系人到客户的关系(多对一)
    linkMan.setCustomer(customer);
    customerDao.save(customer);
    linkManDao.save(linkMan);
}

级联添加:保存一个客户的同时,保存客户的所有联系人,需要在操作主体的实体类上,配置casacde属性

@Test
@Transactional
@Rollback(false)
public void testCascadeAdd() {
    Customer customer = new Customer();
    customer.setCustName("ali");

    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("xiaoma");

    linkMan.setCustomer(customer);
    customer.getLinkMans().add(linkMan);

    customerDao.save(customer);
}

级联删除:删除客户的同时,删除该客户的所有联系人

@Test
@Transactional
@Rollback(false)
public void testCascadeRemove() {
    Customer customer = customerDao.findOne(1L);
    customerDao.delete(customer);
}

源码 javaDemo 51cf714

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/834