十五、Spring Data JPA 属性表关联映射

本文详细介绍了使用SpringDataJPA进行多对一和多对多关联映射的配置及测试。在多对一关系中,一个用户对应一个角色,反之一个角色可以对应多个用户;在多对多关系中,一个用户可以对应多个菜单,反之一个菜单也可以对应多个用户。文中给出了实体类的映射关系设置,以及相关的测试用例,展示了如何保存和查询这些关联关系。
摘要由CSDN通过智能技术生成

(一)、多对一

示例:一个用户(User)只能有一个角色(Role),一个角色(Role)可以对应多个用户(User),User 表通过role_id和 Role 表的id相关联。

1.映射关系创建

  • @ManyToOne:表对应关系;
    mapperBy:在关联表中的映射;
  • @JoinColumn:当前表与其它表关联的外键;
    name:外键名称。

注:

  • 重写toString方法不要造成死循环;
  • 项目配置文件中添加配置,开启懒加载

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

User...
	
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

 
    /**
     * @ManyToOne:多对一
     * @JoinColumn:与其它表关联的外键
     */
    @ManyToOne
    @JoinColumn(name = "role_id")
    private Role role;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", role=" + role.getRole_name() +
                '}';
    }

   ...
}

Role...
	
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    /**
     *  @OneToMany:一对多
     *      mapperBy:关联User表外键
     */
    @OneToMany(mappedBy = "role")
    private Set<User> users = new HashSet<>();


    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", role_name='" + role_name + '\'' +
                '}';
    }
    
    ...
}

2.测试

 ...

    @Autowired
    private UserRepository userRepository;

	@Test
    void testOneToMany(){

        List<Role> roles = new ArrayList<>();
        Role role = new Role();
        role.setRole_name("管理员");
        roles.add(role);
        Role role1 = new Role();
        role1.setRole_name("VIP会员");
        roles.add(role1);
        Role role2 = new Role();
        role2.setRole_name("会员");
        roles.add(role2);

        System.out.println("一对多:");
        List<User> users = userRepository.findAll();
        for (User user : users) {
            System.out.println(user.toString());
            int i = user.getId() % 2 == 0 ? 1 : (user.getId() % 3 == 0 ? 2 : 0);
            user.setRole(roles.get(i));
            userRepository.save(user);
        }

        System.out.println("一对多更新:");
        List<User> users2 = userRepository.findAll();
        for (User user : users2) {
            System.out.println(user);
        }
    }
    
	...

(二)、多对多

示列:*一个User对应可能对应多个Menu,一个Menu也可能对应多个User,两个表都通过id相关联。

1.表关系创建

  • @ManyToMany(表间关系)
    cascade(级联操作)详情见:资料1资料2
         CascadeType.ALL:级联所有实体状态转换;
         CascadeType.PERSIST:持久化,级联保存;
         CascadeType.MERGE:级联实体合并操作;
         CascadeType.REMOVE:级联实体删除操作;
         CascadeType.REFRESH:级联实体刷新操作;
         CascadeType.DETACH:级联实体分离操作;
    mapperBy:映射字段(关联表字段);
  • @JoinTable(中间表
    name:中间表名称(名称任意);
    joinColumns(当前表中间表关联字段信息)
         name:中间表与当前表关联的字段(任意定义);
         referencedColumnName:当前表与中间表关联的字段(当前表中的字段
    inverseJoinColumns:关联表与中间表关联字段信息。
Role...
	
    @ManyToMany(cascade = CascadeType.ALL)
    /**
     * @JoinTable:中间表
     *  name:中间表名称(随便定义)
     *  joinColumns:当前表中主键所关联的中间表中的外键字段
     *      name:中间表与当前表关联的字段(任意定义)
     *      referencedColumnName:当前表与中间表关联的字段(当前表中的字段)
     *  inverseJoinColumns:关联表与当前表关联的字段(任意定义)
     */
    @JoinTable(name = "role_menu",
            joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")})
    private Set<Menu> menus = new HashSet<>();
	
	...
表 menu:
	
	...
	
    @ManyToMany(mappedBy = "menus")
    private Set<Role> roles = new HashSet<>();

    @Override
    public String toString() {
        return "Menu{" +
                "id=" + id +
                ", Work='" + Work +
                '}';
    }

	...

2.测试

	
	...

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Test
    void testManyToMany() {
        Menu menu0 = new Menu();
        menu0.setWork("学习" );
        Menu menu1 = new Menu();
        menu1.setWork("看书");
        Menu menu2 = new Menu();
        menu2.setWork("打游戏");

        System.out.println("多对多查询 Role:");
        List<Role> roles = roleRepository.findAll();
        for (Role role : roles) {
            System.out.println(role.toString());
            Set<Menu> menus = new HashSet<Menu>();
            menus.add( role.getId() % 2 == 0 ? menu0 : (role.getId() % 3 == 0 ? menu1 : menu2));
            role.setMenus(menus);
            roleRepository.save(role);
        }
        System.out.println("多多多查询 Role:");
        List<Role> roles = roleRepository.findAll();
        for (Role role : roles) {
            System.out.println(role);
        }
        System.out.println("多对多查询 Menu:");
        List<Menu> menus = menuRepository.findAll();
        for (Menu menu : menus) {
            System.out.println(menu);
        }
    }
    
    ...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值