(1)
简介:
在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
   在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。
即利用hibernate注解后,可不用定义持久化类对应的*.hbm.xml文件,直接以注解方式写入在持久化类中来实现。
Hibernate annotation使用了ejb JPA的注解,所以,下面安装配置hibernate annotation环境时,需要导入ejb的包。许多网上的资料都是jpa hibernate annotation方面的资料。
(2)
安装 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)。
添加hibernate3.2.jar,hibernate-annotations- 3.3.0.jar,hibernate-commons-annotations.jar和ejb3-persistence.jar 。这样就可以使用hibernate的annotation了。

如果您正在使用 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">
    <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
      <prop key="hibernate.hbm2ddl.auto">create</prop>
      ...
    </props>
  </property>
<!--指明使用标注的实体类-->
  <property name="annotatedClasses">
    <list>
      <value>com.onjava.modelplanes.domain.PlaneType</value>
      <value>com.onjava.modelplanes.domain.ModelPlane</value>
      ...
    </list>
  </property>
<!--当然也可以不使用上面这种指定的方式,而使用包扫描的方式做为替换,推荐这种-->
<property name="packagesToScan">
      <list>
           <value>com.onjava.modelplanes.domain.*</value>
       </list>
     </property>
</bean>
(3)
hibernate Annotation标签的使用:
[1]
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)

1.2
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等其它策略.(相关用法,上网查询)
[2]
第一个持久性类

@Entity
@Table(name="T_MODEL_PLANE")
publicclass ModelPlane    implements Serializable {
       @Id
       @Column(name="PLANE_ID")    
       @GeneratedValue(strategy=GenerationType.AUTO) //注解于属性中
/*
对于oracle想使用各自的Sequence,设置如下:        
@GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")        
@SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")    
另外:
对于自动增长后,在数据表中的相应字段,要设置字段为auto_increment.
*/
private Long id;

private String name;//注解写于getter方法之上.请见下.

//DATE            - java.sql.Date        
//TIME            - java.sql.Time        
//TIMESTAMP - java.sql.Timestamp        
    @Temporal(TemporalType.TIMESTAMP)        
    @Column(name="start_time")        
private Date startTime;

//显示0 隐藏1        
publicstaticenum DisplayType {显示,隐藏}        
    @Enumerated(value = EnumType.ORDINAL)//ORDINAL序数        
private DisplayType displayType = DisplayType.显示;

//1.sql语句中的字段和表名都应该和数据库相应,而不是类中的字段,        
//若带有参数如la.id= id,这个=id才是类中属性        
//2.操作字段一定要用别名        
    @Formula(select COUNT(la.id) from largess la)        
privateint count;

//注解于方法中
       @Column(name="PLANE_ID", length=80, nullable=true) //较详细定义
public String getName() {
return name;
       }
publicvoid setName(String name) {
this.name = name;
       }
其它的setter,getter省略......
}


该内容将映射到下表中:
CREATE TABLE T_MODEL_PLANE
(
       PLANE_ID long,
       PLANE_NAME varchar
       其它字段省略...
)    

默认情况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。例如,下例中,若不用注解,则会映射到如下一表中:
CREATE TABLE MODELPLANE
(
   ID long,
   NAME varchar

其它字段省略...
)
[3]
一对多注解:
1.
在一对多注解中,会用到:
"一"方:
@OneToMany --> mappedBy:"多"方的关联属性(被控方)
"多"方:
@ManyToOne --> @JoinColumn,"多"方定义的外键字段.
如数据表定义外键如下:
FOREIGN KEY (classid) REFERENCES classes(id)
则:
@JoinColumn(name="classid")
2.
在双向关联中,有且仅有一端作为主体(owner)端存在:主体端负责维护联接列(即更新),对于不需要维护这种关系的从表则通过mappedNy属性进行声明。mappedBy的值指向另一主体的关联属性。例子中,mappedBy的值为classes。
附加说明:
mappedBy相当于过去的inverse="true".
inverse=false的side(side其实是指inverse=false所位于的class元素)端有责任维护关系,而inverse=true端无须维护这些关系。
3.
cascade与fetch使用说明:
Cascade
CascadeType.PERSIST (级联新建)
CascadeType.REMOVE  (级联删除)
CascadeType.REFRESH (级联刷新)
CascadeType.MERGE   (级联更新)中选择一个或多个。
CascadeType.ALL
fetch属性:
关联关系获取方式,即是否采用延时加载。
LAZY(默认值)采用延时加载,查询数据时,不一起查询关联对象的数据。而是当访问关联对象时(如:getStudnets()时)才触发相应的查询操作,获取关联对象数据。
EAGER:是在查询数据时,也直接一起获取关联对象的数据。
package oneToMany;
import java.util.Set;
import javax.persistence.*;
/*
注意导入时,是导入:import javax.persistence.*;    
非导入org.hibernate的相关类:import org.hibernate.annotations.Entity;
*/
@Entity
@Table(name="classes")
publicclass Classes implements Serializable {
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
privateint id;
private String name;

@OneToMany(cascade=CascadeType.ALL,mappedBy="classes")    
private Set<Student> students;
//getter,setter省略
}

package oneToMany;
import javax.persistence.*;
@Entity
@Table(name="student")
publicclass Student implements Serializable  {
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
privateint sid;

private String sname;

//若有多个cascade,可以是:{CascadeType.PERSIST,CascadeType.MERGE}
 @ManyToOne(cascade={CascadeType.ALL})        
 @JoinColumn(name="classid")     //student类中对应外键的属性:classid
private Classes classes;
//getter,setter省略
}

publicclass TestOneToMany {
/*
CREATE TABLE    student (    --要定义外键!!!!!!!
   `sid` double NOT NULL auto_increment,
   `classid` double NULL,
   `sname` varchar(255) NOT NULL,
   PRIMARY KEY    (sid),
   INDEX par_ind (classid),
   FOREIGN KEY (classid) REFERENCES classes(id) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
*/
publicstaticvoid main(String[] args) throws SQLException    
 {
try
   {
     SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
     Session session=sf.openSession();
     Transaction tx=session.beginTransaction();

/*
因为mappedBy是定义在classes中,即classes类不负责维护级联关系.即维护者是student.所以,
1.要将clsses的数据,赋给student,即用student的setClasses()方法去捆定class数据;
2.在进行数据插入/更新session.save()/session.update()时,最后操作的是student.
*/
     Classes classes=new Classes();
     classes.setName("access");

Student st1=new Student();
     st1.setSname("jason");
     st1.setClasses(classes);
     session.save(st1);

Student st2=new Student();
     st2.setSname("hwj");
     st2.setClasses(classes);
     session.save(st2);
     tx.commit();

/*
输出如下:
Hibernate: insert into classes (name) values (?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
*/

/*
因为一端维护关系另一端不维护关系的原因,我们必须注意避免在应用中用不维护关系的类(class)建立关系,因为这样建立的关系是不会在数据库中存储的。
如上的代码倒过来,则插入时,student的外键值为空.如下:
*/
//      Student st1=new Student();
//      st1.setSname("jason");
//      session.save(st1);
//        
//      Student st2=new Student();
//      st2.setSname("hwj");
//      session.save(st2);
//        
//      Set<Student> students=new HashSet<Student>();
//      students.add(st1);
//      students.add(st2);
//        
//      Classes classes=new Classes();
//      classes.setName("access");
//      classes.setStudents(students);
//      session.save(classes);
/*
输出如下:
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into student (classid, sname) values (?, ?)
Hibernate: insert into classes (name) values (?)
*/
   }
catch(HibernateException e)
   {
     e.printStackTrace();        
   }
 }
}

[4]
多对多注解:

在多对多注解中,双方都采用@ManyToMany.
其中被控方,像一对多注解中设置一样,也要设置mappedBy.
其中主控方,不像一对多注解那样,采用@joinColumn,而是采用@joinTable.如下:
@JoinTable(name="j_student_course" ,joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="cid")})
其中,
如上所说,mappedBy,相当于inverse="true".所以,在@joinTable中的inverseJoinColumns中定义的字段为mappedBy所在类的主键.
joinColumns定义的字段,就是当前类的主键.
@Entity
@Table(name="jcourse")
publicclass Jcourse {
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
privateint cid;
private String cname;

@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY ,mappedBy="courses")
private Set<Jstudent> students;
//setter,getter省略....    
}

@Entity
@Table(name="jstudent")
publicclass Jstudent {
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
privateint sid;

private String sname;

@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER)
//inverseJoinColumns中对应的id为以下属性course的对应id.
 @JoinTable(name="j_student_course" ,joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="cid")})
private Set<Jcourse> courses;
//setter,getter省略....    
}

publicclass Test {
publicstaticvoid main(String[] args) {
try
   {
     SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
     Session session=sf.openSession();
     Transaction tx=session.beginTransaction();

Jcourse course=new Jcourse();
     course.setCname("jason-english");
     session.save(course); //先各自保存.

Jcourse course2=new Jcourse();
     course2.setCname("herry-english");
     session.save(course2);

Set<Jcourse> courses=new HashSet<Jcourse>();
     courses.add(course);
     courses.add(course2);

Jstudent student=new Jstudent();
     student.setSname("jason");
     student.setCourses(courses);

session.save(student);// 要用非mapby定义的类(studet)来作为主者(会控制级联关系),一对多,多对一也一样道理.
//可以尝试反过来.
     tx.commit();
   }
catch(HibernateException e)
   {
     e.printStackTrace();        
   }
 }
}

转载于:https://blog.51cto.com/andysu/1212070

Hibernate注解使用以及Spring整合相关推荐

  1. flex java blazeds 注解_Flex+BlazeDS+Spring整合

    Flex与服务器通讯有3中方式:HTTPService 组件访问HTTP服务,WebService 组件访问WebService服务,RemoteObject 组件访问Server端对象.第三种方法是 ...

  2. hibernate 学习 并且与spring 整合

    hibernate  的helloWord github地址 先添hibernate加依赖包,如果使用idea 先添加Hibernate support 插件 链接 hibernate的默认主配置文件 ...

  3. 【基于注解方式】Spring整合Kafka

    文章目录 1. 添加Maven依赖 2. 配置与参数分离 3. 工具类度内容 4. Producer 消息生产者配置 5. Consumer 消息消费者配置 6. 使用注解监听消息 7. 请求测试 8 ...

  4. Hibernate Validation与Spring整合各注解的用法Demo

    转自:https://www.aliyun.com/jiaocheng/1315650.html <dependency> <groupId>org.hibernate< ...

  5. JAVAWEB开发之Spring详解之——Spring的入门以及IOC容器装配Bean(xml和注解的方式)、Spring整合web开发、整合Junit4测试

    Spring框架学习路线 Spring的IOC Spring的AOP,AspectJ Spring的事务管理,三大框架的整合 Spring框架概述 什么是Spring?  Spring是分层的Java ...

  6. Spring整合Hibernate步骤以及遇到的问题

    spring整合Hibernate步骤以及遇到的问题 文章目录 spring整合Hibernate步骤以及遇到的问题 步骤: 创建实体类: 编写Dao层: 编写server层: spring配置文件 ...

  7. shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决

    shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决 from :http://blog.csdn.net/babys/article/ ...

  8. Struts2+Hibernate+Spring 整合示例

    转自:https://blog.csdn.net/tkd03072010/article/details/7468769 Struts2+Hibernate+Spring 整合示例 Spring整合S ...

  9. Struts2、Hibernate、Spring整合所需要的jar包

    Struts2.Hibernate.Spring整合所需要的包: Struts2: struts2-core-2.0.14.jar  -- Struts2的核心包. commons-logging-1 ...

最新文章

  1. 关于蹭网的一点点感想
  2. 【记忆化搜索】P1464 Function
  3. oracle的簇与簇表
  4. 改善Java EE生产支持技能的8种方法
  5. 软件工程师必学的9件事
  6. 基于SLS构建RDS审计合规监控
  7. 第二十:如何把Jenkins+Allure2生成的报告发送邮件(重点超详细)
  8. 常见的Java开发框架有哪些?
  9. java pdf 模板_java通过PDF模板填写PDF表单
  10. js数组倒序排列+字符串数组转为数字数组
  11. 捋一捋Python中的List(上)
  12. java算术运算符乘方_用java编写计算器 能够实现简单的加、减、乘、除、乘方、开方运算等;...
  13. git推送被拒绝可能的原因
  14. Python networkx库
  15. 软件设计师考试整理-0-前言
  16. MYSQL 增加唯一索引对于重复数据的处理
  17. 李炎恢ThinkPHP讲义代码/09.ThinkPHP--SQL连贯操作[下][9]
  18. 【ASP.net】--WebSite(网站) 和 WebApplication(Web应用程序)
  19. Linux换国内镜像源(Ubuntu、Debian等)
  20. 实时系统-调度算法和可调度分析

热门文章

  1. 构造函数可以实例化对象
  2. App-V5.0服务器部署
  3. MyISAM 和 InnoDB 讲解
  4. 使用SQL Server 发送邮件
  5. 视图之二--视图中数据的更新
  6. nginx+tomcat+memcached负载均衡
  7. 20个最强的基于浏览器的在线代码编辑器 - OPEN资讯
  8. linux的文件io操作(转)
  9. OpenStack云第五天
  10. 擴展PictureBox的一個組件