JPA--SpringDataJPA多对多关联、级联操作

注解说明

  • @OneToMany:
    作用:建立一对多的关系映射
    属性:
    targetEntityClass:指定多的多方的类的字节码
    mappedBy:指定从表实体类中引用主表对象的名称。
    cascade:指定要使用的级联操作
    fetch:指定是否采用延迟加载
    orphanRemoval:是否使用孤儿删除

  • @ManyToOne
    作用:建立多对一的关系
    属性:
    targetEntityClass:指定一的一方实体类字节码
    cascade:指定要使用的级联操作
    fetch:指定是否采用延迟加载
    optional:关联是否可选。如果设置为false,则必须始终存在非空关系。

  • @JoinColumn
    作用:用于定义主键字段和外键字段的对应关系。
    属性:
    name:指定外键字段的名称
    referencedColumnName:指定引用主表的主键字段名称
    unique:是否唯一。默认值不唯一
    nullable:是否允许为空。默认值允许。
    insertable:是否允许插入。默认值允许。
    updatable:是否允许更新。默认值允许。
    columnDefinition:列的定义信息。

实体类

package pers.zhang.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author zhang
 * @date 2019/12/17 - 22:32
 */
@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;

    public Long getUserId() {
        return userId;
    }


    /*
        配置用户到角色的多对多关系
            1. 声明表关系
                @ManyToMany(targetEntity = Role.class)
                       targetEntity:对方实体类的字节码
            2. 配置中间表(包含两个外键)
                JoinTable
                    name:中间表名
                    joinColumns:当前表在中间表中的外键
                    inverseJoinColumns:对方表在中间表的外键


     */
    @ManyToMany(targetEntity = Role.class, cascade = CascadeType.ALL)
    @JoinTable(name = "sys_user_role",
                joinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")},
                inverseJoinColumns = {@JoinColumn(name = "sys_role_id", referencedColumnName = "role_id")})
    private Set<Role> roles = new HashSet<>();

    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    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;
    }
}
package pers.zhang.entity;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author zhang
 * @date 2019/12/17 - 22:32
 */
@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 = {@JoinColumn(name = "sys_role_id", referencedColumnName = "user_id")},
//            inverseJoinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "role_id")})
    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<>();


    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }

    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;
    }
}

Dao接口

package pers.zhang.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import pers.zhang.entity.Role;

/**
 * @author zhang
 * @date 2019/12/17 - 22:37
 */
public interface RoleDao extends JpaRepository<Role, Long>, JpaSpecificationExecutor<Role> {
}
package pers.zhang.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import pers.zhang.entity.User;

/**
 * @author zhang
 * @date 2019/12/17 - 22:37
 */
public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}

测试类

package pers.zhang;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import pers.zhang.dao.RoleDao;
import pers.zhang.dao.UserDao;
import pers.zhang.entity.Role;
import pers.zhang.entity.User;

/**
 * @author zhang
 * @date 2019/12/17 - 23:04
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Many2ManyTest {

    @Autowired
    UserDao userDao;

    @Autowired
    RoleDao roleDao;


    /*
        保存一个用户,保存一个角色
            多对多放弃维护权:谁被选择谁放弃维护权
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testAdd(){
        User user = new User();
        user.setUserName("小李");

        Role role = new Role();
        role.setRoleName("Java程序员");

        //User方维护多对多关系
        user.getRoles().add(role);

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

        /*
            Hibernate: insert into sys_user (age, user_name) values (?, ?)
            Hibernate: insert into sys_role (role_name) values (?)
            Hibernate: insert into sys_user_role (sys_user_id, sys_role_id) values (?, ?)
         */
    }

    /*
        级联操作:保存一个用户的同时保存用户关联的角色
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testCascadeAdd(){
        User user = new User();
        user.setUserName("小王");

        Role role = new Role();
        role.setRoleName("C#程序员");

        //User方维护多对多关系
        user.getRoles().add(role);

        userDao.save(user);

        /*
            Hibernate: insert into sys_user (age, user_name) values (?, ?)
            Hibernate: insert into sys_role (role_name) values (?)
            Hibernate: insert into sys_user_role (sys_user_id, sys_role_id) values (?, ?)
         */
    }

    /*
        级联删除:删除一个用户同时删除关联的角色
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testCascaseDelete(){
        User user = userDao.findOne(1L);
        userDao.delete(user);

        /*
            Hibernate: select user0_.user_id as user_id1_3_0_, user0_.age as age2_3_0_, user0_.user_name as user_nam3_3_0_ from sys_user user0_ where user0_.user_id=?
            Hibernate: select roles0_.sys_user_id as sys_user1_4_0_, roles0_.sys_role_id as sys_role2_4_0_, role1_.role_id as role_id1_2_1_, role1_.role_name as role_nam2_2_1_ from sys_user_role roles0_ inner join sys_role role1_ on roles0_.sys_role_id=role1_.role_id where roles0_.sys_user_id=?
            Hibernate: delete from sys_user_role where sys_user_id=?
            Hibernate: delete from sys_role where role_id=?
            Hibernate: delete from sys_user where user_id=?
         */
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值