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笔记--使用注解(annotation)方式配置单(双)向多对一的映射关系