Hibernate Annotation

本文介绍使用Hibernate和Annotation进行ORM映射的方法,包括配置、依赖引入及联合主键的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Annotation 写ORM关联数据库表确实要简单很多(主要是可以省略一个配置文件),所以在Hibernate中都喜欢用Annotation 



这个用例中有关于ID生成策略(所以用到了联合主键),和属性是否与数据库映射,以及DATE类型的精度问题····· 



准备工作: 

1.Hibernate 3.3.2 下载 https://www.hibernate.org/6.html 

下载所需要的Hibernate jar包和Annotation jar 包(注意,这里有版本兼容问题)

Html代码  复制代码
  1. Package  Version  Core  Annotations  EntityManager  Validator  Search  Shards  Tools     
  2. Hibernate Core  3.2.6 GA  -  3.2.x, 3.3.x  3.2.x, 3.3.x  3.0.x  3.0.x  3.0.x  3.2.x    
  3.  3.3.2 GA  -  3.4.x  3.4.x  3.1.x  3.1.x  Not compatible  Not compatible   



Hibernate 3.3.6 -->Annotation 3.2.X,3.3.X(兼容) 

Hibernate 3.3.2-->Annotation 3.4.X(兼容) 



2.slf4j 下载 http://www.slf4j.org/ 下载slf4j_x.jar 

因为hibernate 中的日志使用的slf,所以必须下载 

注意(slf4j_api_x.jar 必须与 slf4j_aop_x.jar 版本对应)。 


3.导入jar包 

  1. <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/hibernate3.jar"/>  
  2.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/lib/required/antlr-2.7.6.jar"/>  
  3.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/lib/required/commons-collections-3.1.jar"/>  
  4.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/lib/required/javassist-3.9.0.GA.jar"/>  
  5.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/lib/required/jta-1.1.jar"/>  
  6.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/lib/required/slf4j-api-1.5.8.jar"/>  
  7.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/hibernate-annotations.jar"/>  
  8.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/dom4j.jar"/>  
  9.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/ejb3-persistence.jar"/>  
  10.     <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/hibernate-commons-annotations.jar"/>  
  11.     <classpathentry kind="lib" path="E:/java/sql连接/mysql-connector-java-5.1.11-bin.jar"/>  
  12.     <classpathentry kind="lib" path="E:/java/Hibernate/slf4j-1.5.8/slf4j-1.5.8/slf4j-nop-1.5.8.jar"/>  

 

写hibernate.cfg.xml 

查hibernate 文档可以知道格式

  1. <?xml version='1.0' encoding='utf-8'?>  
  2. <!DOCTYPE hibernate-configuration PUBLIC  
  3.         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  5.   
  6. <hibernate-configuration>  
  7.   
  8.     <session-factory>  
  9.   
  10.         <!-- Database connection settings -->  
  11.         <property name="connection.driver_class">org.hsqldb.jdbcDriver</property><!--数据库驱动-->  
  12.         <property name="connection.url">jdbc:hsqldb:hsql://localhost</property><!--数据库链接-->  
  13.         <property name="connection.username">sa</property><!--数据库用户名--!>  
  14.         <property name="connection.password"></property><!--密码--!>  
  15.   
  16.         <!-- JDBC connection pool (use the built-in) -->  
  17.         <property name="connection.pool_size">1</property><!---->  
  18.   
  19.         <!-- SQL dialect -->  
  20.         <property name="dialect">org.hibernate.dialect.HSQLDialect</property><!--数据库方言-->  
  21.   
  22.         <!-- Enable Hibernate's automatic session context management -->  
  23.         <property name="current_session_context_class">thread</property>  
  24.   
  25.         <!-- Disable the second-level cache  -->  
  26.         <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>  
  27.   
  28.         <!-- Echo all executed SQL to stdout -->  
  29.         <property name="show_sql">true</property>  
  30.   
  31.         <!-- Drop and re-create the database schema on startup -->  
  32.         <property name="hbm2ddl.auto">create</property><!--生成建表语句,这里提供给我们4个值,查文档,试情况可以不写-->  
  33.     </session-factory>  
  34.   
  35. </hibernate-configuration>  

 

4.写实体类 Teacher, 

     这里我们看不同主键(ID生成策略的代码) 



     1,Teacher类,ID为主键 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package com.sccin.entity;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import javax.persistence.Entity;  
  6. import javax.persistence.Id;  
  7. import javax.persistence.Temporal;  
  8. import javax.persistence.TemporalType;  
  9. import javax.persistence.Transient;  
  10.   
  11. @Entity  
  12. public class Teacher {  
  13.     private int id;  
  14.     private String name;  
  15.     private int age;  
  16.     private String title;  
  17.   
  18.     private Date birthday;  
  19.     private String youwifeName;  
  20.   
  21.     @Transient  
  22.     public String getYouwifeName() {  
  23.         return youwifeName;  
  24.     }  
  25.   
  26.     public void setYouwifeName(String youwifeName) {  
  27.         this.youwifeName = youwifeName;  
  28.     }  
  29.   
  30.     @Temporal(TemporalType.DATE)  
  31.     public Date getBirthday() {  
  32.         return birthday;  
  33.     }  
  34.   
  35.     public void setBirthday(Date birthday) {  
  36.         this.birthday = birthday;  
  37.     }  
  38.   
  39.     @Id  
  40.         public int getId() {  
  41.         return id;  
  42.     }  
  43.   
  44.     public void setId(int id) {  
  45.         this.id = id;  
  46.     }  
  47.     public String getName() {  
  48.         return name;  
  49.     }  
  50.   
  51.     public void setName(String name) {  
  52.         this.name = name;  
  53.     }  
  54.   
  55.     public int getAge() {  
  56.         return age;  
  57.     }  
  58.   
  59.     public void setAge(int age) {  
  60.         this.age = age;  
  61.     }  
  62.   
  63.     public String getTitle() {  
  64.         return title;  
  65.     }  
  66.   
  67.     public void setTitle(String title) {  
  68.         this.title = title;  
  69.     }  
  70.   
  71. }  

 

注:在这个类里上写@Entity 我们要让ID为主键,只需要在getId()方法上写上@Id 就行了。 

       @Transient 表示该属性不与数据库表映射 

       @Temporal(TemporalType.DATE) 表示设置类型精度,这个字段为DATE类型,映射到数据库表中类型为Date,只有日期,没有时间精度 



写好了实体类,需要把这个映射添加到hibernate.cfg.xml中 

  1. <mapping class="com.sccin.entity.Teacher"/>  

 

写个方法测试:

 

  1. //保存一个ID=1的Teacher的实体  
  2. public void teachersave() {  
  3.         Teacher t = new Teacher();  
  4.         t.setId(1);  
  5.         t.setName("yang");  
  6.         t.setBirthday(new Date());  
  7.         t.setTitle("T1");  
  8.         t.setAge(20);  
  9.   
  10.         Session session = sessionfactory.openSession();  
  11.   
  12.         session.beginTransaction();  
  13.         session.save(t);  
  14.         session.getTransaction().commit();  
  15.         session.close();  
  16.   
  17.     }  

 

这里主键没有写生成策略,需要我们手动给主键设置值,很容易发生冲突。 

我们一般把主键安装需求设置成它自动增长,有不同的策略。 

  看官方文档给我们的ID生成策略有哪些

 

当然这些很多不常用。 

这里不做解释,看Annotation中怎么标识主键 



需要在主键上增加一个@Id标识

  1. @Id  
  2.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  3.     public int getId() {  
  4.         return id;  
  5.     }  

 

GenerationType 类型的枚举值,它的内容将指定 OpenJPA 容器自动生成实体标识的方式。有 GeneratorType.AUTO,GenerationType.IDENTITY,GenerationType.SEQUENCE, GenerationType.TABLE 四种方式 



@GeneratedValue(strategy = GenerationType.IDENTITY) 

一般可以根据你采取的底层数据库来选择,比如是用oracle,id用sequence的话,可以采取sequence方式,如果是用mysql,一般就用auto模式 


         // 默认相当于native ID生成策略,JPA 1.0 中只有4个可选值 
         // 如果只写@Id ,主键字段不会自动产生,需要我们手动输入 
         // @GeneratedValue 默认为策略产生ID 
         // 如果我要让ID为IDENTITY 则需要手动给他指定值--@GeneratedValue(strategy=GenerationType.IDENTITY) 


这样选择了主键生成策略,在给实体赋值时就不用设置ID值了。 



GenerationType.SEQUENCE 在Oracle中选择这种策略会在数据库中自动建一个为名“Hibernate_Sequence”的SEQUENCE,如果要改这个名字需要另外设置,也很简单,查文档 



GenerationType.TABLE  这中方式是 建一个数据库表 来管理ID主键····省略。 



除了这种方式,有些需求要让多个字段合为主键:联合主键 



联合主键 
     1.建主键类:Teacher_PK(作为主键) 

  1. package com.sccin.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class Teacher_PK implements Serializable {  
  6.   
  7.     private int id;  
  8.     private String name;  
  9.   
  10.     public int getId() {  
  11.         return id;  
  12.     }  
  13.   
  14.     public void setId(int id) {  
  15.         this.id = id;  
  16.     }  
  17.   
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.   
  22.     public void setName(String name) {  
  23.         this.name = name;  
  24.     }  
  25.   
  26.     @Override  
  27.     public boolean equals(Object o) {  
  28.         if (o instanceof Teacher_PK) {  
  29.             Teacher_PK pk = (Teacher_PK) o;  
  30.             if (this.id == pk.getId() && this.name.equals(pk.getName())) {  
  31.                 return true;  
  32.             }  
  33.         }  
  34.         return false;  
  35.     }  
  36.   
  37.     @Override  
  38.     public int hashCode() {  
  39.   
  40.         return this.hashCode();  
  41.     }  
  42.   
  43. }  

 

2.修改Teacher 类 

  1. package com.sccin.entity;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import javax.persistence.Entity;  
  6. import javax.persistence.GeneratedValue;  
  7. import javax.persistence.GenerationType;  
  8. import javax.persistence.Id;  
  9. import javax.persistence.IdClass;  
  10. import javax.persistence.Temporal;  
  11. import javax.persistence.TemporalType;  
  12. import javax.persistence.Transient;  
  13.   
  14. @Entity  
  15. @IdClass(Teacher_PK.class)  
  16. public class Teacher {  
  17.     private int id;  
  18.     private String name;  
  19.     private int age;  
  20.     private String title;  
  21.     private Date birthday;  
  22.   
  23.     private String youwifeName;  
  24.   
  25.     @Transient  
  26.     public String getYouwifeName() {  
  27.         return youwifeName;  
  28.     }  
  29.   
  30.     public void setYouwifeName(String youwifeName) {  
  31.         this.youwifeName = youwifeName;  
  32.     }  
  33.   
  34.     @Temporal(TemporalType.DATE)  
  35.     public Date getBirthday() {  
  36.         return birthday;  
  37.     }  
  38.   
  39.     public void setBirthday(Date birthday) {  
  40.         this.birthday = birthday;  
  41.     }  
  42.   
  43.     @Id  
  44.     public int getId() {  
  45.         return id;  
  46.     }  
  47.   
  48.     public void setId(int id) {  
  49.         this.id = id;  
  50.     }  
  51.   
  52.     @Id  
  53.     public String getName() {  
  54.         return name;  
  55.     }  
  56.   
  57.     public void setName(String name) {  
  58.         this.name = name;  
  59.     }  
  60.   
  61.     public int getAge() {  
  62.         return age;  
  63.     }  
  64.   
  65.     public void setAge(int age) {  
  66.         this.age = age;  
  67.     }  
  68.   
  69.     public String getTitle() {  
  70.         return title;  
  71.     }  
  72.   
  73.     public void setTitle(String title) {  
  74.         this.title = title;  
  75.     }  
  76.   
  77. }  

 

这样ID,与Name就作为一个联合的主键 





联合主键在Annotation中只需要在类上标识@IdClass(Teacher_PK.class)指定哪个类是联合主键类,

前言 1. 翻译说明 2. 版权声明 前言 1. 创建一个注解项目 1.1. 系统需求 1.2. 系统配置 2. 实体Bean 2.1. 简介 2.2. 用EJB3注解进行映射 2.2.1. 声明实体bean 2.2.1.1. 定义表(Table) 2.2.1.2. 乐观锁定版本控制 2.2.2. 映射简单属性 2.2.2.1. 声明基本的属性映射 2.2.2.2. 声明列属性 2.2.2.3. 嵌入式对象(又名组件) 2.2.2.4. 无注解之属性的默认值 2.2.. 映射主键属性 2.2.4. 映射继承关系 2.2.4.1. 每个类一张表 2.2.4.2. 每个类层次结构一张表 2.2.4.3. 连接的子类 2.2.4.4. 从父类继承的属性 2.2.5. 映射实体Bean的关联关系 2.2.5.1. 一对一(One-to-one) 2.2.5.2. 多对一(Many-to-one) 2.2.5.3. 集合类型 2.2.5.4. 用cascading实现传播性持久化(Transitive persistence) 2.2.5.5. 关联关系获取 2.2.6. 映射复合主键与外键 2.2.7. 映射二级表(secondary tables) 2.3. 映射查询 2.3.1. 映射EJBQL/HQL查询 2.3.2. 映射本地化查询 2.4. Hibernate独有的注解扩展 2.4.1. 实体 2.4.2. 标识符 2.4.3. 属性 2.4.3.1. 访问类型 2.4.3.2. 公式 2.4.3.3. 类型 2.4.3.4. 索引 2.4.3.5. @Parent 2.4.3.6. 生成的属性 2.4.4. 继承 2.4.5. 关于单个关联关系的注解 2.4.5.1. 延迟选项和获取模式 2.4.6. 关于集合类型的注解 2.4.6.1. 参数注解 2.4.6.2. 更多的集合类型 2.4.7. 缓存 2.4.8. 过滤器 2.4.9. 查询 3. 通过XML覆写元数据 3.1. 原则 3.1.1. 全局级别的元数据 3.1.2. 实体级别的元数据 3.1.3. 属性级别的元数据 3.1.4. 关联级别的元数据 4. Hibernate验证器 4.1. 约束 4.1.1. 什么是约束? 4.1.2. 内建约束 4.1.3. 错误信息 4.1.4. 编写你自己的约束 4.1.5. 注解你的领域模型 4.2. 使用验证器框架 4.2.1. 数据库schema层次验证 4.2.2. Hibernate基于事件的验证 4.2.3. 程序级验证 4.2.4. 验证信息 5. Hibernate与Lucene集成 5.1. 使用Lucene为实体建立索引 5.1.1. 注解领域模型 5.1.2. 启用自动索引 A. 术语表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值