深入学习 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;
    @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;

    @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 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 list1 = new ArrayList<>();
        list1.add(course);
        list1.add(course2);
        list1.add(course3);

        List 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 list1 = new ArrayList<>();
        list1.add(user);
        list1.add(user2);

        List 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删除对象会将中间表删除。

 

项目地址  [email protected]:Christain1993/jpatest.git

 

你可能感兴趣的:(java)