引入相关的包
注:实验时出现了报错信息,需要加入新的jar包
hibernate-jpa-2.0-api-1.0.0.Final.jar
而上述的ejb3-persistence.jar是与其重复冲突的(ejb3-persistence.jar本来就是属于实现了jpa标准的annotation的实现),故还需要把ejb3的jar包删掉。
又由于Hibernate3.5集成了annotations,故可以删除
hibernate-commons-annotations.jar,hibernate-annotation.jar,hibernate-entitymanager.jar。不删除往往会出现比较奇怪的错误。
(2)创建相关的数据库和表
(3)配置文件hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver</property>
<property name="connection.url">
jdbc:mysql://localhost/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<!--<property name="connection.pool_size">1</property>
-->
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect</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>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!--<property name="hbm2ddl.auto">update</property>
-->
<mapping
resource="com/yilong/hibernate/model/Student.hbm.xml"/>
<!— -注解方式
<mapping class="com.yilong.hibernate.model.Husband"/>
<mapping class="com.yilong.hibernate.model.Wife"/>
--!>
</session-factory>
</hibernate-configuration>
(4)建立相关的类(class)
(5)建立该类的映射文件 class.hbm.xml并进行相关的映射配置
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yilong.hibernate.model">
<class name="Student" table="student" >
<id name="id" column="id"></id>//表示主键
<property name="name"></property>
<property name="age"></property>
</class>
</hibernate-mapping>
或者使用annotation注解的方法:
@Entity//实体与表的对应
public class Teacher {
private int id;
private String name;
private String title;
@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 String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
分别位于包:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
说明:hibernate有自己的Annotation实现,在org.hibernate包,但是推荐使用实现了jpa接口的Annotation的实现。
可见,已经不再依赖hibernate,而是实现了jpa接口的一种annotation的具体实现。
历史:SUN公司设计出的ejb2.0、ejb2.1比较不成熟,使用比较不方便,于是有人设计了Hibernate并很快流行起来。SUN公司见Hibernate使用方便,就把设计Hibernate的人聘请了过来设计出了ejb3,并定义了一套具体的标准jpa。Hibernate为了支持官方版的标准,定义了Hibernate Annotation。
注:annotation为hibernate对JPA接口的一种实现方式。Annotation的注解可以放在成员变量上,也可以放在get方法上,但是写在成员变量field上似乎破坏了private属性的意义,故一般写在get方法上面。要保持field和set、get方法的一致性。“约定优于配置”。
<property name="hbm2ddl.auto">update</property>表示是否设置hbm(hibernate mapping)到ddl(data definition language)的转换。常用的设置为:
<property name="hbm2ddl.auto">create</property>
其中update表示如果不存在指定的表的时候,自动进行创建,然后更新,有则只进行更新;而create则不论情况直接创建(有就先删除再创建),再进行更新,但是如果只是改变表中的数据类型的时则不会自动进行创建。如果没有设置该属性,如果遇到不存在指定的表,那么就会报错。除此之外,设置了该属性在程序运行时还会生成sql语句,也可以在xml配置中不设置,改为在程序中设置:
new SchemaExport(new AnnotationConfiguration().configure())
.create(true, true);
注:create方法中
第一个参数设置为true,则表示会print the DDL to the console
第二个参数设置为true,则表示会export the script to the database
另外:
<property name="show_sql">true</property>表示是否在命令行输出sql语句<property name="format_sql">true</property>表示是否格式化sql语句的输出,是两个比较常设置的基本配置。
使用注解的方式往往会出现一下几个问题:
问题一:实体名和表名不一样时。可以用@Table(name=”表名”)说明,即例如:
@Entity
@Table(name=”_Teacher”)
如果使用xml文件的形式,则可以使用table=”表名”说明,即例如:
<class name="Student" table="student" >
需要注意的是使用xml文件的形式,如果不设置<property>属性,则不会自动对该属性进行映射,而使用annotation没加注解的属性默认帮你进行映射,相当于加上了@Basic注解。
问题二:字段名和属性名不同。使用@Column(name=”_字段名”)进行说明。例如:@Column(name=”_name”)。同样地,对于使用xml文件的情况,则可以使用column属性进行映射:
<id name="id" column="id"></id>
或者<property name=”name” column=”_id”></property>
问题三:某些字段不需要persistence的情况。
Annotation使用注解:@Transient(透明的);xml不写即可。
问题四:映射日期与时间类型,指定时间精度。
private Date birthDate;
默认情况下,在teacher.setBirthDate(new Date())后,会在数据库中记录时间和日期,而有的时候需要指定存储的时间精度:
@Temporal(value=”TemporalType.TIMESTAMP”)//记录时间和日期
@Temporal(TemporalType.DATE)//只记录日期(可以省略value)对应数据库DATE
@Temporal(TemporalType.TIME)//只记录时间
对应用xml方式实现如下:
<property name=”birthDate” type=”date”></property>
<property name=”birthDate” type=”time”></property>
注意:在hibernate注解中如果属性值的名字属于value,那么可以省略,即默认value。
问题五:hibernate的枚举类型。
Hibernate对一些常用的基本类型(int, char, long等)与一些常用类(Date, String, Timestamp等)内置了转换器,使得数据库里面的类型能顺利地与实体类的属性对应上。但是有些时候,需要自己定义一个转换器,比较常见的就是枚举类型,hibernate用xml映射枚举类型比使用annotation进行映射麻烦。
使用xml配置:
l 先定义一个实现了UserType接口的类(如:EnumType),表示该类型是用户自定义的;
l 然后实现接口的方法,通过重写equals方法测试属性是否进行了更改;
l 。。。。。。(比较复杂)
使用annotation(比较简单),只需要添加@Enumrated注解:
@Enumerated(EnumType.STRING)
或者:@Enumerated(EnumType.ORDINAL)
不同之处在于生成的数据库的对应字段的类型不同:
EnumType.STRING:
EnumType.ORDINAL:
其中ZhiCheng是enum类型的对象:
具体设置值:
(6)创建session,并调用相关的方法执行sql语句
方法一:使用xxx.hbm.xml配置
Student s = new Student();
s.setId(1);
s.setName("yilong");
s.setAge(22);
Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(s);
session.getTransaction().commit();
session.close();
sf.close();
方法二:使用注解的方式(写在get方法的上面)
Teacher t = new Teacher();
t.setId(2);
t.setName("yilong");
t.setTitle("中级");
Configuration cfg = new AnnotationConfiguration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
sf.close();
而对于此,hibernate也对创建sessionFactory对象设计了一个辅助类HibernateUtil。由于SessionFactory只需要实例化一次即可,故该类设计成单例模式,可直接调用:
SessionFactory sessionFactory = HibernateUtil.getSessionFactory() 以下是该类的具体内容:
由上图不难看出,hibernate起着O/R Mapping的作用,即将面向关系型的数据库设计改成了面向对象的数据库设计。
一些常见的O/R Mapping Frameworks包括:hibernate、toplink、jdo、ibatis、jpa(意愿一统天下)