1. 程式人生 > >JPA(二):實體對映關係

JPA(二):實體對映關係

1.單向一對一對映

1.1.資料庫

CREATE TABLE `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `password` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `article` (
    `articleId` int(11) NOT NULL AUTO_INCREMENT,
    `articleName` varchar(255) DEFAULT NULL,
    `articleContent` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`articleId`)
   ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

1.2.實體類

新增文章類和使用者類

Article類

@Entity
@Table(name = "article")
public class Article  {

    @Id
    @GeneratedValue
    @Column(name = "articleId")
    private int article;
    @Column
    private String articleName;
    @Column
    private String articleContent;

     //省略getter和setter
}

User類

@Entity
//指定表名,指定唯一約束
@Table(name = "user",uniqueConstraints = {@UniqueConstraint(columnNames = {"id","name"})})
public class User {
    @Id//指定主鍵
    @GeneratedValue
    private int id;
    @Column
    private String name;
    @Column
    private String password;

    //一對一對映
    @OneToOne(optional = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "articleId", unique = true)
    public Article article;
   
//省略getter和setter
}

@JoinColumn(name = "articleId", unique = true),articleId是所對應的外來鍵。

1.3.測試

@Test
    public void testOneToOneRelevance(){
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        User user  = new User();
        user.setName("hz");
        Article article = new Article();
        article.setAricleName("yx");
        user.setArticle(article);
        em.persist(user);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();
    }

2.雙向一對多關係中間表方式實現

2.1.資料庫

CREATE TABLE `author` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `authorName` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `book` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `bookName` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `public` (
    `authorId` int(11) NOT NULL ,
    `bookId` int(11) NOT NULL,
   PRIMARY KEY (`authorId`,`bookId`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.2.實體類

實體類有作者,書籍,和作者所對應的出版的書籍

作者類

@Entity
public class Author {
    @Id
    @GeneratedValue
    private int id;
    private String authorName;

    /**
     * Author和Book是一對多關係
     */
    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    //name:public中間表一方的外來鍵名稱
    //referencedColumnName:public表的authorId外來鍵參考了Author表的id主鍵
    @JoinTable(name = "public",joinColumns = {@JoinColumn(name = "authorId",referencedColumnName = "id")},
    //指定中間表多方外來鍵
    //name:中間表多方外來鍵的名稱為bookId
    //referencedColumnName:bookId參考了book表的id主鍵
    inverseJoinColumns = {@JoinColumn(name = "bookId",referencedColumnName = "id")})
    private Collection<Book> books;

}

書籍類

@Entity
public class Book {

    @Id
    @GeneratedValue
    private int id;
    private String bookName;

}

出版類

public class Publish {

    private int authorId;
    private int bookId;

}

2.3.測試方法

/**
     * 雙向一對多關係OneToMany中間表方式實現
     */
    @Test
    public void testOneToManyRelevance(){
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        Author author = new Author();
        author.setAuthorName("hly");
        Book book1 = new Book();
        Book book2 = new Book();
        book1.setBookName("Java");
        book2.setBookName("Linux");
        Collection<Book> collection = new ArrayList<>();
        collection.add(book1);
        collection.add(book2);
        author.setBooks(collection);
        em.persist(author);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();
    }

3.雙向一對多關係外來鍵關聯方式實現

3.1.資料庫

BOSS表和員工表

CREATE TABLE `boss` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `employee` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.2.實體類

BOSS類

@Entity
public class Boss {

    @Id
    @GeneratedValue
    //取消自增
    private int id;
    private String name;
    //mappedBy:Boss類為多方關係維護方,負責資料庫外來鍵boss_id的更新
    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = "boss")
    private Collection<Employee> employees;
 
}

mappedBy = "boss"對應員工類中的private Boss boss;

員工類

@Entity
public class Employee {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinColumn(name = "boss_id")
    private Boss boss;

}

3.3.測試方法

@Test
    public void testOneToManyForeignKeyLink(){

        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        Boss boss = new Boss();
        boss.setName("hly");
        Employee employee1 = new Employee();
        Employee employee2 = new Employee();
        employee1.setName("aff");
        employee2.setName("gbd");
        Collection<Employee> collection = new ArrayList<>();
        collection.add(employee1);
        collection.add(employee2);
        boss.setEmployees(collection);
        em.persist(boss);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();
    }

4.單向多對一關係

4.1.資料庫

People表和Car表

CREATE TABLE `people` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `car` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.2.實體類

People類

@Entity
public class People {

    @Id
    @GeneratedValue
    private int id;
    private String name;

}

Car類

@Entity
public class Car {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    @ManyToOne(cascade = CascadeType.ALL)
    private People people;
}

這裡沒有用註解宣告外來鍵,自動生成的外來鍵格式為people_id

4.3.測試方法

/**
     * 單向多對一關係ManyToOne
     */
    @Test
    public  void testManyToOneRelevance(){
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        Car car1 = new Car();
        Car car2 = new Car();
        People people  = new People();
        car1.setName("Porsche");
        car2.setName("Ferrari");
        people.setName("hly");
        car1.setPeople(people);
        car2.setPeople(people);
        em.persist(car1);
        em.persist(car2);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();
    }

5.單向多對多關係

從多方A可以獲得另外的多方B;從B不需要獲得A

5.1.資料庫

學生,課程,選課表

CREATE TABLE `student` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `studentName` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `course` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `courseName` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `selectcourse` (
    `studentId` int(11) NOT NULL,
    `courseId` int(11) NOT NULL,
   PRIMARY KEY (`studentId`,`courseId`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.2.實體類

Couse類

@Entity
public class Course {

    @Id
    @GeneratedValue
    private int id;
    private String courseName;
}
Student類
@Entity
public class Student {

    @Id
    @GeneratedValue
    private int id;
    private String studentName;

    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(name = "selectCourse",joinColumns = {@JoinColumn(name = "studentId",referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "courseId",referencedColumnName = "id")})
    private Collection<Course> courses;
}

選課類

public class SelectCourse {
    
    private int studentId;
    private int courseId;
}

5.3.測試方法

/**
     * 單向多對多關係ManyToMany
     */
    @Test
    public void manyToManyOfSingleTrack(){
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        Student student = new Student();
        student.setName("hly");
        Course course1 = new Course();
        Course course2 = new Course();
        course1.setName("Java");
        course2.setName("資料庫");
        Collection<Course> courses = new ArrayList<>();
        courses.add(course1);
        courses.add(course2);
        student.setCourses(courses);
        em.persist(student);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();
    }

6.雙向雙向多對多關係

6.1.資料庫

CREATE TABLE `classes` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `teacher` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
   PRIMARY KEY (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `teaching` (
    `teacherId` int(11) NOT NULL,
    `classesId` int(11) NOT NULL,
   PRIMARY KEY (`teacherId`,`classesId`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

6.2.實體類

教師,班級,教師班級關係類

Teacher類

@Entity
public class Teacher {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    
    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(name = "teaching",joinColumns = {@JoinColumn(name = "teacherId",referencedColumnName = "id")},
            inverseJoinColumns ={@JoinColumn(name = "classesId",referencedColumnName = "id")} )
    private Collection<Classes> classes = new ArrayList<Classes>();

}

Classes類

@Entity
public class Classes {

    @Id
    @GeneratedValue
    private int id ;
    private String name;

    //mapperBy為Teacher的Classes屬性
    @ManyToMany(mappedBy = "classes",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    private Collection<Teacher> teachers = new ArrayList<Teacher>();
}

Teaching類

public class Teaching {

    //命名不是teacher_id格式需要在teacher類中@JoinTable裡宣告
    private int classId;
    private int teacherId;
}

6.3.測試方法

/**
     * 雙向多對多ManyToMany
     */
    @Test
    public void manyToManyOfDuple(){
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("MyJPA");
        EntityManager em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        Teacher teacher1 = new Teacher();
        Teacher teacher2 = new Teacher();
        Classes classes1 = new Classes();
        Classes classes2 = new Classes();
        teacher1.setName("aaa");
        teacher2.setName("bbb");
        classes1.setName("161");
        classes2.setName("162");
        Collection<Teacher> teachers = new ArrayList<>();
        Collection<Classes> classes = new ArrayList<>();
        teachers.add(teacher1);
        teachers.add(teacher2);
        classes.add(classes1);
        classes.add(classes2);
        teacher1.setClasses(classes);
        classes2.setTeachers(teachers);
        em.persist(teacher1);
        em.persist(classes2);
        em.getTransaction().commit();
        em.close();
        entityManagerFactory.close();

    }

對映關係思維導圖

程式碼及地址思維導圖

完整程式碼在筆者的github,歡迎訪問。

清晰思維導圖分享地址為:JPA思維導圖