天天看点

Hibernate(四)基于注解annotation的配置Hibernate04Hibernate基于Annotation的配置使用annotation配置第一个annotation配置的hibernate项目annotation配置many-to-one单向annotation配置many-to-one双向annotation配置one-to-one双向annotation配置many-to-manyannotation配置many-to-many变种总结

Hibernate04

Hibernate基于Annotation的配置

         Annotation在框架中是越来越受欢迎了,因为annotation的配置比起XML的配置来说方便了很多,不需要大量的XML来书写,方便简单了很多,只要几个annotation的配置,就可以完成我们以前需要书写的大量的XML文件。当然annotation的配置也有缺陷的,那就是annotation一般都是配置在代码中的,如果要修改的话,需要动源代码,丧失了灵活性,违背了OCP(增加开放,修改关闭)原则,但是在真实的项目开发中,我们只是动配置文件,而不修改源代码的情况实在是太少见了,所以现在annotation已经被广泛的运用到了编程中,各种框架都提供了基于annotation的配置。

         下面我们来看看hibernate基于annotation的配置吧,在学之前,我们需要知道一些hibernate关于annotation的常识:

1、 hibernate中的annotation是基于JPA这个包的,如果是4.0之前的版本,hibernate的required文件夹下,没有jpa的包,需要去jpa文件夹下加入jpa的包

2、 在hibernate的3.5之前需要下载hibernate的annotation的jar包

3、 在3.5之前如果使用annotation,创建Configuration是需要使用AnnotationConfiguration()来创建。

4、 在3.5之后可以直接使用Configuration来创建(不用管哪种——annotation或者XML)

使用annotation配置

         Annotation的配置使得我们的项目配置文件大大的减少,所以annotation的配置现在在各种框架中的使用越来越广泛,下面我就是用annotation来试试吧。

第一个annotation配置的hibernate项目

         我们就以我们以前的user案例来配置annotation版本的hibernate项目吧。

         创建User.java类,注意看annotation的配置:

package com.lzcc.hibernate.entity;

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name="t_user")

publicclass User {

    privateintid;

    private String username;

    private String password;

    private String nickname;

    private Date bornDate;

    @Id

    @GeneratedValue()

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getUsername() {

       returnusername;

    }

    publicvoid setUsername(String username) {

       this.username = username;

    }

    public String getPassword() {

       returnpassword;

    }

    publicvoid setPassword(String password) {

       this.password = password;

    }

    public String getNickname() {

       returnnickname;

    }

    publicvoid setNickname(String nickname) {

       this.nickname = nickname;

    }

    @Column(name="born_date")

    public Date getBornDate() {

       returnbornDate;

    }

    publicvoid setBornDate(Date bornDate) {

       this.bornDate = 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;

    }

    @Override

    public String toString() {

       return"User [id=" + id + ", username=" + username + ", password="

              + password + ", nickname=" + nickname + ", bornDate="

              + bornDate + "]";

    }

}

         之后在hibernate.cfg.xml文件中加入这个实体类(注意:和配置文件相同的是也是使用mapping引入,但是不同的是使用class属性,并且不是斜杠,而是点):

<!-- 使用annotation的配置,不再使用resource,而是使用class,注意也不再是斜杠,而是点 -->

<mapping class="com.lzcc.hibernate.entity.User"/>

         写单元测试类:

@Test

    publicvoid testAdd() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           User u = new User("laomu", "123", "老孙", DateUtil.getDate("1994-12-23"));

           session.save(u);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           session.getTransaction().rollback();

       } finally {

           HibernateUtil.closed(session);

       }

    }

         运行我们发现和使用配置文件一样,运行成功。

         这就是使用annotation来配置hibernate,我们发现比起XML的配置来说,hibernate的annotation的确比较方便了许多。这个只是单表配置,下面我们来看看many-to-one的配置吧。

annotation配置many-to-one单向

         还是使用我们前面的案例来讲解:

         Student.java:

package com.lzcc.hibernate.entity;

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_stu")

publicclass Student {

    privateintid;

    private String name;

    private String stuNo;

    private ClassRoom classRoom;

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public String getStuNo() {

       returnstuNo;

    }

    publicvoid setStuNo(String stuNo) {

       this.stuNo = stuNo;

    }

@ManyToOne

    @JoinColumn(name="cid")

    public ClassRoom getClassRoom() {

       returnclassRoom;

    }

    publicvoid setClassRoom(ClassRoom classRoom) {

       this.classRoom = classRoom;

    }

    public Student() {

    }

    public Student(int id, String name, String stuNo, ClassRoom classRoom) {

       super();

       this.id = id;

       this.name = name;

       this.stuNo = stuNo;

       this.classRoom = classRoom;

    }

    public Student(String name, String stuNo, ClassRoom classRoom) {

       super();

       this.name = name;

       this.stuNo = stuNo;

       this.classRoom = classRoom;

    }

    @Override

    public String toString() {

       return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo

              + ", classRoom=" + classRoom + "]";

    }

}

         ClassRoom.java:

package com.lzcc.hibernate.entity;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name="t_cls_room")

publicclass ClassRoom {

    privateintid;

    private String name;

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public ClassRoom() {

    }

    public ClassRoom(int id, String name) {

       super();

       this.id = id;

       this.name = name;

    }

    @Override

    public String toString() {

       return"ClassRoom [id=" + id + ", name=" + name + "]";

    }

}

         将两个实体类加入到hibernate的配置文件中:

<!-- 使用annotation的配置,不再使用resource,而是使用class,注意也不再是斜杠,而是点 -->

<mapping class="com.lzcc.hibernate.entity.User"/>

<mapping class="com.lzcc.hibernate.entity.Student"/>

<mapping class="com.lzcc.hibernate.entity.ClassRoom"/>

运行测试代码:

@Test

    publicvoid testAdd01() {

       Session session = null;

        try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           //我们先添加一方,再添加多方

           ClassRoom c = new ClassRoom();

           c.setName("梁山班");

           session.save(c);

           Student stu1 = new Student("宋江", "001", c);

           session.save(stu1);

           Student stu2 = new Student("吴用", "003", c);

           session.save(stu2);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         我们发现配置来说,annotation配置相当的简单,比起XML文件的配置来说要简单了很多的。

         添加来说,annotation和XML配置的都一样,如果先一方,多方后添加,则符合我们的想法,会发送相应的sql数量,如果先添加多方,则会多发送几条更新外键的sql。

@Test

    publicvoid testAdd02() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           //如果我们先添加多的一方呢?

           Student stu1 = new Student();

           stu1.setName("孙悟空");

           stu1.setStuNo("001");

           session.save(stu1);

           Student stu2 = new Student();

           stu2.setName("猪八戒");

           stu2.setStuNo("002");

           session.save(stu2);

           ClassRoom c = new ClassRoom();

           c.setName("西游班");

           session.save(c);

           stu1.setClassRoom(c);

           stu2.setClassRoom(c);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         当我们测试下面代码时发现报错了:

@Test

    publicvoid testAdd03() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           //我们先添加一方,再添加多方

           ClassRoom c = new ClassRoom();

           c.setName("红楼班");

           Student stu1 = new Student("贾宝玉", "001", c);

           session.save(stu1);

           Student stu2 = new Student("林黛玉", "003", c);

           session.save(stu2);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         和XML配置一样,因为我们这样需要强制关联,那么annotation的强制关联怎么写?

         这样就不报错了,但是我们前面就说过,cascade我们一般是不会使用的,只有一些特殊情况才会使用,如在删除一方时,需要关联删除多方时,这些特殊才会使用,但是基本我们也不会这样使用,因为我们要删除时,需要自己控制代码的运行,那么我们一般会在业务层自己写逻辑代码来完成。

@Test

    publicvoid testLoad01() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           Student stu = (Student) session.load(Student.class, 1);

           System.out.println(stu.getName());

           System.out.println(stu.getClassRoom().getName());

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

运行代码,我们发现基于annotation的配置,load方法没有延迟加载,那么如果我们想要延迟加载的话,需要这样配置:

         此时运行代码:

       延迟加载就有了,至于到底使用不使用延迟加载,这个就要根据项目的实际情况而定了。

annotation配置many-to-one双向

         双向的配置和单向很类似,只是在一方设置一个存放多方的集合。

         其实hibernate的annotation配置many-to-one的单向和双向很是类似,下面我们就以上面的案例来实现双向配置。

         Student.java,多方配置跟单向的一样:

package com.lzcc.hibernate.entity;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

@Entity

@Table(name="t_stu")

publicclass Student {

    privateintid;

    private String name;

    private String stuNo;

    private ClassRoom classRoom;

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public String getStuNo() {

       returnstuNo;

    }

    publicvoid setStuNo(String stuNo) {

       this.stuNo = stuNo;

    }

    @ManyToOne(fetch=FetchType.LAZY)

    @JoinColumn(name="cid")

    public ClassRoom getClassRoom() {

       returnclassRoom;

    }

    publicvoid setClassRoom(ClassRoom classRoom) {

       this.classRoom = classRoom;

    }

    public Student() {

    }

    public Student(int id, String name, String stuNo, ClassRoom classRoom) {

       super();

       this.id = id;

       this.name = name;

       this.stuNo = stuNo;

       this.classRoom = classRoom;

    }

    public Student(String name, String stuNo, ClassRoom classRoom) {

       super();

       this.name = name;

       this.stuNo = stuNo;

       this.classRoom = classRoom;

    }

    @Override

    public String toString() {

       return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo

              + ", classRoom=" + classRoom + "]";

    }

}

         ClassRoom.java:

package com.lzcc.hibernate.entity;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;

@Entity

@Table(name="t_cls_room")

public class ClassRoom {

         private int id;

         private String name;

         private Set<Student> students;

         @OneToMany(mappedBy="classRoom")

         public Set<Student> getStudents() {

                  return students;

         }

         public void setStudents(Set<Student> students) {

                  this.students = students;

         }

         @Id

         @GeneratedValue

         public int getId() {

                  return id;

         }

         public void setId(int id) {

                  this.id = id;

         }

         public String getName() {

                  return name;

         }

         public void setName(String name) {

                  this.name = name;

         }

         public ClassRoom() {

         }

         public ClassRoom(int id, String name) {

                  super();

                  this.id = id;

                  this.name = name;

         }

         @Override

         public String toString() {

                  return "ClassRoom [id=" + id + ", name=" + name + "]";

         }

}

         测试代码:

@Test

    publicvoid testAdd01() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           Student stu1 = new Student();

           stu1.setName("曹操");

           stu1.setStuNo("001");

           session.save(stu1);

           Student stu2 = new Student();

           stu2.setName("刘备");

           stu2.setStuNo("002");

           session.save(stu2);

           ClassRoom c = new ClassRoom();

           c.setName("三国班");

           Set<Student> stus = new HashSet<Student>();

           stus.add(stu1);

           stus.add(stu2);

           c.setStudents(stus);

           session.save(c);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         运行结果如下:

         测试load方法:

@Test

    publicvoid testLoad() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           ClassRoom c = (ClassRoom) session.load(ClassRoom.class, 5);

           System.out.println(c.getName());

           System.out.println(c.getStudents().size());

           Student s = (Student) session.load(Student.class, 10);

           System.out.println(s.getName());

           System.out.println(s.getClassRoom().getName());

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           HibernateUtil.closed(session);

       }

    }

         我们发现annotation的配置延迟加载默认不存在了,因为annotation的配置出现的比较晚,这时候hibernate的开发团队发现延迟加载在分层体系中的确不再有那么好的优势,而且因为延迟加载的问题导致hibernate的异常难用,所以默认就不在提供延迟加载了,当然如果想使用延迟加载也行,在many-to-one的annotation中加入就行了:

    @ManyToOne(fetch=FetchType.LAZY)

    @JoinColumn(name="cid")

    public ClassRoom getClassRoom() {

       returnclassRoom;

    }

         除此之外,我们发现了一个问题,如果我们想查询集合或者对应关系的数量时,还是没有使用count(*)这种计数函数,如果我们想要使用的话(当然,如果延迟加载不使用,不建议使用,因为没有延迟加载只会发送一条sql,而加上配置,则会单独的发一条sql完成),可以配置如下:

    @OneToMany(mappedBy="classRoom")

    @LazyCollection(LazyCollectionOption.EXTRA)

    public Set<Student> getStudents() {

       returnstudents;

    }

         注意在one-to-many中加入LazyCollection的annotation中加入extar值,在运行代码,我们发现的确计数使用了count函数:

         但是我们也看出了,多发送了一条sql,所以annotation配置hibernate的话,如果不手动开启延迟加载,不建议开启这个配置。

annotation配置one-to-one双向

         还是以person和IDCard为例:

         Persion.java:

package com.lzcc.hibernate.entity;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.OneToOne;

import javax.persistence.Table;

@Entity

@Table(name = "t_person")

publicclass Person {

    privateintid;

    private String name;

    private IDCard idCard;

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    @OneToOne(mappedBy = "person")

    public IDCard getIdCard() {

       returnidCard;

    }

    publicvoid setIdCard(IDCard idCard) {

       this.idCard = idCard;

    }

    public Person() {

    }

    public Person(int id, String name, IDCard idCard) {

       super();

       this.id = id;

       this.name = name;

       this.idCard = idCard;

    }

    public Person(String name, IDCard idCard) {

       super();

       this.name = name;

       this.idCard = idCard;

    }

    public Person(String name) {

       super();

       this.name = name;

    }

    @Override

    public String toString() {

       return"Person [id=" + id + ", name=" + name + ", idCard=" + idCard

              + "]";

    }

}

         IDCard.java:

package com.lzcc.hibernate.entity;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToOne;

import javax.persistence.Table;

@Entity

@Table(name="t_id_card")

publicclass IDCard {

    privateintid;

    private String no;

    private Person person;

    @OneToOne

    @JoinColumn(name="pid")

    public Person getPerson() {

       returnperson;

    }

    publicvoid setPerson(Person person) {

       this.person = person;

    }

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getNo() {

       returnno;

    }

    publicvoid setNo(String no) {

       this.no = no;

    }

    public IDCard() {

    }

    public IDCard(String no) {

       super();

       this.no = no;

    }

    public IDCard(int id, String no) {

       super();

       this.id = id;

       this.no = no;

    }

    @Override

    public String toString() {

       return"IDCard [id=" + id + ", no=" + no + "]";

    }

}

         此时运行代码:

@Test

    publicvoid testAdd01() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           IDCard card = new IDCard("110120");

           session.save(card);

           //将IDCard设置到用户属性中,表示这个一个一对一的关联

           //表示张三的身份证号码为:110120

           Person p = new Person("张三", card);

           session.save(p);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         代码成功运行,但是我们发现外键没有被关联插入,这是因为annotation的配置中我们明确规定了不由Person端维护关系,有IDCard端的person字段维护关系,那么我们如果要插入数据,必须先有Person,这样IDCard插入数据时才有person字段的id完成外键关联。所以,注意:一对一的annotation配置后,一定要先插入不维护关系的一方。

         那么我们先插入不维护关系的一端:

@Test

    publicvoid testAdd02() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           Person p = new Person("张三 ");

           session.save(p);

           IDCard card = new IDCard("110120");

           card.setPerson(p);

           session.save(card);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         成功的完成了插入。

annotation配置many-to-many

         在hibernate中many-to-many这种配置我们不会使用,我们前面就说过,many-to-many我们会分解为两个many-to-one来配置,下面的代码紧紧供参考。

         User.java:

package com.lzcc.hibernate.entity;

import java.util.Date;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToMany;

import javax.persistence.Table;

@Entity

@Table(name="t_user")

public class User {

         private int id;

         private String username;

         private String password;

         private String nickname;

         private Date bornDate;

         private Set<Role> roles;

         @ManyToMany(mappedBy="users")

         public Set<Role> getRoles() {

                  return roles;

         }

         public void setRoles(Set<Role> roles) {

                  this.roles = roles;

         }

         @Id

         @GeneratedValue

         public int getId() {

                  return id;

         }

         public void setId(int id) {

                  this.id = id;

         }

         public String getUsername() {

                  return username;

         }

         public void setUsername(String username) {

                  this.username = username;

         }

         public String getPassword() {

                  return password;

         }

         public void setPassword(String password) {

                  this.password = password;

         }

         public String getNickname() {

                  return nickname;

         }

         public void setNickname(String nickname) {

                  this.nickname = nickname;

         }

         public Date getBornDate() {

                  return bornDate;

         }

         public void setBornDate(Date bornDate) {

                  this.bornDate = 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;

         }

         @Override

         public String toString() {

                  return "User [id=" + id + ", username=" + username + ", password="

                                   + password + ", nickname=" + nickname + ", bornDate="

                                   + bornDate + "]";

         }

}

         Role.java:

package com.lzcc.hibernate.entity;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.JoinTable;

import javax.persistence.ManyToMany;

import javax.persistence.Table;

@Entity

@Table(name="t_role")

public class Role {

         private int id;

         private String name;

         private Set<User> users;

         @ManyToMany

         @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="rid")},

                          inverseJoinColumns={@JoinColumn(name="uid")})

         public Set<User> getUsers() {

                  return users;

         }

         public void setUsers(Set<User> users) {

                  this.users = users;

         }

         @Id

         @GeneratedValue

         public int getId() {

                  return id;

         }

         public void setId(int id) {

                  this.id = id;

         }

         public String getName() {

                  return name;

         }

         public void setName(String name) {

                  this.name = name;

         }

         public Role() {

         }

         public Role(String name) {

                  this.name = name;

         }

         public Role(int id, String name) {

                  super();

                  this.id = id;

                  this.name = name;

         }

         @Override

         public String toString() {

                  return "Role [id=" + id + ", name=" + name + "]";

         }

}

         这就是多对多的配置,但是不建议使用它,我们多对多都是由两个一对多来完成,下面我来看看吧。

annotation配置many-to-many变种

         还是以前面的案例来说

         Student.java:

package com.lzcc.hibernate.entity;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;

@Entity

@Table(name = "stu")

publicclass Student {

    privateintid;

    private String name;

    private String stuNo;

    private Set<StudentCourse> tcs;

    @OneToMany(mappedBy="stu")

    public Set<StudentCourse> getTcs() {

       returntcs;

    }

    publicvoid setTcs(Set<StudentCourse> tcs) {

       this.tcs = tcs;

    }

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public String getStuNo() {

       returnstuNo;

    }

    publicvoid setStuNo(String stuNo) {

       this.stuNo = stuNo;

    }

    public Student() {

    }

    public Student(int id, String name, String stuNo) {

       this.id = id;

       this.name = name;

       this.stuNo = stuNo;

    }

    public Student(String name, String stuNo) {

       this.name = name;

       this.stuNo = stuNo;

    }

    @Override

    public String toString() {

       return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo

              + "]";

    }

}

         Course.java:

package com.lzcc.hibernate.entity;

import java.util.Set;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;

@Entity

@Table(name="t_course")

publicclass Course {

    privateintid;

    private String name;

    private Set<StudentCourse> tcs;

    @OneToMany(mappedBy="course")

    public Set<StudentCourse> getTcs() {

       returntcs;

    }

    publicvoid setTcs(Set<StudentCourse> tcs) {

       this.tcs = tcs;

    }

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    public Course() {

    }

    public Course(int id, String name) {

       this.id = id;

       this.name = name;

    }

    public Course(String name) {

       this.name = name;

    }

}

         TeacherCourse.java:

package com.lzcc.hibernate.entity;

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_stu_course")

publicclass StudentCourse {

    privateintid;

    privatedoublescore;

    private Student stu;

    private Course course;

    @Id

    @GeneratedValue

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    publicdouble getScore() {

       returnscore;

    }

    publicvoid setScore(double score) {

       this.score = score;

    }

    @ManyToOne

    @JoinColumn(name="sid")

    public Student getStu() {

       returnstu;

    }

    publicvoid setStu(Student stu) {

       this.stu = stu;

    }

    @ManyToOne

    @JoinColumn(name="cid")

    public Course getCourse() {

       returncourse;

    }

    publicvoid setCourse(Course course) {

       this.course = course;

    }

    public StudentCourse() {

    }

    public StudentCourse(int id, double score, Student stu, Course course) {

       super();

       this.id = id;

       this.score = score;

       this.stu = stu;

       this.course = course;

    }

}

         运行测试代码:

@Test

    publicvoid testAdd01() {

       Session session = null;

       try {

           session = HibernateUtil.openSession();

           session.beginTransaction();

           Student s1 = new Student();

           s1.setName("刘建宏");

           s1.setStuNo("001");

           session.save(s1);

           Student s2 = new Student();

           s2.setName("刘帅哥");

           s2.setStuNo("002");

           session.save(s2);

           Course c1 = new Course();

           c1.setName("Java in Action");

           session.save(c1);

           Course c2 = new Course();

           c2.setName("PHP in Action");

           session.save(c2);

           StudentCourse tc = new StudentCourse();

           tc.setScore(88);

           tc.setStu(s1);

           tc.setCourse(c1);

           session.save(tc);

           tc = new StudentCourse();

           tc.setScore(99);

           tc.setStu(s1);

           tc.setCourse(c2);

           session.save(tc);

           tc = new StudentCourse();

           tc.setScore(100);

           tc.setStu(s2);

           tc.setCourse(c2);

           session.save(tc);

           tc = new StudentCourse();

           tc.setScore(60);

           tc.setStu(s2);

           tc.setCourse(c1);

           session.save(tc);

           session.getTransaction().commit();

       } catch (Exception e) {

           e.printStackTrace();

           if (session != null) {

              session.getTransaction().rollback();

           }

       } finally {

           HibernateUtil.closed(session);

       }

    }

         我们发现结果完全一样,而且在关系表中我们可以加入一些其他的字段,这样才是我们做多对多关联的,我们在使用hibernate的时候,会将多对多分解为两个多对一来完成。

总结

         Hibernate引入annotation的时间比较晚,所以annotation的配置相对来说比较好用点,因为hibernate将延迟加载等问题都屏蔽掉了(如果想使用,可以配置),所以在将来的项目中,建议如下:

1、 如果是小型项目,建议使用annotation的配置,简单方便

2、 如果是大型项目(百万行代码量及以上),建议使用hibernate

继续阅读