SpringData - 对多表的操作

一. 创建与数据库对应的封装类

User:

@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)
    @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();


    //getter setter 方法....

    //toString() 方法....

}

Role:

@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(targetEntity = User.class)
    @JoinTable(name = "sys_user_role",    //中间表
            //joinColumns, 当前对象在中间表中的外键
            joinColumns = {@JoinColumn(name = "sys_role_id", referencedColumnName = "role_id")},
            //inverseJoinColumns,对方对象在中间表的外键
            inverseJoinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")}
    )
    private Set<User> users = new HashSet();

    //getter setter 方法....

    //toString() 方法....

}

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

UserDao:

public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

}

RoleDao:

public interface RoleDao extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {

}

三. 编写测试类

编写测试类框架:

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

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;


}

1. 保存一个用户的同时保存该用户所关联的角色

@Test
@Transactional
@Rollback(false)
public void  testAdd() {
    //创建一个用户
    User user = new User();
    user.setUserName("小李");
    user.setAge(18);
    //用户关联的角色
    Role role = new Role();
    role.setRoleName("java程序员");
    //配置用户到角色关系,可以对中间表中的数据进行维护
    user.getRoles().add(role);
    //配置角色到用户的关系,可以对中间表的数据进行维护
    role.getUsers().add(user);

    userDao.save(user);
    roleDao.save(role);
}

运行时, 会对中间表进行两次处理, 导致抛出异常, 在此需要放弃维权处理: 被动的一方(角色)放弃.

修改 Role 封装类:

*** mappedBy 的值为 User 封装类中定义的 Role 的成员变量

@ManyToMany(mappedBy = "roles")      //配置多表关系
private Set<User> users = new HashSet();

2. 级联添加(添加用户的同时添加用户对应的角色)

修改 User 封装类:

* 在 User 封装类中的成员属性上修改注解:

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

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

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

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

@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")}
)

定义级联添加的方法:

@Test
@Transactional
@Rollback(false)
public void  testCasCadeAdd() {
    //创建一个用户
    User user = new User();
    user.setUserName("小王");
    user.setAge(28);
    //用户关联的角色
    Role role = new Role();
    role.setRoleName("产品经理");
    //配置用户到角色关系,可以对中间表中的数据进行维护
    user.getRoles().add(role);
    //配置角色到用户的关系,可以对中间表的数据进行维护
    role.getUsers().add(user);

    userDao.save(user);
}

定义级联删除的方法:

@Test
@Transactional
@Rollback(false)
public void  testCasCadeRemove() {
    //查询1号用户
    User user = userDao.findOne(1L);
    //删除1号用户
    userDao.delete(user);
}

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

猜你喜欢

转载自blog.csdn.net/weixin_42629433/article/details/84784713
今日推荐