剑指架构师系列-Hibernate需要掌握的Annotation
1、一对多的关系配置
@Entity @Table(name = "t_order") public class Order { @Id @GeneratedValue private int id; private String name; /* * 该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作, * 而且这种关系是递归调用的。举个例子:Order 和OrderItem有级联关系,那么删除Order时将同时删除它所对 * 应的OrderItem对象。而如果OrderItem还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。 * * CascadeType.PERSIST(级联新建) 貌似只能在关联对象单独保存后才可以 * CascadeType.REMOVE(级联删除) 有级联的效果 * CascadeType.REFRESH(级联刷新) * CascadeType.MERGE(级联更新) * CascadeType.ALL(选择全部四项) * * 级联的意思是允许你进行某个级联操作,例如是级联删除时,进行级联新建是不允许的 * * mappedBy 属性值是多方中定义的一方的变量名,形成双向关系时需要定义 */ @OneToMany( cascade ={ CascadeType.ALL}, fetch = FetchType.EAGER, mappedBy = "order", targetEntity = OrderItem.class ) private Set<OrderItem> orderItems = new HashSet<OrderItem>(); // 省略 }
// 通过@Entity注解将一个类声明为一个实体bean // 通过 @Table注解可以为实体bean映射指定表,name属性表示实体所对应表的名称,如果没有 // 定义 @Table,那么系统自动使用默认值:实体的类名(不带包名) @Entity @Table(name = "t_orderitem") public class OrderItem implements java.io.Serializable { private static final long serialVersionUID = 1L; // 用于标记属性的主键 // @Id // 表示持久化属性所映射表中的字段,如果属性名与表中的字段名相同,则可以省略@Column注解, // 另外有两种方式标记,一是放在属性前,另一种是放在getter方法前 // @Column(name = "EMPLOYEE_ID") /* * 表生成器。将当前主键的值单独保存到一个数据库表中,主键的值每次都是从指定的表中查询来获得, * 这种生成主键的方式是很常用的。这种方法生成主键的策略可以适用于任何数据库,不必担心不同数 * 据库不兼容造成的问题。推荐这种方式管理主键,很方便,集中式管理表的主键,而且更换数据 * 库不会造成很大的问题。 */ /* @TableGenerator( name="tab-store", // 该表主键生成策略的名称,可以自定义,它被引用在@GeneratedValue中设置的"generator"值中 table="GENERATOR_TABLE", // 表生成策略所持久化的表名,就是管理其它表主键的表 pkColumnName = "G_KEY", // 表生成器中的列名,用来存放其它表的主键键名,这个列名是与表中的字段对应的 pkColumnValue="EMPLOYEE_PK", // 实体表所对应到生成器表中的主键名,可以自定义 // 表生成器中的列名,实体表主键的下一个值,假设EMPLOYEE表中的EMPLOYEE_ID最大为2,那么此时,生成器表中与实体表主键对应的键名值则为3 valueColumnName = "G_VALUE", allocationSize=1 // 表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50 ) */ /* * 定义主键生成策略,这里因为使用的是TableGenerator,所以,主键的生成策略为GenerationType.TABLE, * 生成主键策略的名称则为前面定义的”tab-store”。 * * strategy = GenerationType.AUTO或是strategy = GenerationType.SEQUENCE,采用SEQUENCE序列是因为Oracle数据中不支持identity自动增长, * 要想使用它,还得在数据库中创建一个序列。 * * 采用的是SQL Server作为数据库时,如果想使用AUTO或是IDENTITY生成策略,则一定要对主键加上identity标识,如identity(1,1)。 * 不过对于AUTO来说,是根据不同的数据库选择最合适的自增主键生成策略。如果使用MySQL,则主键要定义AUTO_INCREMENT。 * 如果是Oracle,则要创建Sequence来实现自增。 * * */ @Id // @Column(name = "id") // @TableGenerator(name = "tab-store", table = "GENERATOR_TABLE", pkColumnName = "G_KEY", pkColumnValue = "ORDERITEM_PK", valueColumnName = "G_VALUE", allocationSize = 1) // @GeneratedValue(strategy = GenerationType.TABLE, generator = "tab-store") @GeneratedValue private Integer id; private String name; /* optional属性是定义该关联类是否必须存在,值为false时,关联类双方都必须存在,如果关系被维护端不存在, 查询的结果为null。值为true时,关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端 中指向关系被维护端的属性为null。optional属性的默认值是true。 optional属性实际上指定关联类与被关联 类的join查询关系,如optional=false时join查询关系为inner join, optional=true 时join 查询关系为left join。 */ @ManyToOne( cascade ={ CascadeType.ALL}, optional = false, fetch=FetchType.LAZY, targetEntity=Order.class ) @JoinColumn(name = "order_id")// 在关系被维护端需要建立外键列指向关系维护端的主键列 private Order order; // ManyToOne表示多个Employee对应与一个Department,dept_id字段加入Employee表中 // 省略 }
2、多对多的关系配置
@Entity @Table(name = "Teacher") public class Teacher implements java.io.Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; @Column(name = "name", length = 100) // 对应数据库中表的列,最大长度是100 private String name; // @ManyToMany注释表示Teacher是多对多关系的一端。 /* * @JoinTable描述了多对多关系的数据表关系。 * name属性指定中间表名称, joinColumns定义中间表与Teacher表的外键关系。 * inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系。 */ @JoinTable( name="teacher_student", joinColumns = {@JoinColumn(name="teacher_id")}, inverseJoinColumns={@JoinColumn(name="student_id")} ) @ManyToMany( cascade = CascadeType.ALL, fetch = FetchType.LAZY ) private Set<Student> students = new HashSet<Student>(); // 省略 }
@Entity @Table(name = "Student") public class Student implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; // @ManyToMany注释表示Student是多对多关系的一边,mappedBy属性定义了Student为双向关系的维护端 // 有且仅有一个实体指定mappedBy属性 // 这个teachers属性会在数据库中生成对应的teachers_id字段 @ManyToMany( cascade = CascadeType.ALL, mappedBy = "students" ) private Set<Teacher> teachers = new HashSet<Teacher>(); // 省略 }
3、Hibernate中继承关系的使用
Hibernate的继承映射包含了三种不同的策略:
- 每簇类使用一个表
- 每个子类一个表
- 每个具体内一个表(有限制)
JPA同样支持3种类型的继承形式:
1.Single Table Strategy ,单表策略,一张表包含基类与子类的所有数据,很多情况下都是采用这样的冗余设计,通过一个discriminator来区分
2.Table Per Class Strategy ,每个子类对应一张表,每张表都拥有基类的属性
3.Join Strategy ,仍然是每个子类对应一张表,但此表中不包含基类的属性,仅仅是此子类的扩展属性,共享基类的属性
(1)单表策略
// 采用单表策略,通过@DiscriminatorColumn确定了标志值的字段和类型 // @DiscriminatorValue注释,当Animal类型的Entity存入数据库时,JPA将自动把animal的值赋给animalType字段 @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="animalType") @DiscriminatorValue("animal") public class Animal { private int id; private String name; @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; } } @Entity @DiscriminatorValue("cat") public class Cat extends Animal { private String catName; // 省略 } @Entity @DiscriminatorValue(value="dog") public class Dog extends Animal{ private String dogName; // 省略 }
(2)Table per Class
采用Table Per Class策略的话,每个子类都将单独建表,并且都独立拥有基类中的所有属性,互相之间不共享
@Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class Animal { private int id; private String name; @Id @GeneratedValue(strategy=GenerationType.TABLE) 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; } } @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class Cat extends Animal { private String catName; public String getCatName() { return catName; } public void setCatName(String catName) { this.catName = catName; } } @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public class Dog extends Animal{ private String dogName; public String getDogName() { return dogName; } public void setDogName(String dogName) { this.dogName = dogName; } }
(3)Join策略
每个子类同样独立建表,基类也独立建表,只不过所有的子类的表中只有扩展属性,他们共享基类的表
@Entity @Inheritance(strategy=InheritanceType.JOINED) public class Animal { private int id; private String name; @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; } } @Entity @PrimaryKeyJoinColumn(name="catId") public class Cat extends Animal { private String catName; public String getCatName() { return catName; } public void setCatName(String catName) { this.catName = catName; } } @Entity @PrimaryKeyJoinColumn(name="dogId") public class Dog extends Animal{ private String dogName; public String getDogName() { return dogName; } public void setDogName(String dogName) { this.dogName = dogName; } }
参考文章:
1、http://www.360doc.com/content/11/0906/22/1542811_146326974.shtml
剑指架构师系列-Hibernate需要掌握的Annotation的更多相关文章
- 剑指架构师系列-spring boot的logback日志记录
Spring Boot集成了Logback日志系统. Logback的核心对象主要有3个:Logger.Appender.Layout 1.Logback Logger:日志的记录器 主要用于存放日志 ...
- 剑指架构师系列-持续集成之Maven实现项目的编译、发布和部署
Maven组织项目进行编译.部署 Maven项目基本的结构说明如下: mazhi // 控制所有荐的编译.部署.发布 mazhi-app-parent // 项目的父项目,有一些公共的设置可以被子 ...
- 剑指架构师系列-持续集成之Maven+Nexus+Jenkins+git+Spring boot
1.Nexus与Maven 先说一下这个Maven是什么呢?大家都知道,Java社区发展的非常强大,封装各种功能的Jar包满天飞,那么如何才能方便的引入我们项目,为我所用呢?答案就是Maven,只需要 ...
- 剑指架构师系列-tomcat6通过IO复用实现connector
由于tomcat6的配置文件如下: <Connector port="80" protocol="org.apache.coyote.http11.Http11Ni ...
- 剑指架构师系列-Struts2构造函数的循环依赖注入
Struts2可以完成构造函数的循环依赖注入,来看看Struts2的大师们是怎么做到的吧! 首先定义IBlood与BloodImpl类: public interface IBlood { } pub ...
- 剑指架构师系列-tomcat6通过伪异步实现connector
首先在StandardService中start接收请求的线程,如下: synchronized (connectors) { for (int i = 0; i < connectors.le ...
- 剑指架构师系列-Struts2的缓存
Struts2的缓存中最重要的两个类就是ReferenceMap与ReferenceCache.下面来解释下ReferenceCache中的get()方法. public V get(final Ob ...
- 剑指架构师系列-InnoDB存储引擎、Spring事务与缓存
事务与锁是不同的.事务具有ACID属性: 原子性:持久性:由redo log重做日志来保证事务的原子性和持久性,一致性:undo log用来保证事务的一致性隔离性:一个事务在操作过程中看到了其他事务的 ...
- 剑指架构师系列-Linux下的调优
1.I/O调优 CentOS下的iostat命令输出如下: $iostat -d -k 1 2 # 查看TPS和吞吐量 参数 -d 表示,显示设备(磁盘)使用状态:-k某些使用block为单位的列强制 ...
随机推荐
- android: 内容提供器简介
我们学了 Android 数据持久化的技术,包括文件存储.SharedPreferences 存 储.以及数据库存储.不知道你有没有发现,使用这些持久化技术所保存的数据都只能在当 前应用程序中访问.虽 ...
- nload 实时网速查看
nload eth0 -u K Device eth0 [192.168.0.33] (1/1):=================================================== ...
- 493萬Gmail用戶的賬號密碼遭洩露,Google否認自己存在安全漏洞
最近,大公司在互聯網信息安全問題上狀況頻出.上週,蘋果因iCloud被黑客攻擊而導致大量明星私照外洩,著實是熱鬧了一陣.而Google也來湊熱鬧了.據俄羅斯媒體CNews消息,近493萬Gmail用戶 ...
- 使用 Aircrack-ng 破解 WEP 和 WPA/WPA2 加密的 Wi-Fi 密码。(转)
1.首先请不要使用此方法去搞破坏,去蹭Wi-Fi,因为不装逼地说,我认为技术本身的价值很大,尤其是在学习这个技术的过程中解决遇到的问题,当经过重重困难最后终于成功之后的喜悦又怎么能拿去蹭网呢.我在此过 ...
- 微信小程序实例-获取当前的地理位置、速度
微信小程序官方文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/location.html JS代码 //index.js //获取应用实例 var a ...
- ASP lable标签显示过长,自动换行。
<asp:Label ID="lab_BeforPostR" runat="server" CssClass="labSty" Wid ...
- linux red hat 安装svn
安装步骤如下: 1.yum install subversion 2.输入rpm -ql subversion查看安装位置,如下图: 我们知道svn在bin目录下生成了几个二进制文件. 输入 ...
- 【规范】javascript 变量命名规则
javascript 有三大经典的变量命名法:匈牙利命名法,驼峰式命名法和帕斯卡命名法.今天主要介绍下这三种命名方式. 匈牙利命名法 语法 变量名 = 类型 + 对象描述 类型指变量的类型 对象描述指 ...
- .net微信公众号开发——模板消息
作者:王先荣 本文介绍微信公众号中的模板消息,包括以下内容:(1)TemplateMessage类简介:(2)设置所属行业:(3)获得模板id:(4)发送模板消息:(5)接收推送模板消息发送结果 ...
- mongodb_查询操作使用_条件查询、where子句等(转)
<?php /* mongodb_查询操作使用_条件查询.where子句等(转并学习) 1.find()/findOne() mongodb数据库的查询操作即使用find()或者findO ...