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

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

在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@GeneratedValuepublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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")  --->  指定外键的名字 pidpublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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@GeneratedValuepublic 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注解方式来配置映射关系的一些总结。

转载于:https://my.oschina.net/kt431128/blog/359977

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统Ubuntu(实验一二)

摘录&#xff1a;https://www.cnblogs.com/penglang14/p/10632360.html 实验一二1.1_小技巧1.2_ls查看目录命令1.3_cd切换目录命令1.4_查看文件内容命令(1)cat filename(2)more filename(3)head [-n] filename([]表示此内容可有可无)&#xff08;4&#xff09;wc命令确定行数、…

Redis 是如何执行的?

在以往的面试中&#xff0c;当问到一些面试者&#xff1a;Redis 是如何执行的&#xff1f;收到的答案往往是&#xff1a;客户端发命令给服务器端&#xff0c;服务端收到执行之后再返回给客户端。然而对于执行细节却「避而不谈」 &#xff0c;当继续追问服务器端是如何执行的&am…

java 枚举迭代_Java中的枚举和迭代器之间的区别

java 枚举迭代Java中的枚举与迭代器 (Enumeration vs Iterator in Java) Here, we will see how Enumeration differs from Iterator? 在这里&#xff0c;我们将看到Enumeration与Iterator有何不同&#xff1f; 1)枚举 (1) Enumeration) Enumeration is an interface which i…

ORA-14551: 无法在查询中执行 DML 操作

最近在调试一个带DML操作的函数时&#xff0c;一直不成功&#xff0c;在PL/SQL中测试时没问题&#xff0c;通过SQL语句调用函数时就不行了&#xff0c;刚开始一直没找到原因&#xff0c;后来无意间把 函数中捕获异常的代码注释掉&#xff0c;终于通过SQL调试时&#xff0c;弹出…

第五章I/O管理

I/O章节5.1.1I/O分类&#xff08;1&#xff09;按使用特性分&#xff08;2&#xff09;I/O设备按传输速率分类&#xff08;3&#xff09;I/O设备按信息交换的单位分5.1.2I/O控制器5.1.3I/O控制方式&#xff08;1&#xff09;程序直接控制方式&#xff08;轮询&#xff09;&…

阿里巴巴分布式服务框架 Dubbo

1.Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架&#xff0c;每天为2000 个服务提供3,000,000,000 次访问量支持&#xff0c;并被广泛应用于阿里巴巴集团的各成员站点。Dubbo自2011年开源后&#xff0c;已被许多非阿里系公司使用。 2.入门文档 http://alibaba.github.io/d…

列表使用与内部实现原理

列表类型 (List) 是一个使用链表结构存储的有序结构,它的元素插入会按照先后顺序存储到链表结构中,因此它的元素操作 (插入\删除) 时间复杂度为 O(1),所以相对来说速度还是比较快的,但它的查询时间复杂度为 O(n),因此查询可能会比较慢。 1 基础使用 列表类型的使用相对来…

c ++查找字符串_C ++类和对象| 查找输出程序| 套装1

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>using namespace std;class Sample {privateint A;privateint B;publicvoid init(){A 10;B 20;}publicvoid print(){cout << A << " " << B;}};int main(){Sample S;S.init…

Oracle 练习P297 131026 PL/SQL块程序

--1、编写一个PL/SQL块&#xff0c;输出所有员工的员工姓名&#xff0c;员工号、工资和部门号。beginfor v_emp in (select * from emp) loopdbms_output.put(员工姓名&#xff1a; || v_emp.ename);dbms_output.put(&#xff0c;员工号&#xff1a; || v_emp.empno);dbms_outp…

操作系统习题

操作系统习题习题一一、选择习题二一、选择二、综合题习题三一、选择题&#xff1f;二、简答题进程互斥遵循的四个原则&#xff1a;空闲让进、忙则等待、有限等待、让权等待重点习题四一、选择&#xff1f;&#xff1f;二、综合题死锁产生的 4 个必要条件是&#xff1a; &#…

WCF trace、log

1. 打开wcf配置&#xff1a; &#xff12;. enable trace &#xff0c; log 可以改变log路径&#xff1a; &#xff13;. 用 SvcTraceViewer.exe &#xff08;直接在c盘下搜索&#xff09; 查看 &#xff14;. 如果想自定义trace&#xff1a; catch(Exception ex) { Trace.Writ…

字典使用与内部实现原理

字典类型 (Hash) 又被成为散列类型或者是哈希表类型,它是将一个键值 (key) 和一个特殊的“哈希表”关联起来,这个“哈希表”表包含两列数据:字段和值。例如我们使用字典类型来存储一篇文章的详情信息,存储结构如下图所示: 同理我们也可以使用字典类型来存储用户信息,并且…

游标复习笔记

--while循环访问游标declarecursor cur_dept isselect * from dept;v_dept cur_dept%rowtype;beginopen cur_dept;fetch cur_dept into v_dept;while cur_dept%found loopdbms_output.put_line(v_dept.dname);fetch cur_dept into v_dept;end loop;close cur_dept;end;--retur…

操作系统中同步_操作系统中的经典同步问题

操作系统中同步经典同步问题 (Classical synchronization problem) In this section, we present a number of different philosopher synchronization problems that are important mainly because they are examples for a large class of concurrency- control problems. Th…

算法设计与分析复习第一二章(时间复杂度和蛮力法)

算法复习一二章第一章时间复杂度第二章蛮力法&#xff08;1&#xff09;查找问题顺序查找&#xff08;2&#xff09;排序问题选择排序起泡排序&#xff08;3&#xff09;组合问题0-1bag问题概述&#xff08;略&#xff09;&#xff08;4&#xff09;图问题哈密顿回路TSP问题&am…

有序集合使用与内部实现原理

有序集合类型 (Sorted Set) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。有序集合的存储元素值也是不能重复的,但分值是可以重复的。 当我们把学生的成绩存储在有序集…

Ubuntu12环境下Thin+rails(4)+ruby(2)+nginx+mysql 配置

Ubuntu12环境下Thinrails(4)ruby(2)nginxmysql配置1&#xff0e; 前提条件&#xff1a;已经正确安装了ubuntu12并且更行了源。2&#xff0e; 安装过程&#xff1a;2.1 安装ruby前的准备&#xff1a;1.1修改 /etc/apt/sources.list文件改为mirrors.163.com保存退出…

Oracle 游标的练习

--1、什么是游标&#xff1f;使用游标的基本步骤是什么&#xff1f; /*挡在PL/SQL块中执行查询语句&#xff08;SELECT&#xff09;和数据操纵语句&#xff08;DML&#xff09;时&#xff0c;Oracle会在内存中分配一个缓冲区&#xff0c;缓冲区中包含了处理过程的必需信息&…

集合使用与内部实现原理

集合类型 (Set) 是一个无序并唯一的键值集合。 之所以说集合类型是一个无序集合,是因为它的存储顺序不会按照插入的先后顺序进行存储,如下代码所示: 127.0.0.1:6379> sadd myset v2 v1 v3 #插入数据 v2、v1、v3 (integer) 3 127.0.0.1:6379> smembers myset #查询数…

parse 日期_日期parse()方法以及JavaScript中的示例

parse 日期JavaScript Date parse()方法 (JavaScript Date parse() method) parse() method is a Date class method, it is used to parse a given date string and returns the total number of milliseconds since 01st January 1970 (midnight) to given date string. pars…