深入学习 java jpa (一)实体关系

jpa是完全体对象关系映射的接口规范,

其中实体关系分为

@OneToOne, @OneToMany, @ManyToOne, @ManyToMany等

下面的user实体,使用到了以上的各注解,分别维护了各种关系,构建好实体对象后,直接使用entitymanager进行各种操作即可。

@Entity
@Table(name = "user")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Integer age;

    // user和document是一对一的关系, 在user中维护, document不维护
    @OneToOne(cascade = CascadeType.ALL) // 级联所有, 对user实体的任何操作都会级联到document数据
    @JoinColumn(name = "user_document_id") // 表示在user表中的字段名称
    private UserDocument userDocument;
    @ManyToMany(cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "r_user_cource",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private List<Cource> cource;
    @ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH})
    @JoinColumn(name = "school_id")
    private School school;
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private List<Phone> phone;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", userDocument=" + userDocument +
//                ", cource=" + cource +
                ", school=" + school +
                ", phone=" + phone +
                '}';
    }
}

这里重点介绍下manytomany的测试例子;

与user是多对多关系的是Course实体,


@Data
@Entity
@Table(name = "course")
public class Cource {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    // 课程名称
    private String name;
    // 多少学时
    private Integer num;

    // 实体映射关系
    @ManyToMany(cascade = CascadeType.PERSIST)// 级联级别
    @JoinTable(
            name = "r_user_cource", // 关联中间表
            joinColumns = @JoinColumn(name = "course_id"), // 关联字段
            inverseJoinColumns = @JoinColumn(name = "user_id") // 级联字段
    )
    private List<User> users;

    @Override
    public String toString() {
        return "Cource{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", num=" + num +
//                ", users=" + users +
                '}';
    }
}

可以看到双方都维护了@ManyToMany 引用约束,此时通过两边的实体都可与进行级联操作,

测试类

这些测试方法,给出了增删该查的实例操作;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ManyToManyTest {
    @Autowired
    private EntityManager entityManager;

    @Test
    @Transactional
    @Rollback(false)
    public void contextLoads() {
        User user = new User();
        user.setName("李明");
        user.setAge(11);

        User user2 = new User();
        user2.setName("王华");
        user2.setAge(14);

        Cource course = new Cource();
        course.setName("数学");
        course.setNum(64);
        Cource course2 = new Cource();
        course2.setName("语文");
        course2.setNum(64);
        Cource course3 = new Cource();
        course3.setName("英语");
        course3.setNum(64);

        List<Cource> list1 = new ArrayList<>();
        list1.add(course);
        list1.add(course2);
        list1.add(course3);

        List<Cource> list2 = new ArrayList<>();
        list2.add(course);
        list2.add(course2);

        user.setCource(list1);
        user2.setCource(list2);

        entityManager.persist(user);
        entityManager.persist(user2);
    }


    @Test
    @Transactional
    @Rollback(false)
    public void save() {
        User user = new User();
        user.setName("李明");
        user.setAge(11);

        User user2 = new User();
        user2.setName("王华");
        user2.setAge(14);

        Cource course = new Cource();
        course.setName("数学");
        course.setNum(64);
        Cource course2 = new Cource();
        course2.setName("语文");
        course2.setNum(64);
        Cource course3 = new Cource();
        course3.setName("英语");
        course3.setNum(64);

        List<User> list1 = new ArrayList<>();
        list1.add(user);
        list1.add(user2);

        List<User> list2 = new ArrayList<>();
        list2.add(user);

        course.setUsers(list1);
        course2.setUsers(list2);
        course3.setUsers(list1);

        entityManager.persist(course);
        entityManager.persist(course2);
        entityManager.persist(course3);
    }


    @Test
    @Transactional
    @Rollback(false)
    public void update(){
        User user = entityManager.find(User.class,9L);
        user.getSchool().setName("haha");
        entityManager.merge(user);

    }

    @Test
    @Transactional
    @Rollback(false)
    public void findcource(){
        Cource cource = entityManager.find(Cource.class, 25L);
        System.out.println(cource);
    }

    @Test
    @Transactional
    @Rollback(false)
    public void delete(){
        User user = entityManager.find(User.class,15L);
        entityManager.remove(user);
    }
}

需要注意的是,在多对多关系中, 如果设置了cascade = CascadeType.ALL 或者包含 CascadeType.REMOVE  则在级联删除时,除了删除中间表,还会删除多对多关系中对应的另一方的实体表的数据,一般情况下这是不符合业务逻辑的。其实多对多关系中,不要设置级联删除即可,这是通过entitymanger删除对象会将中间表删除。

 

项目地址  git@github.com:Christain1993/jpatest.git

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值