hibernate annotation 关联关系

怼烎@ 2022-08-21 08:46 123阅读 0赞

在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. @Column(name="register_date")  --->  Column中的name属性对应了数据库的该字段名字,里面还有其他属性,例如lengthnullable等等
  11. public Date getRegisterDate()
  12. {
  13. return registerDate;
  14. }
  15. public void setRegisterDate(Date registerDate)
  16. {
  17. this.registerDate = registerDate;
  18. }
  19. @Id  --->  定义为数据库的主键ID  (建议不要在属性上引入注解,因为属性是private的,如果引入注解会破坏其封装特性,所以建议在getter方法上加入注解)
  20. @GeneratedValue  ---->  ID的生成策略为自动生成  
  21. public int getId()
  22. {
  23. return id;
  24. }
  25. public void setId(int id)
  26. {
  27. this.id = id;
  28. }
  29.   ............
  30. }

复制代码

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

  1. <!-- 基于annotation的配置 -->
  2. <mapping class="com.xiaoluo.bean.User"/>
  3. <!-- 基于hbm.xml配置文件 -->
  4. <mapping resource="com/xiaoluo/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. public ClassRoom()
  9. {
  10. students = new HashSet<Student>();
  11. }
  12. public void addStudent(Student student)
  13. {
  14. students.add(student);
  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 getClassName()
  27. {
  28. return className;
  29. }
  30. public void setClassName(String className)
  31. {
  32. this.className = className;
  33. }
  34. @OneToMany(mappedBy="room")  --->  OneToMany指定了一对多的关系,mappedBy="room"指定了由多的那一方来维护关联关系,mappedBy指的是多的一方对1的这一方的依赖的属性,(注意:如果没有指定由谁来维护关联关系,则系统会给我们创建一张中间表)
  35. @LazyCollection(LazyCollectionOption.EXTRA)  --->  LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能
  36. public Set<Student> getStudents()
  37. {
  38. return students;
  39. }
  40. public void setStudents(Set<Student> students)
  41. {
  42. this.students = students;
  43. }
  44. }

复制代码

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

复制代码

三、一对一映射(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. @OneToOne(mappedBy="person")  --->  指定了OneToOne的关联关系,mappedBy同样指定由对方来进行维护关联关系
  9. public IDCard getCard()
  10. {
  11. return card;
  12. }
  13. public void setCard(IDCard card)
  14. {
  15. this.card = card;
  16. }
  17. @Id
  18. @GeneratedValue
  19. public int getId()
  20. {
  21. return id;
  22. }
  23. public void setId(int id)
  24. {
  25. this.id = id;
  26. }
  27. public String getName()
  28. {
  29. return name;
  30. }
  31. public void setName(String name)
  32. {
  33. this.name = name;
  34. }
  35. }

复制代码

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

复制代码

注意:在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系。

四、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. public Teacher()
  9. {
  10. courses = new HashSet<Course>();
  11. }
  12. public void addCourse(Course course)
  13. {
  14. courses.add(course);
  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. @ManyToMany(mappedBy="teachers")  --->  表示由Course那一方来进行维护
  35. public Set<Course> getCourses()
  36. {
  37. return courses;
  38. }
  39. public void setCourses(Set<Course> courses)
  40. {
  41. this.courses = courses;
  42. }
  43. }

复制代码

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

复制代码

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来进行插入操作的时候,不管是一对多、一对一还是多对多,都只需要记住一点,在哪个实体类声明了外键,就由哪个类来维护关系,在保存数据时,总是先保存的是没有维护关联关系的那一方的数据,后保存维护了关联关系的那一方的数据,如:

复制代码

  1.        Person p = new Person();
  2. p.setName("xiaoluo");
  3. session.save(p);
  4. IDCard card = new IDCard();
  5. card.setNo("1111111111");
  6. card.setPerson(p);
  7. session.save(card);

复制代码

以上就是对hibernate annotation注解方式来配置映射关系的一些总结。

发表评论

表情:
评论列表 (有 0 条评论,123人围观)

还没有评论,来说两句吧...

相关阅读

    相关 hibernate annotation 关联关系

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置

    相关 Hibernate的一对一关联关系

      Hibernate的一对一关联关系,分为基于外键的一对一关联关系和基于主键的一对一关联关系。在这篇文章中,我们以部门和部门经理的例子来说明,一个部门对应唯一一个部门经理,一

    相关 Hibernate 03-配置关联关系映射

    一、了解关联关系 类与类之间最普遍的关系就是关联关系,并且关联是有方向的。以部门(Dept)和员工(Emp)类为例,一个部门下有多个员工,而一个员工只能属于一个部门