SpringData - 一对多表的操作

基与上一篇文章 Specifications 接口动态查询入门小 demo , 我们继续深入

 

一. 创建联系人表(与顾客表是多对一关系)

/*创建联系人表*/
CREATE TABLE cst_linkman (
  lkm_id BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
  lkm_name VARCHAR(16) DEFAULT NULL COMMENT '联系人姓名',
  lkm_gender CHAR(1) DEFAULT NULL COMMENT '联系人性别',
  lkm_phone VARCHAR(16) DEFAULT NULL COMMENT '联系人办公电话',
  lkm_mobile VARCHAR(16) DEFAULT NULL COMMENT '联系人手机',
  lkm_email VARCHAR(64) DEFAULT NULL COMMENT '联系人邮箱',
  lkm_position VARCHAR(16) DEFAULT NULL COMMENT '联系人职位',
  lkm_memo VARCHAR(512) DEFAULT NULL COMMENT '联系人备注',
  lkm_cust_id BIGINT(32) NOT NULL COMMENT '客户id(外键)',
  PRIMARY KEY (`lkm_id`),
  KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
  CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=INNODB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

二. 创建数据库中联系人表的实体类

package com.cast.domain;
 
import java.io.Serializable;
import javax.persistence.*;
 
/**
 * 封装数据库中表的实体类
 */
@Entity    //该类是一个数据库表实体封装类
@Table(name = "cst_linkman")    //指定数据库中对应表名
public class Customer implements Serializable {
 
    @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;    //联系人备注

    /**
     * 配置联系人到客户的多对一关系
     */
    @ManyToOne(targetEntity = Customer.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "lkm_cust_id", referencedColumnName = "cust_id")
    private Customer customer;
 
    // getter setter 方法....
 
    // toString() 方法....

}

三. 创建符合 SpringDataJpa 的 dao 层接口规范

public interface LinkManDao extends JpaRepository<LinkMan, Long>, JpaSpecificationExecutor<LinkMan> {

}

四.Customer 封装类中添加一对多的注解配置

@OneToMany(targetEntity = LinkMan.class)
@JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
private Set<LinkMan> linkMans = new HashSet<>();

五. 创建新的测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class OneToManyTest {

    @Autowired
    private CustomerDao customerDao;

    @Autowired
    private LinkManDao linkManDao;


}

1. 添加数据的方法

配置客户到联系人的关系:

@Test
@Transactional  //配置事务
@Rollback(false)  //不自动回滚
public void testAddByCustomer() {
    //创建一个客户
    Customer customer = new Customer();
    customer.setCustName("张三");
    customer.setCustAddress("武汉市汉阳区");
    //创建一个联系人
    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("小李");
    linkMan.setLkmPhone("1313131313");
    //配置客户到联系人的关系
    customer.getLinkMans().add(linkMan);

    customerDao.save(customer);
    linkManDao.save(linkMan);
}

配置联系人到客户的关系:

@Test
@Transactional  //配置事务
@Rollback(false)  //不自动回滚
public void testAddByLinkman() {
    //创建一个客户
    Customer customer = new Customer();
    customer.setCustName("张三");
    customer.setCustAddress("武汉市汉阳区");
    //创建一个联系人
    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("小李");
    linkMan.setLkmPhone("1313131313");
    //配置联系人到客户的关系
    linkMan.setCustomer(customer);

    customerDao.save(customer);
    linkManDao.save(linkMan);
}

以下操作会产生一条重复更新的 sql 语句:

@Test
@Transactional  //配置事务
@Rollback(false)  //不自动回滚
public void testAdd() {
    //创建一个客户
    Customer customer = new Customer();
    customer.setCustName("张三");
    customer.setCustAddress("武汉市汉阳区");
    //创建一个联系人
    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("小李");
    linkMan.setLkmPhone("1313131313");
    //配置客户到联系人
    customer.getLinkMans().add(linkMan);
    //配置联系人到客户
    linkMan.setCustomer(customer);

    customerDao.save(customer);
    linkManDao.save(linkMan);
}

客户放弃关联外键可解决该问题:

*** mappedBy 的值为 联系人封装类中定义的 Customer 的成员变量

//@OneToMany(targetEntity = LinkMan.class)
//@JoinColumn(name = "lkm_cust_id", referencedColumnName = "cust_id")
@OneToMany(mappedBy = "customer")   //放弃关联外键维护权  配置此注解
private Set<LinkMan> linkMans = new HashSet();

2. 级联添加: 保存客户的同时, 也保存该客户关联的联系人

* 在客户封装联系人类中的成员属性上修改注解:

(CascadeType.ALL          是级联所有操作)

(CascadeType.MERGE   是级联更新操作)

(CascadeType.PERSIST 是级联保存操作)

(CascadeType.REMOVE 是级联删除操作)

@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
private Set<LinkMan> linkMans = new HashSet();

* 编写级联添加的方法:

@Test
@Transactional  //配置事务
@Rollback(false)  //不自动回滚
public void testCascadeAdd() {
    //创建一个客户
    Customer customer = new Customer();
    customer.setCustName("小张");
    customer.setCustAddress("武汉市汉阳区");
    //创建一个联系人
    LinkMan linkMan = new LinkMan();
    linkMan.setLkmName("小陈");
    linkMan.setLkmPhone("1313131313");
    //配置联系人到客户
    linkMan.setCustomer(customer);
    //配置客户到联系人
    customer.getLinkMans().add(linkMan);
    
    customerDao.save(customer);
}

3. 级联删除: 删除客户的同时, 也删除该客户关联的联系人

* 编写级联删除的方法:

@Test
@Transactional  //配置事务
@Rollback(false)  //不自动回滚
public void testCascadeDelete() {
    //查询到指定 id 客户
    Customer customer = customerDao.findOne(1L);
    //执行删除该 id 客户
    customerDao.delete(customer);
}

 

源代码下载: https://pan.baidu.com/s/1ovQIFOHe3sT4ROFop4BM1A

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值