Hibernate Annotation
Hibernate Annotation
用Annotation 写ORM关联数据库表确实要简单很多(主要是可以省略一个配置文件),所以在Hibernate中都喜欢用Annotation
这个用例中有关于ID生成策略(所以用到了联合主键),和属性是否与数据库映射,以及DATE类型的精度问题·····
准备工作:
1.Hibernate 3.3.2 下载 .html
下载所需要的Hibernate jar包和Annotation jar 包(注意,这里有版本兼容问题)
- Package Version Core Annotations EntityManager Validator Search Shards Tools
- 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.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 下载 / 下载slf4j_x.jar
因为hibernate 中的日志使用的slf,所以必须下载
注意(slf4j_api_x.jar 必须与 slf4j_aop_x.jar 版本对应)。
3.导入jar包
- <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-distribution-3.3.2.GA-dist/hibernate-distribution-3.3.2.GA/hibernate3.jar"/>
- <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"/>
- <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"/>
- <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"/>
- <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"/>
- <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"/>
- <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/hibernate-annotations.jar"/>
- <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/dom4j.jar"/>
- <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/ejb3-persistence.jar"/>
- <classpathentry kind="lib" path="E:/java/Hibernate/hibernate-annotations-3.4.0.GA/hibernate-annotations-3.4.0.GA/lib/hibernate-commons-annotations.jar"/>
- <classpathentry kind="lib" path="E:/java/sql连接/mysql-connector-java-5.1.11-bin.jar"/>
- <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 文档可以知道格式
- <?xml version='1.0' encoding='utf-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- ".0.dtd">
- <hibernate-configuration>
- <session-factory>
- <!-- Database connection settings -->
- <property name="connection.driver_class">org.hsqldb.jdbcDriver</property><!--数据库驱动-->
- <property name="connection.url">jdbc:hsqldb:hsql://localhost</property><!--数据库链接-->
- <property name="connection.username">sa</property><!--数据库用户名--!>
- <property name="connection.password"></property><!--密码--!>
- <!-- JDBC connection pool (use the built-in) -->
- <property name="connection.pool_size">1</property><!---->
- <!-- SQL dialect -->
- <property name="dialect">org.hibernate.dialect.HSQLDialect</property><!--数据库方言-->
- <!-- Enable Hibernate's automatic session context management -->
- <property name="current_session_context_class">thread</property>
- <!-- Disable the second-level cache -->
- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
- <!-- Echo all executed SQL to stdout -->
- <property name="show_sql">true</property>
- <!-- Drop and re-create the database schema on startup -->
- <property name="hbm2ddl.auto">create</property><!--生成建表语句,这里提供给我们4个值,查文档,试情况可以不写-->
- </session-factory>
- </hibernate-configuration>
4.写实体类 Teacher,
这里我们看不同主键(ID生成策略的代码)
1,Teacher类,ID为主键
- package com.sccin.entity;
- import java.util.Date;
- import javax.persistence.Entity;
- import javax.persistence.Id;
- import javax.persistence.Temporal;
- import javax.persistence.TemporalType;
- import javax.persistence.Transient;
- @Entity
- public class Teacher {
- private int id;
- private String name;
- private int age;
- private String title;
- private Date birthday;
- private String youwifeName;
- @Transient
- public String getYouwifeName() {
- return youwifeName;
- }
- public void setYouwifeName(String youwifeName) {
- this.youwifeName = youwifeName;
- }
- @Temporal(TemporalType.DATE)
- public Date getBirthday() {
- return birthday;
- }
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- @Id
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- }
注:在这个类里上写@Entity 我们要让ID为主键,只需要在getId()方法上写上@Id 就行了。
@Transient 表示该属性不与数据库表映射
@Temporal(TemporalType.DATE) 表示设置类型精度,这个字段为DATE类型,映射到数据库表中类型为Date,只有日期,没有时间精度
写好了实体类,需要把这个映射添加到hibernate.cfg.xml中
- <mapping class="com.sccin.entity.Teacher"/>
写个方法测试:
view plain copy to clipboard print ?
- //保存一个ID=1的Teacher的实体
- public void teachersave() {
- Teacher t = new Teacher();
- t.setId(1);
- t.setName("yang");
- t.setBirthday(new Date());
- t.setTitle("T1");
- t.setAge(20);
- Session session = sessionfactory.openSession();
- session.beginTransaction();
- session.save(t);
- session.getTransaction().commit();
- session.close();
- }
这里主键没有写生成策略,需要我们手动给主键设置值,很容易发生冲突。
我们一般把主键安装需求设置成它自动增长,有不同的策略。
看官方文档给我们的ID生成策略有哪些
当然这些很多不常用。
这里不做解释,看Annotation中怎么标识主键
需要在主键上增加一个@Id标识
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- public int getId() {
- return id;
- }
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(作为主键)
- package com.sccin.entity;
- import java.io.Serializable;
- public class Teacher_PK implements Serializable {
- private int id;
- private String name;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @Override
- public boolean equals(Object o) {
- if (o instanceof Teacher_PK) {
- Teacher_PK pk = (Teacher_PK) o;
- if (this.id == pk.getId() && this.name.equals(pk.getName())) {
- return true;
- }
- }
- return false;
- }
- @Override
- public int hashCode() {
- return this.hashCode();
- }
- }
2.修改Teacher 类
view plain copy to clipboard print ?- package com.sccin.entity;
- import java.util.Date;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.IdClass;
- import javax.persistence.Temporal;
- import javax.persistence.TemporalType;
- import javax.persistence.Transient;
- @Entity
- @IdClass(Teacher_PK.class)
- public class Teacher {
- private int id;
- private String name;
- private int age;
- private String title;
- private Date birthday;
- private String youwifeName;
- @Transient
- public String getYouwifeName() {
- return youwifeName;
- }
- public void setYouwifeName(String youwifeName) {
- this.youwifeName = youwifeName;
- }
- @Temporal(TemporalType.DATE)
- public Date getBirthday() {
- return birthday;
- }
- public void setBirthday(Date birthday) {
- this.birthday = birthday;
- }
- @Id
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- @Id
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- }
这样ID,与Name就作为一个联合的主键
联合主键在Annotation中只需要在类上标识@IdClass(Teacher_PK.class)指定哪个类是联合主键类,