Hibernate基於註解annotation的配置

Annotation在框架中是愈來愈受歡迎了,由於annotation的配置比起XML的配置來講方便了不少,不須要大量的XML來書寫,方便簡單了不少,只要幾個annotation的配置,就能夠完成咱們之前須要書寫的大量的XML文件。固然annotation的配置也有缺陷的,那就是annotation通常都是配置在代碼中的,若是要修改的話,須要動源代碼,喪失了靈活性,違背了OCP(增長開放,修改關閉)原則,可是在真實的項目開發中,咱們只是動配置文件,而不修改源代碼的狀況實在是太少見了,因此如今annotation已經被普遍的運用到了編程中,各類框架都提供了基於annotation的配置。php

hibernate的註解配置和Jpa中的註解使用基本上都差很少。html

參考博客:java

https://blog.csdn.net/ervinbao/article/details/52861000mysql

http://www.javashuo.com/article/p-ztckvqle-kb.htmlsql

http://www.ilt.me/dmfx/89.html數據庫

 

導入jar包:編程

還有mysql的驅動session

----------------------app

簡單的插入測試小案例:框架

實體:User

package org.model;

import java.util.Date;

import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator;

@Entity
// @Table(name="t_user")//表名 默認不寫的話 就是類名
public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private Date bornDate;

    public User() {
    }

    public User(int id, String username, String password, String nickname, Date bornDate) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.bornDate = bornDate;
    }

    public User(String username, String password, String nickname, Date bornDate) {
        super();
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.bornDate = bornDate;
    }

    @Id
    @GeneratedValue()//默認native @GeneratedValue()
    //@GeneratedValue(generator = "x") //  使用uuid id的類型必須是String類型
    //@GenericGenerator(name = "x", strategy = "uuid") // 使用hibernate的uuid策略
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 5, nullable = false)
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Column(length = 10, nullable = false)//nullable屬性:默認是true  容許空值
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Column(length = 5, nullable = true)
    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    @Column(name = "born_date")
    public Date getBornDate() {
        return bornDate;
    }

    public void setBornDate(Date bornDate) {
        this.bornDate = bornDate;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
                + ", bornDate=" + bornDate + "]";
    }

}

測試類:

package org.execute;

import java.util.Date;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.junit.Test;
import org.model.User;

public class Exe {
    static Configuration config = null;
    static SessionFactory sessionFactory = null;

    // 初始化
    static {
        // 加載核心配置文件 默認加載類路徑下的hibernate.cfg.xml
        config = new Configuration();
        config.configure();
        // 建立工廠
        sessionFactory = config.buildSessionFactory();
    }

    // 返回session
    public Session rtn() {
        return sessionFactory.openSession();
    }

    // 保存測試
    @Test
    public void insert() {
        Session session = rtn();
        session.getTransaction().begin();
        User u = new User("laomu", "123", "老孫", new Date());
        session.save(u);
        session.getTransaction().commit();
    }

}

咱們發如今對實體進行註解配置的時候  導入的包和JPA配置時同樣

在測試類中進行插入時,使用的不是JPA中的EntityManager對象,

EntityManagerFactory factory=Persistence.createEntityManagerFactory("simple");
EntityManager em = factory.createEntityManager();

而仍是hibernate中的session對象。

配置文件:類路徑下的hibernate.cfg.xml文件  默認會去找該文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

    <session-factory>
        <property name="dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <property name="hibernate.hbm2ddl.auto">update</property>
            <!--控制檯打印sql語句-->
        <property name="connection.url">
            jdbc:mysql://localhost:3308/annotationhibernate
        </property>
        <property name="connection.username">root</property>
        <property name="connection.password">jay571018</property>
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
    
        <property name="show_sql">true</property>
        <!--     
        <mapping resource="org/model/Course.hbm.xml" />
        <mapping resource="org/model/Student.hbm.xml" /> 
        -->
        
        <mapping class="org.model.User"/>
    </session-factory>

</hibernate-configuration>
View Code

下面觀察數據庫:

插入的數據:

-------------------------------------------------

annotation配置many-to-one雙向

先看有問題的代碼:(明明配置了級聯  可是卻沒有進行級聯保存的問題)

多方:Student

 

package org.model;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

//多方  由該方維護外鍵
@Entity
@Table(name = "t_student")
public class Student {
    private int id;
    private String name;
    private String stuNo;
    // 一方的屬性
    private ClassRoom room;

    @Id
    @GeneratedValue()
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 5, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(length = 10, nullable = false)
    public String getStuNo() {
        return stuNo;
    }

    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }

    // optional=false 外鍵字段不能爲空 即每一個學生都必須有對應的班級 默認爲true
    // ManyToOne 查詢student 默認使用即時加載
    @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
    // 在維護端 指定外鍵字段名 也能夠不寫 默認屬性_id
    @JoinColumn(name = "r_id")
    public ClassRoom getRoom() {
        return room;
    }

    public void setRoom(ClassRoom room) {
        this.room = room;
    }

    public Student() {
    }

    // 互相關聯的方法
    public Student(String name, String stuNo) {
        this.name = name;
        this.stuNo = stuNo;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
    }

}

 

一方:ClassRoom

package org.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

//一方  被維護端
@Entity
@Table(name = "t_classroom")
public class ClassRoom {
    private int id;
    private String name;
    // 多方的集合屬性
    private Set<Student> students = new HashSet<Student>();

    @Id
    @GeneratedValue()
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 10, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // mappedBy屬性:由集合中對應的實體Student中的classroom屬性來維護外鍵 聲明mappedBy的實體爲被維護方
    // 抓取方式 onetoMany 默認爲lazy加載
    @OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, mappedBy = "room")
    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    public ClassRoom(String name) {
        this.name = name;
    }
    
    public ClassRoom() {}
    /*
     * public ClassRoom(int id,String name) { this.id=id; this.name = name; }
     */

    
    // 互相關聯的方法
    public void addStudent(Student student) { student.setRoom(this); this.students.add(student); }

    @Override
    public String toString() {
        return "ClassRoom [id=" + id + ", name=" + name + "]";
    }

}

測試類:

 

    //一對多插入測試
    @Test
    public void oneToManyInsert() {
        Session session=rtn();
        session.getTransaction().begin();
        //建立對象
        Student s1=new Student("喬克","A01010");
        Student s2=new Student("小明","A01012");
        ClassRoom classRoom=new ClassRoom("就業班");
        //進行互相關聯
 classRoom.addStudent(s1); classRoom.addStudent(s2);//在addStudent()中進行了互相關聯   這裏直接調用這個方法即完成了互相關聯
        //進行持久化操做
        session.save(classRoom);
        session.getTransaction().commit();
    }

 

而後查看數據庫:

能夠看到  只對classRoom表進行了數據的插入   能夠咱們在實體中明明配置了級聯保存的操做啊   同時也進行了互相的關聯  爲啥會出現這種狀況呢?

還記得學習JPA時級聯操做觸發的時機嗎?----》若是使用javax.persistence.*裏面的註解,只有調用相應的方法才生效,如PERSIST,只有調用persist方法才生效

因此這裏固然不能實現級聯了

 

https://blog.csdn.net/l1028386804/article/details/17686229

https://blog.csdn.net/z69183787/article/details/22327725

 

 

 第一種測試:

根據網上說的狀況  我了試試  若是把ClassRoom中的級聯屬性配置爲如下的狀況:

CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH

也不能進行級聯保存,可是,若是配置爲CascadeType.All則能夠級聯保存成功,說明

JPA中的CascadeType.ALL並不等於{CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH}

 

 第二種測試:

而後我把級聯屬性設置成了上面說的那種方式save_update   注意  導入的是hibernate.annotation中的包  而再也不是jpa中的級聯包了

 

 roomClass中的級聯方式修改成:

 

測試結果:

級聯保存成功,因此這裏須要明白,hibernate註解開發 設置級聯時不能使用jpa規範中的級聯方式,而只能是使用本身提供的級聯方式,以下:

---------------------------------------

上面進行了插入測試,下面咱們進行查詢測試:

可見只查詢了一次數據庫,在查詢student對象(多方)  當即查詢一方數據

由於咱們在student中是這樣配置的

抓取方式  在ManyToOne狀況下  默認直接加載了一方屬性  若是改成下面的配置方式:

執行查詢  觀察打印的sql

能夠看到  是發送了兩次sql查詢  一樣  在執行查詢一方屬性時  不指定查詢方式時   默認是懶加載多方屬性的  這裏就再也不執行了

須要注意的一點是:在查詢某個實體的時候  須要在該實體中配置一個無參數的構造方法    好比  我把student實體中的無參構造刪除掉  而後執行查詢

因此  由於框架中好多地方都會用到無參構造  在咱們建立有參構造的時候  記得把無參構造也寫出來。

---------------------------------------------------------------

annotation配置many-to-one單向

student

package org.model.om.danxiang;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "danxiang_student")
public class Student {
    private int id;
    private String name;
    private String stuNo;
    // 一方的屬性
    private ClassRoom room;

    @Id
    @GeneratedValue()
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 5, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(length = 10, nullable = false)
    public String getStuNo() {
        return stuNo;
    }

    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }

    // optional=false 外鍵字段不能爲空 即每一個學生都必須有對應的班級 默認爲true
    // ManyToOne 查詢student 默認使用即時加載
    //使用hibernate本身的級聯方式
    @ManyToOne()
    //@Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
    // 在維護端 指定外鍵字段名 也能夠不寫 默認屬性_id
    @JoinColumn(name = "cid")
    public ClassRoom getRoom() {
        return room;
    }

    public void setRoom(ClassRoom classRoom) {
        this.room = classRoom;
    }
    
    public Student() {
    }

    // 互相關聯的方法
    public Student(String name, String stuNo) {
        this.name = name;
        this.stuNo = stuNo;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
    }

}

classRoom

package org.model.om.danxiang;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

//一方  被維護端
@Entity
@Table(name = "danxiang_classroom")
public class ClassRoom {
    private int id;
    private String name;
    /*
    // 多方的集合屬性
    private Set<Student> students = new HashSet<Student>();*/

    @Id
    @GeneratedValue()
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 10, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    /*
    // mappedBy屬性:由集合中對應的實體Student中的classroom屬性來維護外鍵 聲明mappedBy的實體爲被維護方
    // 抓取方式 onetoMany 默認爲lazy加載
    //使用hibernate本身的級聯方式
    @OneToMany(mappedBy = "room")
    @Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }*/

    public ClassRoom(String name) {
        this.name = name;
    }
    
    public ClassRoom() {}
    /*
     * public ClassRoom(int id,String name) { this.id=id; this.name = name; }
     */

    /*
    // 互相關聯的方法
    public void addStudent(Student student) {
        student.setRoom(this);
        this.students.add(student);
    }*/

    @Override
    public String toString() {
        return "ClassRoom [id=" + id + ", name=" + name + "]";
    }

}

測試:

    //單向 一方classroom中不建立集合 只在多方student中建立一方對象 ---》 測試成功 //因此 單向方式操做時 只能是:在多方對象中建立一方對象屬性 在一方中省略建立多方的集合屬性 反之則不行 好比測試2
    @Test
    public void oneToManyInsertDanXiang() {
        Session session=rtn();
        session.getTransaction().begin();
        //建立對象
        org.model.om.danxiang.Student s1=new org.model.om.danxiang.Student("喬克","A01010");
        org.model.om.danxiang.Student s2=new org.model.om.danxiang.Student("喬克2","A01012");
        
        org.model.om.danxiang.ClassRoom classRoom=new org.model.om.danxiang.ClassRoom("就業班");
        //進行互相關聯
        s1.setRoom(classRoom);
        s2.setRoom(classRoom);
        //保存
        session.save(classRoom);//保存的順序無關
        session.save(s1);
        session.save(s2);
        
        //classRoom.addStudent(s1);
        //classRoom.addStudent(s2);//在addStudent()中進行了互相關聯   這裏直接調用這個方法即完成了互相關聯
        //進行持久化操做
        session.save(classRoom);
        session.getTransaction().commit();
    }

查詢測試:

    //單向查詢
    @Test
    public void oneToManyInsertDanXiangQuery() {
        Session session=rtn();
        //查詢多方   觀察是否同時查詢一方數據
        org.model.om.danxiang.Student student = session.get(org.model.om.danxiang.Student.class,67);
        System.out.println(student);
    }

單向關係,查詢多方的時候,能夠順帶查詢一方的數據   可是不能經過查詢一方同時得到多方的數據   可是雙向關係就能夠  查詢ClassRoom時  能夠選擇即便加載或者懶加載多方屬性   而後經過ClassRoom中的students屬性就能夠獲得多方集合數據

-----------------------------------------------

openSession和getCurrentSession的區別:

 

使用getCurrentSession時  出現下面錯誤  是由於沒有開啓事務

開啓事務  就能夠解決該問題

---------------------------------------------------

 annotation配置many-to-one雙向

Person

package org.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

//一對一雙向實體  person做爲維護方
@Entity
@Table(name = "t_person")
public class Person {
    private int id;// 主鍵
    private String name;// 姓名
    private IDCard idCard;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    // 這裏暫時不配置 數據庫默認字段爲name 能夠爲空 長度255
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

 @OneToOne @JoinColumn(name = "cardid") @Cascade(value = { CascadeType.ALL }) public IDCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IDCard idCard) {
        this.idCard = idCard;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", idCard=" + idCard + "]";
    }

}

IDCard

package org.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

//一對一雙向實體
@Entity
@Table(name = "t_card")
public class IDCard {
    private int id;// 主鍵
    private String no;// 編號
    private Person person;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

  @OneToOne(mappedBy = "idCard") @Cascade(value = { CascadeType.ALL }) public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    @Override
    public String toString() {
        return "IDCard [id=" + id + ", no=" + no + ", person=" + person + "]";
    }

}

測試

//一對一雙向關聯
    @Test
    public void oneToOne() {
        Session session=rtn();
        session.getTransaction().begin();
        //建立person對象
        Person p=new Person();
        p.setName("張三");
        //建立IDCard對象
        IDCard idCard=new IDCard();
        idCard.setNo("xx1");
        //進行相互關聯
        /**
         * 若是沒有配置級聯保存的話 那麼須要相互關聯 而且還要分別保存
        p.setIdCard(idCard);
        idCard.setPerson(p);
        session.save(idCard);
        session.save(p);
        */
        //配置級聯以後 
        p.setIdCard(idCard);
        session.save(p);
        session.getTransaction().commit();
        session.close();
    }

數據庫:

-------------------------------------

annotation配置many-to-many

user

package org.model.mm.shuangxiang;

import java.util.Date;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name="mm_user")
//規定該實體爲外鍵維護方
public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private Date bornDate;
    private Set<Role> roles;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Column(length=10,nullable=false)
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @Column(length=10,nullable=false)
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Column(length=10,nullable=false)
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    @Temporal(TemporalType.TIMESTAMP)//日期 時間 yyyy-dd-mm HH:MM:SS
    public Date getBornDate() {
        return bornDate;
    }
    public void setBornDate(Date bornDate) {
        this.bornDate = bornDate;
    }
    //以m打頭   默認加載方式爲lazy
 @ManyToMany() @Cascade(value= {CascadeType.ALL}) /** @JoinTable( name="u_r",//中間表名稱 joinColumns=@JoinColumn(name="uid"),//本實體在中間表中建立的字段名 inverseJoinColumns= @JoinColumn(name="rid"))//關聯實體在中間表中建立的字段名 //以上內容能夠省略不寫 有默認值 */
    public Set<Role> getRoles() {
        return roles;
    }
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
    public User(String username, String password, String nickname, Date bornDate) {
        super();
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.bornDate = bornDate;
    }
    public User() {}
    
}

role

package org.model.mm.shuangxiang;

import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = "mm_role")
public class Role {
    private int id;
    private String name;
    private Set<User> users;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    @Column(length=10,nullable=false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
 @ManyToMany(mappedBy="roles") @Cascade(value= {CascadeType.ALL}) public Set<User> getUsers() {
        return users;
    }

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

    @Override
    public String toString() {
        return "Role [id=" + id + ", name=" + name + ", users=" + users + "]";
    }

    public Role(String name) {
        super();
        this.name = name;
    }
    public Role() {}
    

}

測試:

//多對多不拆分
    @Test
    public void manyToMany() {
        Session session=rtn();
        session.getTransaction().begin();
        //建立user對象
        org.model.mm.shuangxiang.User user1=new org.model.mm.shuangxiang.User("zhang","123","小張",new Date());
        //org.model.mm.shuangxiang.User user2=new org.model.mm.shuangxiang.User("wang","123","小王",new Date());
        //org.model.mm.shuangxiang.User user3=new org.model.mm.shuangxiang.User("sun","123","小孫",new Date());
    
        //建立role對象
        Role role1=new Role("總監");
        Role role2=new Role("保安");
        Role role3=new Role("菜鳥");
        //建立集合
        Set<Role> roles=new HashSet<Role>();
        roles.add(role1);
        roles.add(role2);
        roles.add(role3);
        //進行關聯  
        user1.setRoles(roles);
        //保存user對象
        session.save(user1);
        session.getTransaction().commit();
        session.close();
    }

數據庫:

 

-----------------------------------------

 annotation配置many-to-many變種  拆分爲兩個一對多

Student

package org.model.mm.shuangxiang2;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = "mm_student")
public class Student {
    private int id;
    private String name;
    private String stuNo;
    private Set<StudentCourse> tcs;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 10, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(length = 10, nullable = false)
    public String getStuNo() {
        return stuNo;
    }

    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }

    // 與中間表相比 是一方 被維護端
    @OneToMany(mappedBy = "student") @Cascade(value = { CascadeType.ALL }) public Set<StudentCourse> getTcs() {
        return tcs;
    }

    public void setTcs(Set<StudentCourse> tcs) {
        this.tcs = tcs;
    }

    public Student() {
    }

    public Student(String name, String stuNo) {
        this.name = name;
        this.stuNo = stuNo;
    }
}

Course

package org.model.mm.shuangxiang2;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = "mm_course")
public class Course {
    private int id;
    private String name;
    private Set<StudentCourse> tcs;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 10, nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 是一方 被維護端
    @OneToMany(mappedBy = "course") @Cascade(value = { CascadeType.ALL }) public Set<StudentCourse> getTcs() {
        return tcs;
    }

    public void setTcs(Set<StudentCourse> tcs) {
        this.tcs = tcs;
    }

    public Course() {
    }

    public Course(String name) {
        this.name = name;
    }

}

中間實體  StudentCourse

 

package org.model.mm.shuangxiang2;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

@Entity
@Table(name = "mm_SC") // 指定中間表名稱
public class StudentCourse {
    private int id;
    private double score;
    private Student student;
    private Course course;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(length = 5, nullable = false)
    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    // 多方維護外鍵 指定中間表外鍵名稱爲student_ID
 @ManyToOne() @Cascade(value = { CascadeType.ALL }) @JoinColumn(name = "student_ID") public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    // 多方維護外鍵 指定中間表外鍵名稱爲course_ID
 @ManyToOne() @Cascade(value = { CascadeType.ALL }) @JoinColumn(name = "course_ID") // 多方做爲維護端
    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    public StudentCourse(double score, Student student, Course course) {
        super();
        this.score = score;
        this.student = student;
        this.course = course;
    }

    public StudentCourse() {
    }

}

 

配置文件中引入:

測試:

//多對多  拆分爲兩個一對多
    @Test
    public void manyToMany2() {
        Session session=rtn();
        session.getTransaction().begin();
        //建立2個student對象
        org.model.mm.shuangxiang2.Student student1=new org.model.mm.shuangxiang2.Student("zhang","141164000");
        org.model.mm.shuangxiang2.Student student2=new org.model.mm.shuangxiang2.Student("wang","141164888");
        //建立2個course對象
        Course course1=new Course("java");
        Course course2=new Course("php");
        //建立studentCourse對象  把建立的student course加入進去
        //學生1的兩門課成績
        StudentCourse sc1=new StudentCourse(88.5,student1,course1);
        StudentCourse sc2=new StudentCourse(99.5,student1,course2);
        //學生2的兩門課成績
        StudentCourse sc3=new StudentCourse(66.5,student2,course1);
        StudentCourse sc4=new StudentCourse(49.5,student2,course2);
        //保存維護端對象  studentcourse
        session.save(sc1);
        session.save(sc2);
        session.save(sc3);
        session.save(sc4);
        session.getTransaction().commit();
        session.close();
    }

數據庫:

-------------------------------------

相關文章
相關標籤/搜索