【Spring Data JPA】09 多表关系 Part2 多对多关系操作
环境搭建:
用户类:
package cn.echo42.domain; import javax.persistence.*; import java.util.HashSet; import java.util.Set; @Entity @Table(name = "sys_user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="user_id") private Long userId; @Column(name="user_name") private String userName; @Column(name="age") private Integer age; /** * 配置用户到角色的多对多关系 * 配置多对多的映射关系 * 1.声明表关系的配置 * @ManyToMany(targetEntity = Role.class) //多对多 * targetEntity:代表对方的实体类字节码 * 2.配置中间表(包含两个外键) * @JoinTable * name : 中间表的名称 * joinColumns:配置当前对象在中间表的外键 * @JoinColumn的数组 * name:外键名 * referencedColumnName:参照的主表的主键名 * inverseJoinColumns:配置对方对象在中间表的外键 */ @ManyToMany(targetEntity = Role.class,cascade = CascadeType.ALL) @JoinTable(name = "sys_user_role", //joinColumns,当前对象在中间表中的外键 joinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")}, //inverseJoinColumns,对方对象在中间表的外键 inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")} ) private Set<Role> roles = new HashSet<>(); public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } }
角色类
package cn.echo42.domain; import javax.persistence.*; import java.util.HashSet; import java.util.Set; @Entity @Table(name = "sys_role") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "role_id") private Long roleId; @Column(name = "role_name") private String roleName; //配置多对多 @ManyToMany(mappedBy = "roles") //配置多表关系 private Set<User> users = new HashSet<>(); public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } }
注意把JPA配置更改为Create否则报错找不到关联表
测试运行:
@Test public void addTest(){ User user = new User(); user.setUserName("用户1"); Role role = new Role(); role.setRoleName("Java全栈工具人"); userRepository.save(user); roleRepository.save(role); }
虽然用户和角色表都插入了角色,
但是我们的关联表什么也没有
则我们需要像一对多关系一样进行双向插入:
@Test public void addTest(){ User user = new User(); user.setUserName("用户1"); Role role = new Role(); role.setRoleName("Java全栈工具人"); user.getRoles().add(role); role.getUsers().add(user); userRepository.save(user); roleRepository.save(role); }
但是执行出错:
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'sys_user_role.PRIMARY'
主键重复,解决办法还是一样,其中一个实体类放弃维护
多对多放弃维护,被动的一方放弃
再次执行则正常执行:
多对多级联操作:
基本一样:
@Test @Transactional @Rollback(false) // 设置不自动回滚 public void addExecute6(){ Specification<User> userSpecification = (Specification<User>) (root, criteriaQuery, criteriaBuilder) -> { // 获取比较的属性 Path<Object> user_id = root.get("userId"); // 模糊要求指定参数类型 return criteriaBuilder.equal(user_id, 1); }; Optional<User> userOptional = userRepository.findOne(userSpecification); User user = userOptional.get(); userRepository.delete(user); }