分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

hibernate关联映射注解

发布时间:2023-09-06 01:51责任编辑:董明明关键词:暂无标签

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

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

一、单对象操作

@Entity  --->  如果我们当前这个bean要设置成实体对象,就需要加上Entity这个注解@Table(name="t_user")  ---->  设置数据库的表名public class User{ ???private int id; ???private String username; ???private String password; ???private Date born; ???private Date registerDate;
???@Column(name="register_date")  --->  Column中的name属性对应了数据库的该字段名字,里面还有其他属性,例如length,nullable等等 ???public Date getRegisterDate() ???{ ???????return registerDate; ???} ???public void setRegisterDate(Date registerDate) ???{ ???????this.registerDate = registerDate; ???}
???@Id  --->  定义为数据库的主键ID  (建议不要在属性上引入注解,因为属性是private的,如果引入注解会破坏其封装特性,所以建议在getter方法上加入注解) ???@GeneratedValue  ---->  ID的生成策略为自动生成   ???public int getId() ???{ ???????return id; ???} ???public void setId(int id) ???{ ???????this.id = id; ???}   ............}

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

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

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

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

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

ClassRoom类:

@Entity@Table(name="t_classroom")public class ClassRoom{ ???private int id; ???private String className; ???private Set<Student> students; ???????public ClassRoom() ???{ ???????students = new HashSet<Student>(); ???} ???????public void addStudent(Student student) ???{ ???????students.add(student); ???} ???@Id ???@GeneratedValue ???public int getId() ???{ ???????return id; ???} ???public void setId(int id) ???{ ???????this.id = id; ???} ???public String getClassName() ???{ ???????return className; ???} ???public void setClassName(String className) ???{ ???????this.className = className; ???} ???@OneToMany(mappedBy="room")  --->  OneToMany指定了一对多的关系,mappedBy="room"指定了由多的那一方来维护关联关系,mappedBy指的是多的一方对1的这一方的依赖的属性,(注意:如果没有指定由谁来维护关联关系,则系统会给我们创建一张中间表) ???@LazyCollection(LazyCollectionOption.EXTRA)  --->  LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能 ???public Set<Student> getStudents() ???{ ???????return students; ???} ???public void setStudents(Set<Student> students) ???{ ???????this.students = students; ???} ???}

Student类:

@Entity@Table(name="t_student")public class Student{ ???private int id; ???private String name; ???private int age; ???private ClassRoom room; ???????@ManyToOne(fetch=FetchType.LAZY)  ---> ManyToOne指定了多对一的关系,fetch=FetchType.LAZY属性表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载) ???@JoinColumn(name="rid")  --->  通过 JoinColumn 的name属性指定了外键的名称 rid (注意:如果我们不通过JoinColum来指定外键的名称,系统会给我们声明一个名称) ???public ClassRoom getRoom() ???{ ???????return room; ???} ???public void setRoom(ClassRoom room) ???{ ???????this.room = room; ???} ???@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 int getAge() ???{ ???????return age; ???} ???public void setAge(int age) ???{ ???????this.age = age; ???} ???}

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

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

Person类:

@Entity@Table(name="t_person")public class Person{ ???private int id; ???private String name; ???private IDCard card; ???????@OneToOne(mappedBy="person")  --->  指定了OneToOne的关联关系,mappedBy同样指定由对方来进行维护关联关系 ???public IDCard getCard() ???{ ???????return card; ???} ???public void setCard(IDCard card) ???{ ???????this.card = card; ???} ???@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; ???} ???}

IDCard类:

@Entity@Table(name="t_id_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  --->  OnetoOne指定了一对一的关联关系,一对一中随便指定一方来维护映射关系,这里选择IDCard来进行维护 ???@JoinColumn(name="pid")  --->  指定外键的名字 pid ???public Person getPerson() ???{ ???????return person; ???} ???public void setPerson(Person person) ???{ ???????this.person = person; ???}}

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

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

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

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

Teacher类:

@Entity@Table(name="t_teacher")public class Teacher{ ???private int id; ???private String name; ???private Set<Course> courses; ???????public Teacher() ???{ ???????courses = new HashSet<Course>(); ???} ???public void addCourse(Course course) ???{ ???????courses.add(course); ???} ???????@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; ???} ???@ManyToMany(mappedBy="teachers")  --->  表示由Course那一方来进行维护 ???public Set<Course> getCourses() ???{ ???????return courses; ???} ???public void setCourses(Set<Course> courses) ???{ ???????this.courses = courses; ???} ???}

Course类:

@Entity@Table(name="t_course")public class Course{ ???private int id; ???private String name; ???private Set<Teacher> teachers; ???????public Course() ???{ ???????teachers = new HashSet<Teacher>(); ???} ???public void addTeacher(Teacher teacher) ???{ ???????teachers.add(teacher); ???} ???@ManyToMany   ---> ManyToMany指定多对多的关联关系 ???@JoinTable(name="t_teacher_course", joinColumns={ @JoinColumn(name="cid")}, ????inverseJoinColumns={ @JoinColumn(name = "tid") })  --->  因为多对多之间会通过一张中间表来维护两表直接的关系,所以通过 JoinTable 这个注解来声明,name就是指定了中间表的名字,JoinColumns是一个 @JoinColumn类型的数组,表示的是我这方在对方中的外键名称,我方是Course,所以在对方外键的名称就是 ridinverseJoinColumns也是一个 @JoinColumn类型的数组,表示的是对方在我这放中的外键名称,对方是Teacher,所以在我方外键的名称就是 tid ???public Set<Teacher> getTeachers() ???{ ???????return teachers; ???} ???public void setTeachers(Set<Teacher> teachers) ???{ ???????this.teachers = teachers; ???} ???@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; ???}}

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

Admin类:

@Entity@Table(name="t_admin")public class Admin{ ???private int id; ???private String name; ???private Set<AdminRole> ars; ???public Admin() ???{ ???????ars = new HashSet<AdminRole>(); ???} ???public void add(AdminRole ar) ???{ ???????ars.add(ar); ???} ???@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; ???} ???@OneToMany(mappedBy="admin")  --->  OneToMany关联到了AdminRole这个类,由AdminRole这个类来维护多对一的关系,mappedBy="admin" ???@LazyCollection(LazyCollectionOption.EXTRA)   ???public Set<AdminRole> getArs() ???{ ???????return ars; ???} ???public void setArs(Set<AdminRole> ars) ???{ ???????this.ars = ars; ???}}

Role类:

@Entity@Table(name="t_role")public class Role{ ???private int id; ???private String name; ???private Set<AdminRole> ars; ???public Role() ???{ ???????ars = new HashSet<AdminRole>(); ???} ???public void add(AdminRole ar) ???{ ???????ars.add(ar); ???} ???@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; ???} ???@OneToMany(mappedBy="role")  --->  OneToMany指定了由AdminRole这个类来维护多对一的关联关系,mappedBy="role" ???@LazyCollection(LazyCollectionOption.EXTRA) ???public Set<AdminRole> getArs() ???{ ???????return ars; ???} ???public void setArs(Set<AdminRole> ars) ???{ ???????this.ars = ars; ???}}

AdminRole类:

@Entity@Table(name="t_admin_role")public class AdminRole{ ???private int id; ???private String name; ???private Admin admin; ???private Role role; ???@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; ???} ???@ManyToOne  --->  ManyToOne关联到Admin ???@JoinColumn(name="aid")   ???public Admin getAdmin() ???{ ???????return admin; ???} ???public void setAdmin(Admin admin) ???{ ???????this.admin = admin; ???} ???@ManyToOne  --->   ???@JoinColumn(name="rid") ???public Role getRole() ???{ ???????return role; ???} ???public void setRole(Role role) ???{ ???????this.role = role; ???}}

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

       Person p = new Person(); ???????????p.setName("xiaoluo"); ???????????session.save(p); ???????????????????????IDCard card = new IDCard(); ???????????card.setNo("1111111111"); ???????????card.setPerson(p); ???????????session.save(card);

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

hibernate关联映射注解

原文地址:https://www.cnblogs.com/yadongliang/p/8965091.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved