简介:

传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。

然而现在借助新的 Hibernate   Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java类中,并提供一种强大及灵活的方法来声明持久性映射。即利用hibernate注解后,可不用定义持久化类对应的*.hbm.xml文件,直接以注解方式写入在持久化类中来实现。

Hibernate annotation使用了ejb JPA的注解,所以,下面安装配置hibernate annotation环境时,需要导入ejb的包。

配置:

(1)安装 Hibernate Annotation 第一步, 环境与jar包: 要使用  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)。

(2)添加hibernate3.2.jar,hibernate-annotations-  3.3.0.jar,hibernate-commons-annotations.jar和ejb3-persistence.jar   。这样就可以使用hibernate的annotation了。
(3) 如果您正在使用 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>
 
(4)hibernate annotation标签的使用
      【1】带注释的持久化类也是普通POJO,它们只是具有持久性注释的普通POJO。
      【2】事实上你既可以保持字段(注释写在成员变量之上)的持久性,也可以保持属性(注释写在getter方法之上)的持久性。
      【3】常用的Hibernate annotation标签如下: 
             @Entity                    --注释声明该类为持久类。将一个Javabean类声明为一  个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的,  要用下面的Transient来注解.
             @Table(name="promotion_info")      --持久性映射的表(表名="promotion_info).@Table是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字,默认为实体bean的类名,不带包名.
             @Id    --注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。    
             @GeneratedValue    --定义自动增长的主键的生成策略.              
             @Transient              --将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错.
             @Temporal(TemporalType.TIMESTAMP)      --声明时间格式 
             @Enumerated         --声明枚举
             @Version                --声明添加对乐观锁定的支持
             @OneToOne            --可以建立实体bean之间的一对一的关联
             @OneToMany          --可以建立实体bean之间的一对多的关联
             @ManyToOne          --可以建立实体bean之间的多对一的关联
             @ManyToMany        --可以建立实体bean之间的多对多的关联
             @Formula               --一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)           
             @OrderBy               --Many端某个字段排序(List)
        【4】Hibernate能够出色的自动生成主键。Hibernate/EBJ 3 也可以为主键的自动生成提供丰富的支持,允许实现各种策略。
                其生成规则由@GeneratedValue设定的,这里的@Id和@GeneratedValue都是JPA的标准用法。
               JPA提供了四种标准用法,由@GeneratedValue的源代码可以看出,JPA提供的四种标准用法是: 
               TABLE,SEQUENCE,IDENTITY,AUTO     
          详解如下: 
               TABLE:使用一个特定的数据库表格来保存主键。
               SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
                   IDENTITY:主键由数据库自动生成(主要是自动增长型)
               AUTO:主键由程序控制。在指定主键时,如果不指定主键生成策略,默认为AUTO。
                   @Id
               相当于
               @Id @GeneratedValue(strategy = GenerationType.AUTO)
               identity:
               使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence
               (MySQL 和 SQL Server 中很常用)。Oracle就要采用sequence了.
               同时,也可采用uuid,native等其它策略。
(5)
onetomany示例:
@Entity
@Table(name = "Dept") public class Dept {
@Id
@GeneratedValue
/*
对于oracle想使用各自的Sequence,设置如下:
@GeneratedValue(strategy =GenerationType.AUTO,generator="PROMOTION_SEQ")
@SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")
另外:
对于自动增长后,在数据表中的相应字段,要设置字段为auto_increment.
*/
private Integer deptno;
@Column
private String deptname;
@OneToMany(mappedBy="dept")
//mappedBy 属性主要针对外键而言,与之对应的是.xml中的inverse属性
//mappedBy="dept" 是把维护权交给多的一方
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Emp> emps=new HashSet<Emp>();
public Integer getDeptno() { return deptno; }
public void setDeptno(Integer deptno) { this.deptno = deptno; }
public String getDeptname() { return deptname; }
public void setDeptname(String deptname) { this.deptname = deptname; }
public Set<Emp> getEmps() { return emps; }
public void setEmps(Set<Emp> emps) { this.emps = emps; } }

默认情况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。

@Entity
@Table(name = "Emp")
public class Emp {
@Id
@GeneratedValue
private Integer empno;
@Column
private String ename;
//如果有多个cascade,可以是{CascadeType.PERSIST,CascadeType.MERGE}
@ManyToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "deptno")//dept类对应外键的属性:deptno
private Dept dept; public Integer getEmpno() {
return empno;
} public void setEmpno(Integer empno) {
this.empno = empno;
} public String getEname() {
return ename;
} public void setEname(String ename) {
this.ename = ename;
} public Dept getDept() {
return dept;
} public void setDept(Dept dept) {
this.dept = dept;
} }

在hibernate.cfg.xml中的

<session-factory>

.....

<mapping class="cn.onetomanydouble.entity.Dept"/>

<mapping class="cn.onetomanydouble.entity.Emp"/>

</session-factory>

这里遇到一个问题:如果配置mappedBy属性的同时加上@JoinColumn会抛出异常,所以不能同时使用@JoinColumn和mappedBy;因为@JoinColumn本身就是自己来维护外键,和mappedBy冲突了。--->>>希望大牛可以再详细的解说下!

抛出的异常如下:

java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:)
at org.junit.runners.BlockJUnit4ClassRunner$.runReflectiveCall(BlockJUnit4ClassRunner.java:)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:)
at org.junit.runners.ParentRunner$.run(ParentRunner.java:)
at org.junit.runners.ParentRunner$.schedule(ParentRunner.java:)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:)
at org.junit.runners.ParentRunner.access$(ParentRunner.java:)
at org.junit.runners.ParentRunner$.evaluate(ParentRunner.java:)
at org.junit.runners.ParentRunner.run(ParentRunner.java:)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.lizhou.entity.test.Department.employeeList
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory$.getObject(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:)
at com.lizhou.action.test.TestAction.<clinit>(TestAction.java:)
... more
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.lizhou.entity.test.Department.employeeList
at org.hibernate.cfg.annotations.CollectionBinder.bind(CollectionBinder.java:)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:)
... more

在这里再说一下,如果先保存员工后保存部门,会多出四条update语句。

Hibernate: insert into emp (deptno, ename, empno) values (?, ?, ?)
Hibernate: insert into emp (deptno, ename, empno) values (?, ?, ?)
Hibernate: insert into dept(dname) values (?)
Hibernate: update emp set deptno=?, ename=? ,empno=? where id=?
Hibernate: update emp set deptno=?, ename=? ,empno=? where id=?
Hibernate: update emp set deptno=? ,empno=? where id=?
Hibernate: update emp set deptno=? ,empno=? where id=?

总结:mappedBy属性跟xml配置文件里的inverse一样。在一对多或一对一的关系映射中,如果不表明mappedBy属性,默认是由本方维护外键。但如果两方都由本方来维护的话,会多出一些update语句,性能有一定的损耗。

解决的办法就是在一的一方配置上mappedBy属性,将维护权交给多的一方来维护,就不会有update语句了。

注意,配了mappedBy属性后,不要再有@JoinColumn,会冲突!

Hibernate Annotation (Hibernate 注解)的更多相关文章

  1. hibernate Annotation 以及注解版的数据关联 4.4

    目的是不写xxx.hbm.xml映射文件,使用注解 主配置文件还是要有hibernate.cfg.xml <?xml version="1.0" encoding=" ...

  2. Rhythmk 学习 Hibernate 07 - Hibernate annotation 实体注解

    参考: http://docs.jboss.org/hibernate/annotations/3.4/reference/zh_cn/html_single/ 1.系统配置: 可以通过使用  map ...

  3. hibernate Annotation 以及注解版的数据关联

    目的是不写xxx.hbm.xml映射文件,使用注解 主配置文件还是要有hibernate.cfg.xml <?xml version="1.0" encoding=" ...

  4. hibernate annotation 之 注解声明

    @Entity 将一个 POJO 类注解成一个实体 bean ( 持久化 POJO 类 ) @Table 为实体 bean 映射指定具体的表,如果该注解没有被声明,系统将使用默认值 ( 即实体 bea ...

  5. 转Hibernate Annotation mappedBy注解理解

    在Annotation 中有这么一个@mappedBy 属性注解,相信有些同学还是对这个属性有些迷惑,上网找了些理解@mappedBy比较深刻的资料,下面贴出来供大家参考. http://xiaoru ...

  6. Rhythmk 学习 Hibernate 08 - Hibernate annotation 关联关系注解

    1.一对一 (One to One)    共三种情况:     1.1 主键共享    1.2 外键共享 1.3 中间表关联 1.1  code: @Entity public class arti ...

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

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

  8. Hibernate框架之注解的配置

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

  9. Hibernate Annotation笔记

    (1)简介:在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准.它非常强大.灵活,而且具备了优异的性能.在本文中,我们将了解如何使用Java 5 注释来简化Hiberna ...

随机推荐

  1. linux系统下运行java项目的脚本编写

    本文主要讲linux系统下运行jar包,至于如何打包jar包,放到linux系统下可以参考其他的博客. 在linux系统下运行jar包的命令如下: 1.java -jar xxxxx.jar  //  ...

  2. 打扮IDEA更换主题

    原文链接:https://blog.csdn.net/github_39577257/article/details/80629750 当我们安装一个新的IDEA工具时,第一次进入时会提示我们选择一个 ...

  3. iOS中的自由桥接

    [摘抄自<iOS 6编程实战>] 与Objective-C库不同,我们在Objective-C中使用标准C语言和Core Foundation类库(CF*方法)不会遵循那些命名约定.这意味 ...

  4. 阿里VS华为-开源镜像站体验及评测

    最近对阿里和华为的开源镜像站做了深度体验,并将评测结果分享给大家: 一.评测产品: 华为开源镜像站(https://mirrors.huaweicloud.com/)以下简称 华为 阿里开源镜像站(h ...

  5. flask.abort

    abort(status) status:标注状态码,和异常 抛出异常后会终止当前函数 使用errorhandler装饰器捕获abort异常 @app.errorhandler(500) def in ...

  6. U盘拷贝大文件提示文件过大无法拷贝解决方案

    工具: 计算机 windows操作系统 U盘 原因:由于U盘的格式问题导致的,当期的磁盘格式是FAT32类型的,无拷贝过大的文件 方法:接下来修改U盘类型,且不格式化U盘 1.键盘win+R快捷键弹出 ...

  7. mysql编码不统一形成的错误

    错误提示:[Err]1267 - Illegal mix of collations(utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) ...

  8. 20164324王启元 Exp1 PC平台逆向破解

    一.逆向及Bof基础实践说明 1.1实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 手工修 ...

  9. git提交过程中遇到的 index.lock 问题导致无法提交的解决方法

    在提交代码的过程中,可能会遇到下面的问题: fatal: Unable to create 'C:/programLists/zzw-q1/.git/index.lock': File exists. ...

  10. IDEA里运行代码时出现Error:scalac: error while loading JUnit4, Scala signature JUnit4 has wrong version expected: 5.0 found: 4.1 in JUnit4.class错误的解决办法(图文详解)

    不多说,直接上干货!  问题详情 当出现这类错误时是由于版本不匹配造成的 Information:// : - Compilation completed with errors and warnin ...