hibernate annotation注解方式来处理映射关系
2017-10-30 15:02
483 查看
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用annotation的方式可以更简介,所以这里就简单记录下通过annotation来配置各种映射关系,在hibernate4以后已经将annotation的jar包集成进来了,如果使用hibernate3的版本就需要引入annotation的jar包。
最后只需要在hibernate.cfg.xml文件里面将该实体类加进去即可:
这样我们就可以写测试类来进行我们的CRUD操作了
ClassRoom类:
Student类:
Person类:
IDCard类:
注意 : 在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系。
Teacher类:
Course类:
Role类:
AdminRole类:
小技巧 :
通过hibernate来进行插入操作的时候,不管是一对多、一对一还是多对多,都只需要记住一点,在哪个实体类声明了外键,就由哪个类来维护关系,在保存数据时,总是先保存的是没有维护关联关系的那一方的数据,后保存维护了关联关系的那一方的数据
例:
inverse与cascade属性使用总结:
使用”inverse”这个属性时,要考虑清楚关系,不然你的系统就会有大的性能问题,关系一般由”多方”维护,当遇到”多对多”时怎么办,其实多对多久是两个”一对多”,随意设置一 方”inverse”为”true”就可以了,不要两方都设置或都不设置。而使用”cascade”属性时,主对象(一 方)一般设置为”all”,而多方不建议设置包含delete操作的选项,建议设置多方为”save-update”,这是因为你删除一方,多方已经没有 存在的意义了,而删除多方不能代表一方没意义了(例如,消费者和订单)。最后,“cascade”操作的是两张表的记录或两端的对象, 而”inverse”操作的是两张表的关系或两个对象的关系。
Hibernate注解关系映射:(注意:在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系。)
Hibernate Annotation关系映射的几种类型映射用法及使用方法(说明:以前实例的实体是user和role,主键分别是userid和roleid)
1)一对一外键关联映射(单向)
@OneToOne(cascade=CascadeType.ALL) //一对一外键关联,使用@OneToOne,并设置了级联操作
@JoinColumn(name=”userid”,unique=true) //@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id。外键的值是唯一的(unique),不可重复,与另一类的主键一直
2)一对一外键关联映射(双向)
@OneToOne(mappedBy=” role”,cascade=CascadeType.ALL) //一对一双向关联关系,使用@OneToOne。注意:需要加上mappedBy=”role”,如果不加上的话,role 也会生成一个外键(user_id),mappedby=”role”需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性
//规律:只有是双向关联关系,都加上mappedby,cascade=CascadeType.ALL级联
3)一对一主键关联映射(不重要)
在实际中很少用,使用注解@PrimaryKeyJoinColumn,意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了
4)多对一关联映射
多端配置
@ManyToOne(targetEntity=role.class) //多对一注解@ManyToOne;targetEntity指定了关联对象
@JoinColumn(name=”userid”) //@JoinColumn(name=”userid”)指定生产的外键的字段名,默认是org_id
5)一对多关联映射(单向)
@OneToMany //一对多注解@OneToMany(单向),如果只写@OneToMany的话,hibernate会建一张中间表来维护他们之间的关系
@JoinColumn(name=”roleid”) //加上@JoinColumn(name=”roleid”),则不会建中间表,他会在多的一端加上外键roleid,来维护他们之间的关系
6)一对多关联映射(双向)(多的一端维护关系)
一端配置
@OneToMany(mappedBy=”role”) //一对多双向,在一的一端中设置mappedBy,说明多的一端为主导
@JoinColumn(name=”roleid”) //如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
@LazyCollection(LazyCollectionOption.EXTRA) —> LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能
多端配置
@ManyToOne(fetch=FetchType.LAZY) —> ManyToOne指定了多对一的关系,fetch=FetchType.LAZY属性表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载) //一对多双向
@JoinColumn(name=” roleid “) //需要指定外键与一的一端给的外键名称一致,@JoinColumn(name=” roleid “),也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键
7)多对多关联映射(单向)
@ManyToMany //多对多映射:注解@ManyToMany(单向),默认情况下,hibernate会自动的创建一张中间表来维护多对多关系
默认中间表的名称 :user_role中间表,字段的名称user_id role_id,如果想更换表名和字段名称,注解如下:
@JoinTable(name=”t_u_r”,joinColumns={@JoinColumn(name=”u_id”)},inverseJoinColumns={@JoinColumn(name=”r_id”)})
8)多对多关联映射(双向)
user端
@ManyToMany //多对多映射:注解@ManyToMany(单向);默认情况下,hibernate会自动的创建一张中间表,来维护多对多关系;默认中间表的名称 :user_role中间表,字段的名称user_id role_id
如果想更换表名和字段名称,注解如下:
@JoinTable(name=”t_u_r”,joinColumns={@JoinColumn(name=”u_id”)},inverseJoinColumns={@JoinColumn(name=”r_id”)}) //@JoinTable(name=”t_u_r”),指定中间表的表名;joinColumns={@JoinColumn(name=”u_id”)},指定当前对象的外键;inverseJoinColumns={@JoinColumn(name=”r_id”)},指定关联对象的外键
role端
@ManyToMany(mappedBy=”role”) //多对多,双向关联映射
一、单对象操作
如果我们当前这个bean要设置成实体对象,就需要加上Entity这个注解 hljs java"> @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 116d9 (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对象以及一个Course对象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,所以在对方外键的名称就是 cid,inverseJoinColumns也是一个 //@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)//LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时, //只会发出一条 count(*)的语句,提高性能 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)//LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时, //只会发出一条 count(*)的语句,提高性能 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 //ManyToOne关联到Role @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);
inverse与cascade属性使用总结:
使用”inverse”这个属性时,要考虑清楚关系,不然你的系统就会有大的性能问题,关系一般由”多方”维护,当遇到”多对多”时怎么办,其实多对多久是两个”一对多”,随意设置一 方”inverse”为”true”就可以了,不要两方都设置或都不设置。而使用”cascade”属性时,主对象(一 方)一般设置为”all”,而多方不建议设置包含delete操作的选项,建议设置多方为”save-update”,这是因为你删除一方,多方已经没有 存在的意义了,而删除多方不能代表一方没意义了(例如,消费者和订单)。最后,“cascade”操作的是两张表的记录或两端的对象, 而”inverse”操作的是两张表的关系或两个对象的关系。
Hibernate注解关系映射:(注意:在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系。)
Hibernate Annotation关系映射的几种类型映射用法及使用方法(说明:以前实例的实体是user和role,主键分别是userid和roleid)
1)一对一外键关联映射(单向)
@OneToOne(cascade=CascadeType.ALL) //一对一外键关联,使用@OneToOne,并设置了级联操作
@JoinColumn(name=”userid”,unique=true) //@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id。外键的值是唯一的(unique),不可重复,与另一类的主键一直
2)一对一外键关联映射(双向)
@OneToOne(mappedBy=” role”,cascade=CascadeType.ALL) //一对一双向关联关系,使用@OneToOne。注意:需要加上mappedBy=”role”,如果不加上的话,role 也会生成一个外键(user_id),mappedby=”role”需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性
//规律:只有是双向关联关系,都加上mappedby,cascade=CascadeType.ALL级联
3)一对一主键关联映射(不重要)
在实际中很少用,使用注解@PrimaryKeyJoinColumn,意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了
4)多对一关联映射
多端配置
@ManyToOne(targetEntity=role.class) //多对一注解@ManyToOne;targetEntity指定了关联对象
@JoinColumn(name=”userid”) //@JoinColumn(name=”userid”)指定生产的外键的字段名,默认是org_id
5)一对多关联映射(单向)
@OneToMany //一对多注解@OneToMany(单向),如果只写@OneToMany的话,hibernate会建一张中间表来维护他们之间的关系
@JoinColumn(name=”roleid”) //加上@JoinColumn(name=”roleid”),则不会建中间表,他会在多的一端加上外键roleid,来维护他们之间的关系
6)一对多关联映射(双向)(多的一端维护关系)
一端配置
@OneToMany(mappedBy=”role”) //一对多双向,在一的一端中设置mappedBy,说明多的一端为主导
@JoinColumn(name=”roleid”) //如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
@LazyCollection(LazyCollectionOption.EXTRA) —> LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能
多端配置
@ManyToOne(fetch=FetchType.LAZY) —> ManyToOne指定了多对一的关系,fetch=FetchType.LAZY属性表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载) //一对多双向
@JoinColumn(name=” roleid “) //需要指定外键与一的一端给的外键名称一致,@JoinColumn(name=” roleid “),也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键
7)多对多关联映射(单向)
@ManyToMany //多对多映射:注解@ManyToMany(单向),默认情况下,hibernate会自动的创建一张中间表来维护多对多关系
默认中间表的名称 :user_role中间表,字段的名称user_id role_id,如果想更换表名和字段名称,注解如下:
@JoinTable(name=”t_u_r”,joinColumns={@JoinColumn(name=”u_id”)},inverseJoinColumns={@JoinColumn(name=”r_id”)})
8)多对多关联映射(双向)
user端
@ManyToMany //多对多映射:注解@ManyToMany(单向);默认情况下,hibernate会自动的创建一张中间表,来维护多对多关系;默认中间表的名称 :user_role中间表,字段的名称user_id role_id
如果想更换表名和字段名称,注解如下:
@JoinTable(name=”t_u_r”,joinColumns={@JoinColumn(name=”u_id”)},inverseJoinColumns={@JoinColumn(name=”r_id”)}) //@JoinTable(name=”t_u_r”),指定中间表的表名;joinColumns={@JoinColumn(name=”u_id”)},指定当前对象的外键;inverseJoinColumns={@JoinColumn(name=”r_id”)},指定关联对象的外键
role端
@ManyToMany(mappedBy=”role”) //多对多,双向关联映射
相关文章推荐
- hibernate annotation注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- Hibernate注解方式处理映射关系
- hibernate annotation注解方式来处理映射关系
- hibernate注解方式来处理映射关系
- hibernate annotation注解方式来处理映射关系
- Hibernate注解方式处理实体映射关系
- Hibernate一对一主键关联(基于annotation注解方式)
- Hibernate中,One2Many和Many2One的双向映射关系的基于注解Annotation实现方式
- hibernate annotation注解方式来处理映射关系
- springmvc+spring+hibernate 整合 annotation(全注解)方式
- SS6.2_Hibernate_Hibernate_IdStrategyAnnotation 主键生成策略uuid Annotation注解的配置方式
- hibernate注解方式来处理映射关系
- spring与hibernate整合配置基于Annotation注解方式管理实务
- Hibernate一对一主键关联(基于annotation注解方式)
- Hibernate_003_在MyEclipse中配置部署(注解方式Annotation)