Hibernate基于注解的配置样例
实体类上的常用注解
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Entity ( name = "ChristmasTree" ) @Table ( name = "T_CRISMS_TREE" ) //给自动生成的表添加注释 @org.hibernate.annotations.Table ( appliesTo = "T_CRISMS_TREE", comment = "圣诞树" ) @Cacheable //JPA注解,表示该类型的实体支持缓存 //启用二级缓存时有意义,指定Hibernate缓存策略、存放区域 @Cache ( usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache" ) public class ChristmasTree { //集合属性的缓存策略必须单独配置 @Cache ( usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache" ) private List branches; } |
使用注解方式进行对象-数据库映射时,应当以JPA注解为主,仅Hibernate特有的功能则使用其私有的注解类。
简单主键和简单属性映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//简单的主键映射 @Id //该注解指明此实体的标识符属性,对应了关系型数据库的主键 @Column ( name = "ID", columnDefinition = "int(11) comment '主键'" ) private Integer id; //UUID方式的主键生成器配置,其它任何自定义的主键生成器可以依样扩展 @Id @Column ( name = "ID", columnDefinition = "varchar(36) comment '主键,36位UUID'" ) @GeneratedValue ( generator = "uuid" ) @GenericGenerator ( name = "uuid", strategy = "org.hibernate.id.UUIDGenerator" ) private String id; //可以指定普通属性的延迟加载 @Basic ( fetch = FetchType.EAGER, optional = true ) @Column ( name = "BUILD_COST", columnDefinition = "decimal(10,2) comment '建造费用'" ) private BigDecimal buildCost; //时间映射 //只能用于java.util.Date或者java.util.Calendar,用于表示日期、时间或者时间戳 @Temporal ( TemporalType.TIMESTAMP ) @Column ( name = "BUILD_TIME", columnDefinition = "datetime comment '建造时间'" ) private Date buildTime; //大字段映射 @Lob @Column ( name = "REMARK", columnDefinition = "longtext comment '圣诞树备注信息'" ) private String remark; //枚举类型映射 @Enumerated ( EnumType.ORDINAL ) //根据枚举元素的声明顺序,从0开始 @Column ( name = "STATUS", columnDefinition = "tinyint comment '状态'" ) private Status status; //乐观并发控制用列 @Version @Column ( name = "VERSION" ) public Integer version; |
复合主键映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//复合主键映射 @Embeddable public class TreeId { @Column ( name = "ORG_ID" ) private Integer org; @Column ( name = "SEQ_ID" ) private Integer seq; } //可以覆写默认映射 @EmbeddedId @AttributeOverride ( name = "seq", column = @Column (name = "SEQ_NO" ) ) private TreeId treeId; //复合主键中甚至可以包含实体类 @Embeddable public class TreeId { @ManyToOne @JoinColumn (name = "ORG_ID", referencedColumnName="ID" ) private Org org; @Column ( name = "SEQ_ID" ) private Integer seq; } //也可以使用多个属性作为主键 public class ChristmasTree { @Id @OneToOne @JoinColumn (name = "ORG_ID", referencedColumnName="ID" ) private Org org; @Id @Column ( name = "SEQ_ID" ) private Integer seq; } |
嵌入式(embeddable)对象映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
//嵌入式对象映射,也叫组件映射 @Embeddable public class Country { @ManyToOne @JoinColumn (name = "ORG_ID", referencedColumnName="ID" ) private Org adminOrg; private String name; } @Embeddable public class Address implements Serializable { String city; Country nationality; // 递归嵌入 } @Entity public class Person implements Serializable { private Address homeAddress; //由于Address声明为@Embeddable,所以自动进行组件映射 @Embedded @AttributeOverrides( { //进行映射覆写 @AttributeOverride ( name = "adminOrg", column = @Column ( name = "ADMIN_ORG_ID" ) ), @AttributeOverride ( name = "name", column = @Column ( name = "COUNTRY_NAME" ) ) } ) Country bornIn; } //嵌入式对象的集合也可以被映射,注意子表不需要主键,也没有实体地位 @Embeddable public class Address implements Comparable<Address> { @Column ( name = "ZIP_CODE" ) private Integer zip; @Column ( name = "STREET" ) private String street; } @Entity @Table ( name = "T_PERSON" ) public class Person { @Id private Integer id; @ElementCollection @CollectionTable ( name = "T_ADDRESS", joinColumns = @JoinColumn ( name = "PERSON_ID" ) ) //两种定义集合元素顺序的方法: @Sort ( type = SortType.NATURAL ) @OrderBy ( "zip DESC" ) private Set<Address> addresses; } |
关联映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
//基于主键共享的一对一关联 public class ChristmasTree { @Id private Long id; @OneToOne ( cascade = CascadeType.ALL, optional = false ) @MapsId //共享主键 private TreeRoot root; } public class TreeRoot { @Id private Long id; } //基于外键的多对一关联 @ManyToOne ( fetch = FetchType.EAGER,//默认非延迟加载 optional = false //是否可选,如果设置为真则允许为空,默认否 ) @JoinColumn ( /*本表外键列*/ name = "ROOM_ID", columnDefinition = "varchar(36) comment '所在房间'" , referencedColumnName = "NOT_PK_COLUMN" //可以指定不和目标表的主键,而是其它唯一键列进行映射 ) @NotFound ( action = NotFoundAction.IGNORE ) //当对应数据找不到的时候,是否抛出异常 @OnDelete ( action = OnDeleteAction.CASCADE ) //父表ROOM的数据被删除时,在数据库级别自动级联删除当前表的相关数据 @ForeignKey (name = "FK_CRISMS_TREE_ROOM" ) //指定外键名称 private Room room; //基于映射表的多对一关联 @ManyToOne @JoinTable ( name = "T_M_CRISMS_TREE_ROOM", joinColumns = @JoinColumn ( name = "TREE_ID" ), inverseJoinColumns = @JoinColumn ( name = "ROOM_ID" ) ) private Room room; //多对多关联 @ManyToMany @JoinTable ( /*映射表*/ name = "T_M_CRISMS_TREE_CHILD", joinColumns = @JoinColumn ( name = "TREE_ID" ), inverseJoinColumns = @JoinColumn ( name = "CHILD_ID" ) ) private Set children; //一对多映射:有序集合 @OneToMany ( fetch = FetchType.LAZY,//延迟加载(直到第一次访问时才加载),集合默认真 orphanRemoval = true,//是否在目标实体从集合中移除时,对其进行删除 targetEntity = AbstractFurit.class,//目标实体,不使用泛型时,必须指定 cascade = CascadeType.ALL //在进行各种增删改操作时,关联的目标实体是否也要进行同样的操作 ) @JoinColumn ( /*子表外键列*/name = "TREE_ID", columnDefinition = "varchar(36) comment '该水果挂在哪棵树上'" ) //集合属性可以设置(在Java中的)排序方式 @Sort ( type = SortType.NATURAL ) private SortedSet furits; //如果不需要支持排序,可以使用Set接口 //一对多映射:列表 @OneToMany @JoinColumn ( name = "TREE_ID", columnDefinition = "varchar(36) comment '该树枝是哪棵树的'" ) //子表索引列必须为整数,从0开始,不得跳跃 @IndexColumn ( name = "ORD", columnDefinition = "int(11) comment '序号'" ) @Cache ( usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache" ) private List branches; //任意多态映射,关联目标不再同一个实体层次下 @AnyMetaDef ( //该元数据可以在包上定义,以便重用 name = "adminMetaDef", idType = "string", //目标实体的标识符类型 metaType = "integer", //元数据列的数据类型 metaValues = { @MetaValue ( value = "1", targetEntity = Child.class ), @MetaValue ( value = "2", targetEntity = Org.class ) } ) @Any ( metaDef = "adminMetaDef", metaColumn = @Column ( name = "ADMIN_TYPE", columnDefinition = "int(11) comment '管理者类别:1孩子,2机构'" ) ) @JoinColumn ( name = "ADMIN_ID", columnDefinition = "varchar(36) comment '圣诞树主管理者'" ) private Admin mainAdmin; //任意多态集合映射 @ManyToAny ( metaDef = "adminMetaDef", metaColumn = @Column ( name = "ADMIN_TYPE" ) ) @JoinTable ( name = "T_M_CRISMS_TREE_ADMIN", //必须使用映射表,以便指定元数据列 joinColumns = @JoinColumn ( name = "TREE_ID" ), inverseJoinColumns = @JoinColumn ( name = "ADMIN_ID" ) ) private Set admins; |
继承映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//*** 整个实体层次使用单张表 @Entity ( name = "AbstractFurit" ) @Table ( name = "T_FURIT" ) @Inheritance ( strategy = InheritanceType.SINGLE_TABLE ) @DiscriminatorColumn ( name = "TYPE_ID", columnDefinition = "int(11) comment '水果类型'" ) public class AbstractFurit implements IFurit, Serializable {} @Entity ( name = "Apple" ) @DiscriminatorValue ( "1" ) public class Apple extends AbstractFurit {} //*** 公共属性放在一张表,子类中的属性放在各自单独表中 @Entity ( name = "AbstractFurit" ) @Table ( name = "T_FURIT" ) @Inheritance ( strategy = InheritanceType.JOINED ) public class AbstractFurit implements IFurit, Serializable { @id private Integer id; } @Entity ( name = "Apple" ) @Table ( name = "T_APPLE" ) @PrimaryKeyJoinColumn ( name = "FURIT_ID" ) public class Apple extends AbstractFurit {} //*** 每个子类使用一张表 @Entity ( name = "AbstractFurit" ) @Inheritance ( strategy = InheritanceType.TABLE_PER_CLASS ) public class AbstractFurit implements IFurit, Serializable {} |
其它注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//领域驱动风格的建模时,实体的瞬时属性,必须同时使用注解和关键字 @Inject @Transient //表示该字段不支持持久化 @JsonIgnore //结合JacksonJSON使用,忽略无业务意义的字段 private transient ServiceHelper service; //指定transient关键字,不会在Java串行化时尝试串行化该字段 //公式列,可以使用SQL表达式定义一个只读的列,在数据库端完成计算 @Formula("length * height * width") private long volume; // 一个或者多个字段可以作为自然键的组成,具有惟一性非空约束 @NaturalId ( mutable = true ) //可以配置自然键是否可变 @Column ( name = "COLOR", columnDefinition = "varchar(50) comment '颜色'" ) private String color; //定义一个用于继承的父类,该父类不具有实体资格,但是可以定义若干公用的映射属性 @MappedSuperclass public class Admin { @Column ( name = "NAME" ) private String name; } @Entity ( name = "Child" ) //可以在上述父类的某个作为实体层次根的子类上,对属性(AttributeOverride)、关联映射(AssociationOverride)进行覆写 @AttributeOverride ( name = "name", column = @Column ( name = "CHILD_NAME" ) ) public class Child extends Admin {} //把一个实体映射到多张表上,这种映射方式支持在实体层次(例如单表/类层次)中的某个分支上使用 @SecondaryTables ( { @SecondaryTable ( name = "T_CRISMS_TREE_OTHER", pkJoinColumns = { @PrimaryKeyJoinColumn ( name = "cat_id", referencedColumnName = "id" ) } ), @SecondaryTable ( name = "T_CRISMS_TREE_OTHER_2" ) } ) public class ChristmasTree implements Serializable { @Column ( table = "T_CRISMS_TREE_OTHER" ) //指定某个列存放在哪张表上 private String otherInfo; } |
Leave a Reply