hibernate 生成注释的注释该如何使用?每一个注释代表什么意思

酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
对于Java开发人员,Hibernate 3 annotations提供了非常好的方式来展示域分层。你可以很轻松的通过Hibernate自动生成需要的数据库架构,带有完整的SQL脚本。然而回到现实世界,你还需要考虑到,有时数据库管理员所使用的模糊的命名惯例。本文中,&Java Power Tools&的作者John Ferguson Smart将告诉你如何通过Hibernate自动生成数据库架构,而且还方便数据库管理。
Hibernate 3 注释有一种强大的持久管理数据库的方式,运用这些注释,你不需要为XML映射文件而费心,你可以设置成默认,由系统完成,从而减少了大量需要维护的代码。Hibernate提供了强大的自动生成数据库架构的工具,因此Hibernate可以自动完成生成和更新数据库架构的操作,你也无需担心那些不可思议的SQL脚本。
第一步:更新数据库架构
用Hibernate自动更新数据库架构很容易,你所需要做的只是设置好Hibernate.hbm2ddl.auto,如示例1:
&hibernate-configuration&
&session-factory&
&property name=&hibernate.dialect&&org.hibernate.dialect.Oracle10gDialect&/property&
&property name=&hibernate.hbm2ddl.auto&&create-drop&/property&
&!-- Persistent classes --&
&mapping class=&com.mycompany.myapp.domain.Client&/&
&mapping class=&com.mycompany.myapp.domain.Order&/&
&/session-factory&
&/hibernate-configuration&
设置它的属性为&create-drop&,那么每次启动应用程序都会产生新的数据库,这对集成测试很有用,但是有些情况下却不需要。另一方面,如果你设置这个值是为了更新,如果不存在数据库,Hibernate只会自动创建数据库,并更新与当前域模型匹配的所有表。
现在,在默认情况下,Hibernate将创建一套与Java类很相似的表及字段,从Java开发者的角度来看这样刚好符合要求。考虑下面的例子:
示例2:A simple persistent class
@Entitypublic class Client implements Serializable {
@GeneratedValue(strategy = GenerationType.AUTO)
private String firstN
private String lastN
...}这个类中,Hibernate在默认情况下创建SQL模式,可以继续看示例3。示例3:
create table Client (
id bigint generated by default as identity (start with 1),
firstName varchar(255),
lastName varchar(255),
primary key (id)
旧的命名惯例
数据库的惯例约定有相当充分的理由存在,但是在任何情况下DBA常常要保守一些。开发者该如何做呢?
一个简单的解决办法是使用名字特征:@Entity、@Column注释,这种方法优于默认情况下,如示例4:
@Entity(name=&T_CLIENT&)public class Client implements Serializable {
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name=&CLIENT_ID&)
@Column(name=&FIRST_NAME&)
private String firstN
@Column(name=&LAST_NAME&)
private String lastN
...}这样很有作用,但是会有些麻烦,你不得不有更多的表。实际上,你必须对每个表及字段都做这样的操作。有没有更好的方法呢?当然,你可以在Hibernate会话中定义命名策略集合取代默认值。这样的话你得写一个类,说明Hibernate如何定义表及字段名。从ImprovedNamingStrategy类开始是一个恰当位置,用下划线转换类名,如SomeDomainEntity,转换成some_domain_entity。在启动Hibernate会话时需准备这个类。如果你用Spring,需简化创建命名策略bean并为命名策略集合提供所创建的命名策略。示例5就是Spring配置的典型说明:示例5:&bean id=&sessionFactory&
class=&org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&&
&property name=&dataSource& ref=&dataSource& /&
&property name=&configLocation& value=&classpath:/hibernate.cfg.xml& /&
&property name=&configurationClass& value=&org.hibernate.cfg.AnnotationConfiguration& /&
&property name=&namingStrategy& ref=&namingStrategy& /&
&bean id=&namingStrategy& class=&org.hibernate.cfg.ImprovedNamingStrategy&/&在这种命名策略下,Hibernate将生成如下面示例6的脚本:示例6:create table client (
id bigint generated by default as identity (start with 1),
first_name varchar(255),
last_name varchar(255),
primary key (id)
);这样虽然很好,但是它不能解决你所的问题。还需要数据库命名约定。例如,每个表都可能从&T_&开始(比如T_CLIENT就是Client类),或者表中的每个字段可能以表中特定的前缀开始(比如写成CLI_FIRST_NAME和CLI_LAST_NAME)。为了能自动生成这些约束,你写自己的命名策略实施。自定义命名策略实现自定义命名策略最简单的方法是扩展ImprovedNamingStrategy类。这个类提供一些用户默认的情况,因此你只需实现你真正需要的方法就可以。你可以不去理睬通用样式任务的表名和列名方法,比如,把名称都加上大写字母。Hibernate生成表或列名时就会调用这种方法,甚至是在注释中明确指定的列名也会调用这种方法。,从ImprovedNamingStrategy类继承而来的addUnderscores()方法,可以派上用场,如示例7所示:示例7:public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {
public String columnName(String columnName) {
return addUnderscores(columnName).toUpperCase();
public String tableName(String tableName) {
return addUnderscores(tableName).toUpperCase();
}}接下来的示例8,展现的是如何在表名前加&T_&前缀,转换成名字前加大写字母和下划线。示例8:@Override
public String classToTableName(String className) {
return &T_& + tableName(className);
public String propertyToColumnName(String propertyName) {
return addUnderscores(propertyName).toUpperCase();
}一个更复杂的命名策略命名策略接口实际上非常简单,但在很多方面受限制。首先,在任何特定的时间你无法知道调用方法的参数是属于哪个表。这样会受限制,比如,如果需要在表中每个列名前加表前缀,正如数据库约定所要求的。可以在classToTableName()方法中加变量成员存储当前的表,来解决这个限制。对于给定的表,这个方法将在propertyToColunmName()方法后被调用。例如,示例9为表创建了三个字母的前缀,加在表名及表中所有列名前。示例9:public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {
private String currentTableP
public String classToTableName(String className) {
currentTablePrefix = className.substring(0, 3).toUpperCase() + &_&;
return &T& + currentTablePrefix + tableName(className);
public String propertyToColumnName(String propertyName) {
return currentTablePrefix + addUnderscores(propertyName).toUpperCase();
public String columnName(String columnName) {
return addUnderscores(columnName).toUpperCase();
public String tableName(String tableName) {
return addUnderscores(tableName).toUpperCase();
}}使用这种命名策略,Hibernate将产生如示例10的代码:示例10:create table TCLI_CLIENT (
CLI_ID bigint generated by default as identity (start with 1),
CLI_FIRST_NAME varchar(255),
CLI_LAST_NAME varchar(255),
primary key (CLI_ID)
);外部关键字一般很难自动生成的外部关键字,构成了一个麻烦的问题。默认情况下,Hibernate可随机生成如&FKAB1273D65CCF7AB&这样的名字,DBA不会喜欢这样自动产生的命名。解决这个问题,需要使用@ForeignKey注释,如示例11所示:示例11:@Entity
public class Order {
@JoinColumn(name = &CLIENT_ID&)
@ManyToOne(optional = false)
@ForeignKey(name = &FK_CLIENT_ORDERS&)
}多对多关系当然,复杂的关系下(比如多对多的关系),上面所说的变得有些更复杂。例如,示例12中的SocialNerworker类,有许多朋友。这种情况下,你需要使用像@JoinTable,@ForeignKey这样的注释。示例12:@Entity
public class SocialNetworker {
@ManyToMany
@JoinTable(name = &TFRD_FRIEND&,
joinColumns = {@JoinColumn(name = &NETWORKER_ID&) },
inverseJoinColumns = {@JoinColumn(name = &FRIEND_ID&) }
@ForeignKey(name = &FK_SNT_FRIENDS&,
inverseName=&FK_FRD_FRIENDS&)
private Set&SocialNetworker& friends = new HashSet&SocialNetworker&();
}展示SQL脚本一旦你需要对数据库做改动或更新时,数据库管理员出于职责会很谨慎,可能会看要执行的SQL脚本,Hibernate可以通过SchemaExport工具,展示SQL脚本。你使用这个工具把要完成的模式生成普通的SQL脚本。当然,此类操作你不想做为构建过程的一部分去做,如果使用Maven,例如,你使用Hibernate3-maven-plugin自动生成数据库架构。关键部分如示例13所示,当然你可以设置drop和export为false,这样就相当于没有更新数据库资料。示例13:&plugin&
&groupId&org.codehaus.mojo&/groupId&
&artifactId&hibernate3-maven-plugin&/artifactId&
&version&2.1&/version&
&executions&
&execution&
&phase&process-classes&/phase&
&goal&hbm2ddl&/goal&
&/execution&
&/executions&
&configuration&
&components&
&component&
&name&hbm2ddl&/name&
&implementation&annotationconfiguration&/implementation&
&/component&
&component&
&name&hbmdoc&/name&
&/component&
&/components&
&componentProperties&
&configurationfile&/target/classes/hibernate.cfg.xml&/configurationfile&
&outputfilename&schema.ddl&/outputfilename&
&namingstrategy&mycompany.myapp.IRDNamingStrategy&/namingstrategy&
&drop&false&/drop&
&create&true&/create&
&export&false&/export&
&format&true&/format&
&/componentProperties&
&/configuration&
&/plugin&这样会生成SQL脚本,可以拿给DBA们看了。
总结DBA命名惯例保留了下来,如果你将与他们共事,将需要顾及这些惯例。幸运的是,这并不意味着你要放弃Hibernate自动产生的数据库架构,也不用自已写SQL脚本。用相结合的命名策略,你会获得双赢。
来自:原文:
& 相关主题:这是我的个人博客,但我期待你的参与...MSN:(将#改成@)
Hibernate4 mysql 采用注解(annotation)方式配置入门例子
作者:轻舞肥羊 日期:
前面的例子(参考)中记录了利用传统的hibernate XML 隐射方式配置, 但这种处理方式在近几年已经不流行了,因为要维护太多的XML 配置文件,而且修改之后还得重启应用服务器。近年流行的是用注解方式写程序, 直观,对程序员来说更容易维护,代码更少。所以在前一个例子的基础上,改写成hibernate 注解方式.1. 拷贝前面的例子,重新命名为一个新的工程删掉 Stock.xml hibernate映射配置文件, 修改 Stock.java 为如下: 程序代码package com.yihaomen.hibernate.import javax.persistence.Cimport javax.persistence.Eimport javax.persistence.GeneratedVimport javax.persistence.GenerationTimport javax.persistence.Id;import javax.persistence.T/** * Model class for Stock */@Entity@Table(name="stock")public class Stock implements java.io.Serializable {    private static final long serialVersionUID = 1L;    @Id    @GeneratedValue(strategy=GenerationType.AUTO)    @Column(name="STOCK_ID")    private Integer stockId;        @Column(name="STOCK_CODE", length=10)    private String stockC        @Column(name="STOCK_NAME", length=20)    private String stockN    public Stock() {    }    public Stock(String stockCode, String stockName) {        this.stockCode = stockC        this.stockName = stockN    }    public Integer getStockId() {        return this.stockId;    }    public void setStockId(Integer stockId) {        this.stockId = stockId;    }    public String getStockCode() {        return this.stockC    }    public void setStockCode(String stockCode) {        this.stockCode = stockC    }    public String getStockName() {        return this.stockN    }    public void setStockName(String stockName) {        this.stockName = stockN    }}这里注意 怎么定义映射那个表,那个字段的。当然还有自动增量的定义,Id,以及生成策略, 先简单介绍一下有如下几种生成策略:AUTO - 可以是identity column类型,或者sequence类型或者table类型,取决于不同的底层数据库.TABLE - 使用表保存id值(也就是会为应用的表创建一张专门保存Id的表)IDENTITY - identity columnSEQUENCE – sequence这里采用了 AUTO 方式,可以在多个数据库之间切换,自动识别,如果是oracle 应该用 sequence 方式了,具体才用那种方式,根据自己数据库需要,以及程序要求.2. 更新注解下的hibernate 配置文件
程序代码&?xml version="1.0" encoding="utf-8"?&&!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN"""&&hibernate-configuration&&&&&&session-factory&&&&&&&&&&property name="hibernate.bytecode.use_reflection_optimizer"&false&/property&&&&&&&&&&property name="hibernate.connection.driver_class"&com.mysql.jdbc.Driver&/property&&&&&&&&&&property name="hibernate.connection.password"&password&/property&&&&&&&&&&property name="hibernate.connection.url"&jdbc:mysql://localhost:3306/yihaomen-hibernate&/property&&&&&&&&&&property name="hibernate.connection.username"&root&/property&&&&&&&&&&property name="hibernate.dialect"&org.hibernate.dialect.MySQLDialect&/property&&&&&&&&&&property name="show_sql"&true&/property&&&&&&&&&&!--&&&&&&&&&mapping resource="com/yihaomen/hibernate/domain/Stock.hbm.xml"&&/mapping&&&&&&&&&--&&&&&&& &mapping class="com.yihaomen.hibernate.domain.Stock"&&/mapping&&&&&&/session-factory&&/hibernate-configuration&这里的重点是将 程序代码&mapping resource="com/yihaomen/hibernate/domain/Stock.hbm.xml"&&/mapping&替换成 程序代码&mapping class="com.yihaomen.hibernate.domain.Stock"&&/mapping&3. 其他配置部分以及程序代码保持原样运行测试程序,可以但到结果,数据被成功插入到数据库中了,源代码在下面下载:
| 查看次数: -
游客发言不需要密码.
禁止表情转换
禁止自动转换链接
禁止自动转换关键字
虽然发表评论不用注册,但是为了保护您的发言权,建议您.Hibernate注解方法使用总结
1.类级别注解
@Entity&&&&
@Entity(name="tableName")
@Table(name="",catalog="",schema="")& - @Entity &
name - &&&&&&&&&
catalog - Catalog
Catalog("").
, Schema("").
@Version&&&
@Column&&&&
@Transient&&&&
与主键相关注解
@GeneratedValue(strategy=GenerationType,generator="")
Strategy -
GenerationType.AUTO - &&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
GenerationType.INDENTITY - IdentityDB2MySQL&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&
MSSQL ServerSyBaseHyperanoicSQLIdentity&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
GenerationType.SEQUENCE - SequenceOracleDB2&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Sequence@SequenceGenerator
(OracleSequence)
GenerationType.TABLE& - @TableGenerator
@TableGenerator(name="tab_cat_gen",allocationSize=1)
@GeneratedValue(Strategy=GenerationType.Table)
Generator - ORM
@SequenceGenerator
注解声明了一个数据库序列。
表示该表主键生成策略名称,它被引用在@GeneratedValue中设置的“gernerator”值中。
sequenceName -
表示生成策略用到的数据库序列名称。
initialValue -
表示主键初始值,默认为0.
allocationSize -
每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50.
@GeneratedValues(strategy=StrategyType.SEQUENCE)
public int getPk() {
Hibernatefield
propertygetter
与非主键相关注解
@Basic(fetch=FetchType.EAGER)&&
@Basic(fetch=FetchType.LAZY)&&&
@Temporal -
@Temporal(TemporalType=DATE)&&&&&&
@Temporal(TemporalType=TIME)&&&&&&
@Temporal(TemporalType=TIMESTAMP)
&&&&&&&&&&
@Transient - ORM@TransientORM
&&& @Transient
public int getAge() {
return getYear(new Date()) - getYear(birth);
2.3无注解属性的默认值
,@Embeddable,@Embedded
,Serializable, @Basicserialized
,java.sql.Clob
java.sql.Blob,@LobLobType.
hierarchy)
4.1关联映射的一些定义
@OneToMany(mappedBy="") //
关联映射的一些共有属性
@OneToOne@OneToMany@ManyToOneManyToMany
Fetch.EAGER -& Fetch.EAGER&
Fetch.LAZY - Fetch.LAZY
CascadeType.PERSIST -
CascadeType.REMOVE -
CascadeType.MERGE -
CascadeType.REFRESH -
CascadeType.ALL -
targetEntity - @OneToMany(targetEntity=Book.class)
@JoinColumn -
@JoinColumn@Column
@ManyToOne
name - @JoinColumnManyToOne,
一对一关联
@OneToOne & 表示一个一对一的映射
1.主表类A与从表类B的主键值相对应。
&主表:@OneToOne(cascade =
CascadeType.ALL)
@PrimaryKeyJoinColumn
& public B getB(){
& &&}从表:无
2.主表A中有一个从表属性是B类型的b
主表:@OneToOne(cascade =
CascadeType.ALL)
&&&@JoinColumn(name="主表外键") &&//这里指定的是数据库中的外键字段。&&&public
3.主表A中有一个从表属性是B类型的b,同时,从表B中有一个主表属性是A类型的a主表:@OneToOne(cascade = CascadeType.ALL)
&&&@JoinColumn(name="主表外键") &&//这里指定的是数据库中的外键字段。&&&public
}从表:@OneToOne(mappedBy = "主表类中的从表属性")&&&public
主表类 get主表类(){
&&注意:@JoinColumn是可选的。默认值是从表变量名+"_"+从表的主键(注意,这里加的是主键。而不是主键对应的变量)。
多对一关联
@ManyToOne -
@ManyToOne(targetEntity=XXXX.class)&&
@JoinColumn(name="")&&&&&&&&&&&&&&&&&&&&&&&&&&&
@ManyToOne()
@JoinColumn(name="USER")
public User getUser() {
一对多关联
@OneToMany -
@OneToMany&
@JoinColumn(name="xxx_id")
@ManyToOne
@JoinColumn(name="")
@OneToMany(mappedBy="")
@JoinColumn(name="")
多对多关联
@ManyToMany -
targetEntity - package.Book.class
mappedBy -
@ManyToMany
@ManyToManytargetEntity@ManyToManymappedBytargetEntity
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。java(72)
hibernate(15)
1、@Entity(name=&EntityName&)
必须,name为可选,对应数据库中一的个表
2、@Table(name=&&,catalog=&&,schema=&&)
可选,通常和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息
name:可选,表示表的名称.默认地,表名和实体名称一致,只有在不一致的情况下才需要指定表名
catalog:可选,表示Catalog名称,默认为Catalog(&&).
schema:可选,表示Schema名称,默认为Schema(&&).
@id定义了映射到数据库表的主键的属性,一个实体只能有一个属性被映射为主键.置于getXxxx()前.
4、@GeneratedValue(strategy=GenerationType,generator=&&)
strategy:表示主键生成策略,有AUTO,INDENTITY,SEQUENCE 和 TABLE 4种,分别表示让ORM框架自动选择,
根据数据库的Identity字段生成,根据数据库表的Sequence字段生成,以有根据一个额外的表生成主键,默认为AUTO
generator:表示主键生成器的名称,这个属性通常和ORM框架相关,例如,Hibernate可以指定uuid等主键生成方式.
&&& @GeneratedValues(strategy=StrategyType.SEQUENCE)
&&& public int getPk() {
5、@Basic(fetch=FetchType,optional=true)
@Basic表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的getXxxx()方法,默认即为@Basic
fetch: 表示该属性的读取策略,有EAGER和LAZY两种,分别表示主支抓取和延迟加载,默认为EAGER.
optional:表示该属性是否允许为null,默认为true
&&& @Basic(optional=false)
&&& public String getAddress() {
6、@Column
@Column描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具非常有作用.
name:表示数据库表中该字段的名称,默认情形属性名称一致
nullable:表示该字段是否允许为null,默认为true
unique:表示该字段是否是唯一标识,默认为false
length:表示该字段的大小,仅对String类型的字段有效
insertable:表示在ORM框架执行插入操作时,该字段是否应出现INSETRT语句中,默认为true
updateable:表示在ORM框架执行更新操作时,该字段是否应该出现在UPDATE语句中,默认为true.对于一经创建就不可以更改的字段,该属性非常有用,如对于birthday字段.
columnDefinition:表示该字段在数据库中的实际类型.通常ORM框架可以根据属性类型自动判断数据库中字段的类型,但是对于Date类型仍无法确定数据库中字段类型究竟是DATE,TIME还是TIMESTAMP.此外,String的默认映射类型为VARCHAR,如果要将String类型映射到特定数据库的BLOB或TEXT字段类型,该属性非常有用.
&&& @Column(name=&BIRTH&,nullable=&false&,columnDefinition=&DATE&)
&&& public String getBithday() {
7、@Transient
@Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性.
如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic
&&& //根据birth计算出age属性
&&& @Transient
&&& public int getAge() {
&&&&&& return getYear(new Date()) - getYear(birth);
8、@ManyToOne(fetch=FetchType,cascade=CascadeType)
@ManyToOne表示一个多对一的映射,该注解标注的属性通常是数据库表的外键
optional:是否允许该字段为null,该属性应该根据数据库表的外键约束来确定,默认为true
fetch:表示抓取策略,默认为FetchType.EAGER
cascade:表示默认的级联操作策略,可以指定为ALL,PERSIST,MERGE,REFRESH和REMOVE中的若干组合,默认为无级联操作
targetEntity:表示该属性关联的实体类型.该属性通常不必指定,ORM框架根据属性类型自动判断targetEntity.
&&& //订单Order和用户User是一个ManyToOne的关系
&&& //在Order类中定义
&&& @ManyToOne()
&&& @JoinColumn(name=&USER&)
&&& public User getUser() {
9、@JoinColumn
@JoinColumn和@Column类似,介量描述的不是一个简单字段,而一一个关联字段,例如.描述一个@ManyToOne的字段.
name:该字段的名称.由于@JoinColumn描述的是一个关联字段,如ManyToOne,则默认的名称由其关联的实体决定.
例如,实体Order有一个user属性来关联实体User,则Order的user属性为一个外键,
其默认的名称为实体User的名称+下划线+实体User的主键名称
&&& 见@ManyToOne
10、@OneToMany(fetch=FetchType,cascade=CascadeType)
@OneToMany描述一个一对多的关联,该属性应该为集体类型,在数据库中并没有实际字段.
fetch:表示抓取策略,默认为FetchType.LAZY,因为关联的多个对象通常不必从数据库预先读取到内存
cascade:表示级联操作策略,对于OneToMany类型的关联非常重要,通常该实体更新或删除时,其关联的实体也应当被更新或删除
例如:实体User和Order是OneToMany的关系,则实体User被删除时,其关联的实体Order也应该被全部删除
&&& @OneTyMany(cascade=ALL)
&&& public List getOrders() {
11、@OneToOne(fetch=FetchType,cascade=CascadeType)
@OneToOne描述一个一对一的关联
fetch:表示抓取策略,默认为FetchType.LAZY
cascade:表示级联操作策略
&&& @OneToOne(fetch=FetchType.LAZY)
&&& public Blog getBlog() {
12、@ManyToMany
@ManyToMany 描述一个多对多的关联.多对多关联上是两个一对多关联,但是在ManyToMany描述中,中间表是由ORM框架自动处理
targetEntity:表示多对多关联的另一个实体类的全名,例如:package.Book.class
mappedBy:表示多对多关联的另一个实体类的对应集合属性名称
&&& User实体表示用户,Book实体表示书籍,为了描述用户收藏的书籍,可以在User和Book之间建立ManyToMany关联
&&& @Entity
&&& public class User {
&&&&&& private L
&&&&&& @ManyToMany(targetEntity=package.Book.class)
&&&&&& public List getBooks() {
&&&&&&&&&&
&&&&&& public void setBooks(List books) {
&&&&&&&&&& this.books=
&&& @Entity
&&& public class Book {
&&&&&& private L
&&&&&& @ManyToMany(targetEntity=package.Users.class, mappedBy=&books&)
&&&&&& public List getUsers() {
&&&&&&&&&&
&&&&&& public void setUsers(List users) {
&&&&&&&&&& this.users=
两个实体间相互关联的属性必须标记为@ManyToMany,并相互指定targetEntity属性,
需要注意的是,有且只有一个实体的@ManyToMany注解需要指定mappedBy属性,指向targetEntity的集合属性名称
利用ORM工具自动生成的表除了User和Book表外,还自动生成了一个User_Book表,用于实现多对多关联
13、@MappedSuperclass
@MappedSuperclass可以将超类的JPA注解传递给子类,使子类能够继承超类的JPA注解
&&& @MappedSuperclass
&&& public class Employee() {
&&&&&& ....
&&& @Entity
&&& public class Engineer extends Employee {
&&&&&& .....
&&& @Entity
&&& public class Manager extends Employee {
&&&&&& .....
14、@Embedded
@Embedded将几个字段组合成一个类,并作为整个Entity的一个属性.
例如User包括id,name,city,street,zip属性.
我们希望city,street,zip属性映射为Address对象.这样,User对象将具有id,name和address这三个属性.
Address对象必须定义为@Embededable
&&& @Embeddable
&&& public class Address {city,street,zip}
&&& @Entity
&&& public class User {
&&&&&& @Embedded
&&&&&& public Address getAddress() {
&&&&&&&&&& ..........
  现在,让我们来动手使用Hibernate Annotation。
安装 Hibernate Annotation
  要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点 下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。如果您正在使用 Maven,只需要向
POM 文件添加相应的依赖项即可,如下所示:
&dependency&
&groupId&org.hibernate&/groupId&
&artifactId&hibernate&/artifactId&
&version&3.2.1.ga&/version&
&/dependency&
&dependency&
&groupId&org.hibernate&/groupId&
&artifactId&hibernate-annotations&/artifactId&
&version&3.2.0.ga&/version&
&/dependency&
&dependency&
&groupId&javax.persistence&/groupId&
&artifactId&persistence-api&/artifactId&
&version&1.0&/version&
&/dependency&
  下一步就是获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:
sessionFactory = new
AnnotationConfiguration().buildSessionFactory();
  尽管通常使用 &mapping& 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:
&!DOCTYPE hibernate-configuration PUBLIC
&-//Hibernate/Hibernate Configuration DTD 3.0//EN&
&http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&&
&hibernate-configuration&
&session-factory&
&mapping class=&com.onjava.modelplanes.domain.PlaneType&/&
&mapping class=&com.onjava.modelplanes.domain.ModelPlane&/&
&/session-factory&
&/hibernate-configuration&
  近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用 AnnotationSessionFactoryBean 类轻松建立一个基于注释的 Hibernate 会话工厂,如下所示:
&!-- Hibernate session factory --&
&bean id=&sessionFactory&
class=&org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&&
&property name=&dataSource&&
&ref bean=&dataSource&/&
&/property&
&property name=&hibernateProperties&&
&prop key=&hibernate.dialect&&org.hibernate.dialect.DerbyDialect&/prop&
&prop key=&hibernate.hbm2ddl.auto&&create&/prop&
&/property&
&property name=&annotatedClasses&&
&value&com.onjava.modelplanes.domain.PlaneType&/value&
&value&com.onjava.modelplanes.domain.ModelPlane&/value&
&/property&
第一个持久性类
  既然已经知道了如何获得注释所支持的 Hibernate 会话,下面让我们来了解一下带注释的持久性类的情况:
  像在其他任何 Hibernate应用程序中一样,带注释的持久性类也是普通 POJO。差不多可以说是。您需要向 Java 持久性 API (javax.persistence.*)添加依赖项,如果您正在使用任何特定于 Hibernate的扩展,那很可能就是 Hibernate Annotation 程序包(org.hibernate.annotations.*),但除此之外,它们只是具备了持久性注释的普通 POJO 。下面是一个简单的例子:
public class ModelPlane {
public Long getId() {
public void setId(Long id) {
public String getName() {
public void setName(String name) {
this.name =
  正像我们所提到的,这非常简单。@Entity 注释声明该类为持久类。@Id 注释可以表明哪种属性是该类中的独特标识符。事实上,您既可以保持字段(注释成员变量),也可以保持属性(注释getter方法)的持久性。后文中将使用基于属性的注释。基于注释的持久性的优点之一在于大量使用了默认值(最大的优点就是 “惯例优先原则(convention over configuration)”)。例如,您无需说明每个属性的持久性——任何属性都被假定为持久的,除非您使用 @Transient 注释来说明其他情况。这简化了代码,相对使用老的
XML 映射文件而言也大幅地减少了输入工作量。
  Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。下面的示例说明了一种常用的方法,其中 Hibernate 将会根据底层数据库来确定一种恰当的键生成策略:
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
定制表和字段映射
  默认情况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。例如,前一个类可以与映射到以如下代码创建的表中:
CREATE TABLE MODELPLANE
NAME varchar
  如果您是自己生成并维护数据库,那么这种方法很有效,通过省略代码可以大大简化代码维护。然而,这并不能满足所有人的需求。有些应用程序需要访问外部数据库,而另一些可能需要遵从公司的数据库命名惯例。如果有必要,您可以使用 @Table 和 @Column 注释来定制您自己的持久性映射,如下所示:
@Table(name=&T_MODEL_PLANE&)
public class ModelPlane {
@Column(name=&PLANE_ID&)
public Long getId() {
public void setId(Long id) {
@Column(name=&PLANE_NAME&)
public String getName() {
public void setName(String name) {
this.name =
  该内容将映射到下表中:
CREATE TABLE T_MODEL_PLANE
PLANE_ID long,
PLANE_NAME varchar
  也可以使用其他图和列的属性来定制映射。这使您可以指定诸如列长度、非空约束等详细内容。Hibernate支持大量针对这些注释的属性。下例中就包含了几种属性:
@Column(name=&PLANE_ID&, length=80, nullable=true)
public String getName() {
  Java 持久性映射过程中最重要和最复杂的一环就是确定如何映射表间的关系。像其他产品一样, Hibernate 在该领域中提供了高度的灵活性,但却是以复杂度的增加为代价。我们将通过研究几个常见案例来了解如何使用注释来处理这一问题。
  其中一种最常用的关系就是多对一的关系。假定在以上示例中每个 ModelPlane 通过多对一的关系(也就是说,每个飞机模型只与一种飞机类型建立联系,尽管指定的飞机类型可以与七种飞机模型建立联系)来与 PlaneType 建立联系。可如下进行映射:
&&& @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public PlaneType getPlaneType() {
return planeT
  CascadeType 值表明 Hibernate 应如何处理级联操作。
  另一种常用的关系与上述关系相反:一对多再对一关系,也称为集合。在老式的 Hibernate 版本中进行映射或使用注释时,集合令人头疼,这里我们将简要加以探讨,以使您了解如何处理集合,例如,在以上示例中每个 PlaneType 对象都可能会包含一个 ModelPlanes 集合。可映射如下:
@OneToMany(mappedBy=&planeType&,
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
@OrderBy(&name&)
public List&ModelPlane& getModelPlanes() {
return modelP
  Hibernate 最优秀的功能之一就在于它能够在您的映射文件中声明命名查询。随后即可通过代码中的名称调用此类查询,这使您可以专注于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的情况。
  也可以使用注释来实现命名查询,可以使用 @NamedQueries 和 @NamedQuery 注释,如下所示:
@NamedQueries(
@NamedQuery(
name=&planeType.findById&,
query=&select p from PlaneType p left join fetch p.modelPlanes where id=:id&
@NamedQuery(
name=&planeType.findAll&,
query=&select p from PlaneType p&
@NamedQuery(
name=&planeType.delete&,
query=&delete from PlaneType where id=:id&
  一旦完成了定义,您就可以像调用其他任何其他命名查询一样来调用它们
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:940444次
积分:7980
积分:7980
排名:第2119名
原创:107篇
转载:90篇
评论:75条
(1)(2)(1)(3)(1)(1)(3)(1)(4)(2)(1)(1)(3)(6)(5)(1)(6)(1)(7)(1)(1)(5)(11)(9)(4)(3)(11)(1)(10)(12)(33)(10)(2)(3)(11)(6)(10)(5)

我要回帖

更多关于 hibernate注释配置 的文章

 

随机推荐