简介:

传统上,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. 本机安装mysql服务

    Windows 上安装 MySQL Windows 上安装 MySQL 相对来说会较为简单,你需要在 MySQL 下载中下载 Windows 版本的 MySQL 安装包. Download Link: ...

  2. [转] Spark快速入门指南 – Spark安装与基础使用

    [From] https://blog.csdn.net/w405722907/article/details/77943331 Spark快速入门指南 – Spark安装与基础使用 2017年09月 ...

  3. Shiro在SpringBoot中的使用

    Demo代码请参考:https://github.com/roostinghawk/ShiroDemo 以下为主要代码(经过验证,测试) 1. pom.xml:引用shiro <dependen ...

  4. [转]Hive 数据类型

    Hive的内置数据类型可以分为两大类:(1).基础数据类型:(2).复杂数据类型.其中,基础数据类型包括:TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBL ...

  5. Vue vs React: Javascript 框架之战

    https://baijiahao.baidu.com/s?id=1608210396818353443&wfr=spider&for=pc    原文档 正如我们之前提到的,Word ...

  6. [转]C#算法题

    1:不允许使用循环语句.条件语句,在控制台中打印出1-200这200个数. 参考答案:这里我使用的是递归. static void Main(string[] args) { Print(); Con ...

  7. 我的Python升级打怪之路【五】:Python模块

    模块,是一些代码实现了某个功能的集合 模块的分类: 自定义模块 第三方模块 内置模块 导入模块 import module from module.xx.xx import xx from modul ...

  8. Python爬虫抓取某音乐网站MP3(下载歌曲、存入Sqlite)

    最近右胳膊受伤,打了石膏在家休息.为了实现之前的想法,就用左手打字.写代码,查资料完成了这个资源小爬虫.网页爬虫, 最主要的是协议分析(必须要弄清楚自己的目的),另外就是要考虑对爬取的数据归类,存储. ...

  9. javascript正则表达式语法

    1. 正则表达式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的标点符号,都是"普通字符".表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的 ...

  10. 2-3 树/红黑树(red-black tree)

    2-3 tree 2-3树节点: null节点,null节点到根节点的距离都是相同的,所以2-3数是平衡树 2叉节点,有两个分树,节点中有一个元素,左树元素更小,右树元素节点更大 3叉节点,有三个子树 ...