hibernate annotation注解方式来处理映射关系

Posted smellpawn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate annotation注解方式来处理映射关系相关的知识,希望对你有一定的参考价值。

在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用annotation的方式可以更简介,所以这里就简单记录下通过annotation来配置各种映射关系,在hibernate4以后已经将annotation的jar包集成进来了,如果使用hibernate3的版本就需要引入annotation的jar包。

一、单对象操作

 1 @Entity  --->  如果我们当前这个bean要设置成实体对象,就需要加上Entity这个注解
 2 @Table(name="t_user")  ---->  设置数据库的表名
 3 public class User
 4 {
 5     private int id;
 6     private String username;
 7     private String password;
 8     private Date born;
 9     private Date registerDate;
10 
11     @Column(name="register_date")  --->  Column中的name属性对应了数据库的该字段名字,里面还有其他属性,例如length,nullable等等
12     public Date getRegisterDate()
13     {
14         return registerDate;
15     }
16     public void setRegisterDate(Date registerDate)
17     {
18         this.registerDate = registerDate;
19     }
20 
21     @Id  --->  定义为数据库的主键ID  (建议不要在属性上引入注解,因为属性是private的,如果引入注解会破坏其封装特性,所以建议在getter方法上加入注解)
22     @GeneratedValue  ---->  ID的生成策略为自动生成  
23     public int getId()
24     {
25         return id;
26     }
27     public void setId(int id)
28     {
29         this.id = id;
30     }
31    ............
32 }

最后只需要在hibernate.cfg.xml文件里面将该实体类加进去即可:

<!-- 基于annotation的配置 -->
        <mapping class="com.qinkang.bean.User"/>
<!-- 基于hbm.xml配置文件 -->
        <mapping resource="com/qinkang/bean/User.hbm.xml"/>

这样我们就可以写测试类来进行我们的CRUD操作了。

二、一对多的映射(one-to-many)

这里我们定义了两个实体类,一个是ClassRoom,一个是Student,这两者是一对多的关联关系。

ClassRoom类:

 1 @Entity
 2 @Table(name="t_classroom")
 3 public class ClassRoom
 4 {
 5     private int id;
 6     private String className;
 7     private Set<Student> students;
 8     
 9     public ClassRoom()
10     {
11         students = new HashSet<Student>();
12     }
13     
14     public void addStudent(Student student)
15     {
16         students.add(student);
17     }
18 
19     @Id
20     @GeneratedValue
21     public int getId()
22     {
23         return id;
24     }
25 
26     public void setId(int id)
27     {
28         this.id = id;
29     }
30 
31     public String getClassName()
32     {
33         return className;
34     }
35 
36     public void setClassName(String className)
37     {
38         this.className = className;
39     }
40 
41     @OneToMany(mappedBy="room")  --->  OneToMany指定了一对多的关系,mappedBy="room"指定了由多的那一方来维护关联关系,mappedBy指的是多的一方对1的这一方的依赖的属性,(注意:如果没有指定由谁来维护关联关系,则系统会给我们创建一张中间表)
42     @LazyCollection(LazyCollectionOption.EXTRA)  --->  LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能
43     public Set<Student> getStudents()
44     {
45         return students;
46     }
47 
48     public void setStudents(Set<Student> students)
49     {
50         this.students = students;
51     }
52     
53 }

Student类:

 1 @Entity
 2 @Table(name="t_student")
 3 public class Student
 4 {
 5     private int id;
 6     private String name;
 7     private int age;
 8     private ClassRoom room;
 9     
10     @ManyToOne(fetch=FetchType.LAZY)  ---> ManyToOne指定了多对一的关系,fetch=FetchType.LAZY属性表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载)
11     @JoinColumn(name="rid")  --->  通过 JoinColumn 的name属性指定了外键的名称 rid (注意:如果我们不通过JoinColum来指定外键的名称,系统会给我们声明一个名称)
12     public ClassRoom getRoom()
13     {
14         return room;
15     }
16     public void setRoom(ClassRoom room)
17     {
18         this.room = room;
19     }
20     @Id
21     @GeneratedValue
22     public int getId()
23     {
24         return id;
25     }
26     public void setId(int id)
27     {
28         this.id = id;
29     }
30     public String getName()
31     {
32         return name;
33     }
34     public void setName(String name)
35     {
36         this.name = name;
37     }
38     public int getAge()
39     {
40         return age;
41     }
42     public void setAge(int age)
43     {
44         this.age = age;
45     }
46     
47 }

三、一对一映射(One-to-One)

一对一关系这里定义了一个Person对象以及一个IDCard对象

Person类:

 1 @Entity
 2 @Table(name="t_person")
 3 public class Person
 4 {
 5     private int id;
 6     private String name;
 7     private IDCard card;
 8     
 9     @OneToOne(mappedBy="person")  --->  指定了OneToOne的关联关系,mappedBy同样指定由对方来进行维护关联关系
10     public IDCard getCard()
11     {
12         return card;
13     }
14     public void setCard(IDCard card)
15     {
16         this.card = card;
17     }
18     @Id
19     @GeneratedValue
20     public int getId()
21     {
22         return id;
23     }
24     public void setId(int id)
25     {
26         this.id = id;
27     }
28     public String getName()
29     {
30         return name;
31     }
32     public void setName(String name)
33     {
34         this.name = name;
35     }
36     
37 }

IDCard类:

 1 @Entity
 2 @Table(name="t_id_card")
 3 public class IDCard
 4 {
 5     private int id;
 6     private String no;
 7     private Person person;
 8     
 9     @Id
10     @GeneratedValue
11     public int getId()
12     {
13         return id;
14     }
15     public void setId(int id)
16     {
17         this.id = id;
18     }
19     public String getNo()
20     {
21         return no;
22     }
23     public void setNo(String no)
24     {
25         this.no = no;
26     }
27     @OneToOne  --->  OnetoOne指定了一对一的关联关系,一对一中随便指定一方来维护映射关系,这里选择IDCard来进行维护
28     @JoinColumn(name="pid")  --->  指定外键的名字 pid
29     public Person getPerson()
30     {
31         return person;
32     }
33     public void setPerson(Person person)
34     {
35         this.person = person;
36     }
37 }

四、Many-to-Many映射(多对多映射关系)

多对多这里通常有两种处理方式,一种是通过建立一张中间表,然后由任一一个多的一方来维护关联关系,另一种就是将多对多拆分成两个一对多的关联关系

1.通过中间表由任一一个多的一方来维护关联关系

Teacher类:

 1 @Entity
 2 @Table(name="t_teacher")
 3 public class Teacher
 4 {
 5     private int id;
 6     private String name;
 7     private Set<Course> courses;
 8     
 9     public Teacher()
10     {
11         courses = new HashSet<Course>();
12     }
13     public void addCourse(Course course)
14     {
15         courses.add(course);
16     }
17     
18     @Id
19     @GeneratedValue
20     public int getId()
21     {
22         return id;
23     }
24     public void setId(int id)
25     {
26         this.id = id;
27     }
28     public String getName()
29     {
30         return name;
31     }
32     public void setName(String name)
33     {
34         this.name = name;
35     }
36     @ManyToMany(mappedBy="teachers")  --->  表示由Course那一方来进行维护
37     public Set<Course> getCourses()
38     {
39         return courses;
40     }
41     public void setCourses(Set<Course> courses)
42     {
43         this.courses = courses;
44     }
45     
46 }

Course类:

 1 @Entity
 2 @Table(name="t_course")
 3 public class Course
 4 {
 5     private int id;
 6     private String name;
 7     private Set<Teacher> teachers;
 8     
 9     public Course()
10     {
11         teachers = new HashSet<Teacher>();
12     }
13     public void addTeacher(Teacher teacher)
14     {
15         teachers.add(teacher);
16     }
17     @ManyToMany   ---> ManyToMany指定多对多的关联关系
18     @JoinTable(name="t_teacher_course", joinColumns={ @JoinColumn(name="cid")}, 
19     inverseJoinColumns={ @JoinColumn(name = "tid") })  --->  因为多对多之间会通过一张中间表来维护两表直接的关系,所以通过 JoinTable 这个注解来声明,name就是指定了中间表的名字,JoinColumns是一个 @JoinColumn类型的数组,表示的是我这方在对方中的外键名称,我方是Course,所以在对方外键的名称就是 rid,inverseJoinColumns也是一个 @JoinColumn类型的数组,表示的是对方在我这放中的外键名称,对方是Teacher,所以在我方外键的名称就是 tid
20     public Set<Teacher> getTeachers()
21     {
22         return teachers;
23     }
24 
25     public void setTeachers(Set<Teacher> teachers)
26     {
27         this.teachers = teachers;
28     }
29 
30     @Id
31     @GeneratedValue
32     public int getId()
33     {
34         return id;
35     }
36 
37     public void setId(int id)
38     {
39         this.id = id;
40     }
41 
42     public String getName()
43     {
44         return name;
45     }
46 
47     public void setName(String name)
48     {
49         this.name = name;
50     }
51 
52 }

2.将Many-to-Many拆分成两个One-to-Many的映射(Admin、Role、AdminRole)

Admin类:

 1 @Entity
 2 @Table(name="t_admin")
 3 public class Admin
 4 {
 5     private int id;
 6     private String name;
 7     private Set<AdminRole> ars;
 8     public Admin()
 9     {
10         ars = new HashSet<AdminRole>();
11     }
12     public void add(AdminRole ar)
13     {
14         ars.add(ar);
15     }
16     @Id
17     @GeneratedValue
18     public int getId()
19     {
20         return id;
21     }
22     public void setId(int id)
23     {
24         this.id = id;
25     }
26     public String getName()
27     {
28         return name;
29     }
30     public void setName(String name)
31     {
32         this.name = name;
33     }
34     @OneToMany(mappedBy="admin")  --->  OneToMany关联到了AdminRole这个类,由AdminRole这个类来维护多对一的关系,mappedBy="admin"
35     @LazyCollection(LazyCollectionOption.EXTRA)  
36     public Set<AdminRole> getArs()
37     {
38         return ars;
39     }
40     public void setArs(Set<AdminRole> ars)
41     {
42         this.ars = ars;
43     }
44 }

Role类:

 1 @Entity
 2 @Table(name="t_role")
 3 public class Role
 4 {
 5     private int id;
 6     private String name;
 7     private Set<AdminRole> ars;
 8     public Role()
 9     {
10         ars = new HashSet<AdminRole>();
11     }
12     public void add(AdminRole ar)
13     {
14         ars.add(ar);
15     }
16     @Id
17     @GeneratedValue
18     public int getId()
19     {
20         return id;
21     }
22     public void setId(int id)
23     {
24         this.id = id;
25     }
26     public String getName()
27     {
28         return name;
29     }
30     public void setName(String name)
31     {
32         this.name = name;
33     }
34     @OneToMany(mappedBy="role")  --->  OneToMany指定了由AdminRole这个类来维护多对一的关联关系,mappedBy="role"
35     @LazyCollection(LazyCollectionOption.EXTRA)
36     public Set<AdminRole> getArs()
37     {
38         return ars;
39     }
40     public void setArs(Set<AdminRole> ars)
41     {
42         this.ars = ars;
43     }
44 }

AdminRole类:

 1 @Entity
 2 @Table(name="t_admin_role")
 3 public class AdminRole
 4 {
 5     private int id;
 6     private String name;
 7     private Admin admin;
 8     private Role role;
 9     @Id
10     @GeneratedValue
11     public int getId()
12     {
13         return id;
14     }
15     public void setId(int id)
16     {
17         this.id = id;
18     }
19     public String getName()
20     {
21         return name;
22     }
23     public void setName(String name)
24     {
25         this.name = name;
26     }
27     @ManyToOne  --->  ManyToOne关联到Admin
28     @JoinColumn(name="aid")  
29     public Admin getAdmin()
30     {
31         return admin;
32     }
33     public void setAdmin(Admin admin)
34     {
35         this.admin = admin;
36     }
37     @ManyToOne  --->  
38     @JoinColumn(name="rid")
39     public Role getRole()
40     {
41         return role;
42     }
43     public void setRole(Role role)
44     {
45         this.role = role;
46     }
47 }

小提示:通过hibernate来进行插入操作的时候,不管是一对多、一对一还是多对多,都只需要记住一点,在哪个实体类声明了外键,就由哪个类来维护关系,在保存数据时,总是先保存的是没有维护关联关系的那一方的数据,后保存维护了关联关系的那一方的数据

以上是关于hibernate annotation注解方式来处理映射关系的主要内容,如果未能解决你的问题,请参考以下文章

hibernate关联映射注解

hibernate笔记--使用注解(annotation)方式配置单(双)向多对一的映射关系

[Hibernate] 注解映射例子

Hibernate 零配置之Annotation注解

Hibernate or JPA Annotation中BLOBCLOB注解写法

Hibernate Annotations 注解