一、一对一关系

拥有端:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    /**
     * 关系的拥有端存储一个被控端的一个外键。
     * 在这个例子中 Person表 中的 address_id 就是指向 address表 的一个外键,
     * 缺省情况下这个外键的字段名称,是以它指向的表的名称加下划线“_”加“id”组成的。
     * 当然我们也可以根据我们的喜好来修改这个字段,修改的办法就是使用 @JoinColumn 这个注解。
     * 在这个例子中我们可以将这个注解标注在 Person 类中的 Address 属性上去。
     */
    @Id
    private Long id;
    private String firstName;
    private String lastName;
    @OneToOne
    private Address address;
}

被控端:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
    /**
     * mappedBy = (Optional) The field that owns the relationship,即指向拥有端的(变量名).
     */
    @Id
    private Long id;
    private String state;
    private String city;
    private String street;
    private String zipCode;
    @OneToOne(mappedBy = "address")
    private Person person;
}

表结构:

自关联中@ManyToOne、@OneToMany的使用

二、一对多关系

拥有端:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Comment {
    /**
     * 一对多关系中,一般都是选择“多”这端作为拥有端,因为可以很方便把“一”这端作为一个属性包含进来。
     */
    @Id
    private Integer id;
    private Integer year;
    private boolean approved;
    private String content;
    @ManyToOne
    private Post post;
}

被控端:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Post {
    /**
     * 一对多的被控端,往往是“一”这端,需要以List的方式将“多”端添加进来
     */
    @Id
    private Integer id;
    private String title;
    private String content;
    @OneToMany(mappedBy = "post")
    private List<Comment> comments;
}

表结构:

自关联中@ManyToOne、@OneToMany的使用

三、自关联

事实上,在国内互联网领域很少使用外键,database也不会交给ORM管理,table结构会保持一定程度的字段冗余。个人不太习惯用JPA管理映射关系,思维和经验都没有转变过来,但是在多级分类的表结构(省市区表、商品分类表)当中,往往是以自关联的方式组织树形结构数据的,不需要建立外键也可以发挥JPA的优势。

@Entity
@Table
@Data
public class Area {
    @Id
    @GeneratedValue
    private Long id;

    // 区域名
    private String name;

    // 父区域
    @ManyToOne(fetch = FetchType.LAZY)  // 相当于把2个Area写在一处;
    @JsonIgnore                         // 忽略父类属性JSON序列化;
    private Area parent;

    // 子区域,一个区域信息可以有多级子区域,比如 : 广东省 - 广州市 - 天河区
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    private List<Area> children;
}

Repository接口:

public interface AreaRepository extends JpaRepository<Area, Long> {}

利用测试方法把数据写入数据库:

    @Autowired
    private AreaRepository areaRepository;
    
    @Test
    public void addArea() {

        // 广东省 (顶级区域)
        Area guangdong = new Area();
        guangdong.setName("广东省");
        areaRepository.save(guangdong);

        //广东省 下面的 广州市(二级区域)
        Area guangzhou = new Area();
        guangzhou.setName("广州市");
        guangzhou.setParent(guangdong);
        areaRepository.save(guangzhou);

        //广州市 下面的 天河区(三级区域)
        Area tianhe = new Area();
        tianhe.setName("天河区");
        tianhe.setParent(guangzhou);
        areaRepository.save(tianhe);

        //广东省 下面的 湛江市(二级区域)
        Area zhanjiang = new Area();
        zhanjiang.setName("湛江市");
        zhanjiang.setParent(guangdong);
        areaRepository.save(zhanjiang);

        //湛江市 下面的 霞山区(三级区域)
        Area xiashan = new Area();
        xiashan.setName("霞山区");
        xiashan.setParent(zhanjiang);
        areaRepository.save(xiashan);
    }

最后我们可以得到如下的表结构:

id     name        parent_id
1    广东省         null
2    广州市         1
3    天河区         2
4    湛江市         1
5    霞山区         4

添加一个最简单的RESTful接口,主要是实现JSON序列化查看结果,

@RestController
public class OutputController {
    @Autowired
    private AreaRepository areaRepository;

    @GetMapping("area")
    public Area getArea() {
        List<Area> areas = areaRepository.findAll();
        return areas.get(0);
    }

    @GetMapping("areas")
    public List<Area> getAreas() {
        return areaRepository.findAll();
    }
}

返回结果:

// 20200611004952
// http://localhost:8080/area

{
  "id": 1,
  "name": "广东省",
  "children": [
    {
      "id": 2,
      "name": "广州市",
      "children": [
        {
          "id": 3,
          "name": "天河区",
          "children": [
            
          ]
        }
      ]
    },
    {
      "id": 4,
      "name": "湛江市",
      "children": [
        {
          "id": 5,
          "name": "霞山区",
          "children": [
            
          ]
        }
      ]
    }
  ]
}
View Code

相关文章:

  • 2022-12-23
  • 2021-11-21
  • 2022-12-23
  • 2022-12-23
  • 2022-01-04
  • 2022-12-23
  • 2021-07-20
猜你喜欢
  • 2021-08-06
  • 2021-12-24
  • 2022-12-23
  • 2021-09-19
  • 2022-12-23
  • 2018-04-16
  • 2021-12-06
相关资源
相似解决方案