• JPA级联查询


    客户 :指一家公司,可以有多个联系人  与联系人是一对多关系
    联系人: 只属于一家公司 与客户是多对一关系
     
    客户表
    public class Customer {
    
    /**
    * @Id:声明主键的配置
    * @GeneratedValue:配置主键的生成策略
    * strategy
    * GenerationType.IDENTITY :自增,mysql
    * * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
    * GenerationType.SEQUENCE : 序列,oracle
    * * 底层数据库必须支持序列
    * GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
    * GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略
    * @Column:配置属性和字段的映射关系
    * name:数据库表中字段的名称
    */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cust_id")
    private Long custId; //客户的主键
    
    @Column(name = "cust_name")
    private String custName;//客户名称
    
    @Column(name="cust_source")
    private String custSource;//客户来源
    
    @Column(name="cust_level")
    private String custLevel;//客户级别
    
    @Column(name="cust_industry")
    private String custIndustry;//客户所属行业
    
    @Column(name="cust_phone")
    private String custPhone;//客户的联系方式
    
    @Column(name="cust_address")
    private String custAddress;//客户地址
    
    /**
    * 配置一对多关系
    * 使用注解方式
    * 1.声明关系 @OneToMany 表示一对多关系
    * 2. 配置外键(中间表)
    * @JoinColumn: 配置外键
    * name: 外键字段名称
    * referencedColumnName:参照主表的主键字段名称
    * 在客户实体类上 添加了外键配置,所以对于客户而言,也具备了维护外键的作用
    */
    @OneToMany(targetEntity = LinkMan.class)
    @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
    private Set<LinkMan> linkMans = new HashSet<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)
    @JoinColumn(name = "lkm_cust_id",referencedColumnName = "cust_id")
    private Customer customer;

    测试代码

      @Test
        @Transactional
        @Rollback(false)
        public  void testAff(){
            //创建一个客户
            Customer customer = new Customer();
            customer.setCustName("百度");
    
            LinkMan linkMan = new LinkMan();
            linkMan.setLkmName("小李");
            /*LinkMan linkMan2 = new LinkMan();
            linkMan.setLkmName("小李2");*/
            customer.getLinkMans().add(linkMan);
            customerDao.save(customer);
            linkManDao.save(linkMan);
    
        }

    运行之后可以在表中看到link _man 表中lkm_cust_id 会有外键

     说明实体之间已经建立联系,也就是外键维护

    如果没有这一行

    customer.getLinkMans().add(linkMan);

    是不会生成外键

    实际上看控制台会知道 执行了两条insert语句 以及一条update 更新外键的语句

     这里是通过客户维护到联系人 同样联系人也可以维护到客户 却只有两条insert语句

        @Test
        @Transactional
        @Rollback(false)
        public  void testAff01(){
            //创建一个客户
            Customer customer = new Customer();
            customer.setCustName("百度");
    
            LinkMan linkMan = new LinkMan();
            linkMan.setLkmName("小李");
    
            linkMan.setCustomer(customer);
            customerDao.save(customer);
            linkManDao.save(linkMan);
    
        }

     同样都能到达效果,但 多对一中 一的一方会维护外键 多了update语句 

     所以一般情况下 会放弃一的一方放弃维护权

     题外:实体上我用的@Data 但是测试时会报错,就换成了@Setter @Getter ???

     删除主表数据

          1. 默认情况下从表数据会把外键设置为null,然后删除主表数据,如果有非空约束,则报错

           2.  如果放弃了维护关联关系,则不能删除(于外键是否为空,没有关系),因为在删除时根本不会去更新从表的外键字段

           3. 如果非要删除,使用级联删除引用

     级联 :

              操作一个对象的同时操作他的关联对象

              1.需要区分操作的主体

              2.需要在主体上添加级联属性(注解)  -------cascade

     

    @Test
        @Transactional
        @Rollback(false)
        public  void testAff02(){
            //创建一个客户
            Customer customer = new Customer();
            customer.setCustName("百度");
    
            LinkMan linkMan = new LinkMan();
            linkMan.setLkmName("小李");
    
            linkMan.setCustomer(customer);
            customer.getLinkMans().add(linkMan);
    
            customerDao.save(customer);
    
        }

    去掉了

    linkManDao.save(linkMan);

    删除

    cascada  

    CascadeType {
    all 所以
    MERGE 更新
    persist 保存
    remove 删除
    }

    需要之前的create 改为 update

    @Test
        @Transactional
        @Rollback(false)
        public  void testAff03(){
    
            Customer customer = customerDao.getOne((long) 1);
    
            customerDao.delete(customer);
    
    
        }

  • 相关阅读:
    codevs1044 拦截导弹(最长不下降子序列dp)
    codevs1014 装箱问题(DP)
    codevs1068 乌龟棋(DP)
    angular.extend vs angular.copy
    angular input框点击别处 变成不可输入状态
    angular select框 option空行
    angular ui 路由传参
    setTimeout 传参
    设置请求头信息的不同方式
    vertical-align
  • 原文地址:https://www.cnblogs.com/yangbom/p/14032419.html
Copyright © 2020-2023  润新知