一、Hibernate基础
1.Hibernate简介
Hibernate是一种对象关系映射(ORM)框架,是实现持久化存储的一种解决方案。Java包括Java类到数据库表的映射和数据查询及获取的方法,能够大大减少开发人员使用JDK和SQL处理数据的时间。
2.Hibernate获取
Hibernate的官网是http://www.hibernate.org,需要的时候可以去官网上下载相关的版本。
3.Hibernate配置
在一个项目中有时候不需要Hibernate中的全部jar包,所以当项目用到Hibernate的时候可以将相关jar包复制到项目的classpath/WebContent/WEB-INF/lib下面;或者在项目中建立一个Library加载Hibernate的jar包。
4.Hibernate配置文件
Hibernate的配置文件一般命名为hibernate.cfg.xml,这个配置文件默认存储在项目的classpath根目录下。下面以一个具体的配置文件说明hibernate配置文件的相关知识
<?xml version='1.0' encoding='utf-8'?> <!-- 这是一个xml文件头,定义版本和编码 -->
<!DOCTYPE hibernate-configuration PUBLIC
"_//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- hibernate独有的,建议写上 -->
<hibernate-configuration>
<session-factory>
<property name="driver_class">com.mysql.jdbc.Driver</property> <!-- 数据库驱动,这个是MySQL的驱动 请加载你相应数据库的驱动 -->
<property name="url">jdbc:mysql://localhost:3306/test</property> <!-- 数据库连接的URL -->
<property name="username">root</property> <!-- 数据库连接用户名 -->
<property name="password">passwd</property> <!-- 数据库连接密码 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- hibernate方言 -->
<property name="show_sql">true</property> <!-- 打印SQL语句 -->
<mapping resource="com/lyq/User.hbm.xml" /> <!-- 映射文件,可以用这个属性改变映射文件的位置和名称 -->
</session-factory>
</hibernate-configuration>
关于配置文件作如下解释:
<hibernate-configuration>是配置文件的根元素;
<session-factory>元素通常只有一个,其包含有多个<property>和<mapping>子元素用来配置Hibernate属性信息;
<mapping>元素用来配置持久化类映射文件的相对路径;
<property>元素的常用属性及说明如下:
connectio.driver_class:设置数据库驱动;
connection.url:设置数据库连接的URL;
connection.username:设置连接数据库所使用的用户名;
connection.password:设置连接数据库所使用的密码;
dialect:设置连接数据库所使用的Hibernate方言;
show_sql:是否打印SQL语句;
format_sql:设置是否对SQL语句进行格式化;
hbm2ddl.auto:设置自动建表。
5.Hibernate的核心接口
Hibernate的核心接口主要有五个:
(1)Session接口:负责执行被持久化对象的CRUD操作,需要注意的是Session对象是非线程安全的;
(2)SessionFactory接口:负责初始化Hibernate,他充当数据存储源的代理,并负责创建Session对象;
(3)Configuration接口:负责配置并启动Hibernate,创建SessionFactory对象;
(4)Transaction接口:负责事务相关的操作(可选);
(5)Query接口:负责执行各种数据库查询。
二、持久化对象(数据库对象映射)
1.持久类的编写
持久类是Hibernate操作的对象,它与数据库中的数据表相对应,描述数据表的结构信息。下面是一个学生类student.java
public class Student{
private String id; //id编号
private String name; //姓名
private boolean sex; //性别
//参数的setter和getter方法
}
编写Hibernate的持久类时候需要注意以下几点:声明一个默认的、无参的构造方法;类的声明是非final类型的;拥有一个标识属性;为属性声明getter和setter方法。
2.映射文件的编写
Hibernate的映射文件与持久类相互对应,映射文件指定持久类与数据表之间的映射关系。Hibernate的映射文件的命名规则是*.hbm.xml。上面student类的映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"_//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="持久类的全名" table="数据表名">
<id name="id" column="id" type="String">
<generator class="native"></generator>
</id>
<property name="name" type="String" not-null="true" length="50">
<column name="name"></column>
</property>
<property name="sex" type="boolean">
<column name="sex" />
</property>
</class>
</hibernate-mapping>
关于持久类的映射文件作如下解释:
<hibernate-mapping>元素是映射文件的根元素,其常用的属性主要是package属性,用来指定包名;
<class>元素用于指定持久化类和数据表的映射,其属性中的table属性用于指定数据表的名称,name属性指定持久化类的完整类名(包含包名),但是当<hibernate-mapping>中指定package属性时可以不指定包名;上述<class>中包含<id>和<property>,下面分别介绍
<id>元素对应数据表中的标识,指定持久化类的OID和表主键的映射;<id>通过name属性指定持久化类中的属性,column属性指定数据表中的字段名称,type属性用于指定字段的类型。<id>的子元素<generator>用于配置数据表主键的成长策略,主键生成策略标识如下:
increment:适用于代理主键,由Hibernate以自增的方式生产,增量为1;
identity:适用于代理主键,由底层数据库生成,前提是底层数据库支持自增字段类型;
sequence:适用于代理主键,Hibernate根据底层数据库的序列生成,前提条件是底层数据库支持序列;
hilo:适用于代理主键;
native:适用于代理主键,根据底层数据库对自动生成标识符的支持能力,选择identity、sequence和hilo;
uuid:适用于代理主键,不推荐使用,因为字符串型要比整形占用更多的数据库空间;
assigned:适用于自然主键,由Java应用程序负责生成;
<id>的子元素<property>元素描述数据表中字段的属性,用于配置数据表中字段的属性信息,通过此元素能够详细地对数据表的字段进行描述。<property>元素的常用配置属性及说明如下:
name:指定持久化类中的属性名称;
column:指定数据表中的字段名称;
type:指定数据表中的字段类型;
not-null:指定数据表字段的非空属性,它是一个布尔值;
length:指定数据表中的字段长度;
unique:指定数据表字段值是否唯一,它是一个布尔值;
lazy:设置延迟加载。
3.映射关系的使用
持久化对象使用最频繁的操作是增删改查的操作,所以在下文中介绍对映射关系的使用。
三、关联关系映射
映射在Hibernate中发挥着重大的作用,它将实体对象映射成数据表,实体对象的属性映射成数据表中的字段,另外,实体之间的关联关系也是通过映射实现的。其实关联类型分两种:
单向关联:具有关联关系的实体对象之间的加载关系是单向的;
双向关系:具有关联关系的实体对象之间的加载关系是双向的。
1.一对多的关联关系
再建一个类class.Java,包含id,classname和student三个变量。如下:
public class Class {
private int id;
private String classname;
private Ser<Student> studentes;
//相应的getter和setter方法
}
这时,映射文件class.hbm.xml的内容主要部分如下:
<set name="students"> <!-- Set为我们在class.java中定义的集合 -->
<key column="id"></key> <!-- 外键名称 -->
<one-to-many class="....../student.java" /> <!-- 一对多关系的对应的类,类名的全称 -->
</set>
除了Set集合,还有List、Map等集合。映射文件的写法大同小异,如下:
<!-- 映射集合属性studentes,指定存放集合属性的表明 -->
<list name="studentes" table="student">
<!-- 集合属性和持久化类的关联外键 -->
<key column="id" not-null="true"/>
<!-- 集合属性的次序列 -->
<list-index column="list-order"/>
<!-- 集合属性的元素 -->
<element type="String" column="name" />
</list>
<!-- 映射Map 集合属性 -->
<map name="student" table="student">
<key column="id" not-null="true"/>
<map-key column="name" type="String"/>
</map>
2.多对一的关联关系
将上面的一对多的关系颠倒过来就是多对一的关联关系了。假设在学生类中加一个班级属性,两个类如下:
public class student {
private int id;
private String name;
private Stirng sex;
private Great great;
//相应的getter和setter方法
}
public class Great{
private int id;
private String name;
//相应的getter和setter方法
}
在student.hbm.xml里面的主要语句如下:
<!-- 多对一的映射关系 -->
<many-to-one name="great" column="great_id"></many-ro-one>
3.多对多的关联关系
学生和课程之间就是一个常见的多对多的关系,一个学生可以选多门课、一门课也可以被多个学生选择。假设课程类Course.java如下:
public class Course{
private String name;
private int core;
private Set<Student> students;
//相应的getter和setter方法
}
这时,应该在student.java中增加一个属性private Set<Course> course;
student.hbm.xml中的主要配置如下:
<!-- cascade="save-update"表示在保存和更新当前对象时,级联保存和更新附属对象 -->
<!-- inverse="true"表示该对象不维护关系(一般由一边来维护,下面会介绍让course维护) -->
<!-- table="sc_table"表示中间表 -->
<set name="courses" cascade="save-update" inverse="true" table="sc_table">
<!-- column为中间表 参照student_table的外键 -->
<key column="stu_id" not-null="true"></key>
<!-- 多对多的关系映射 -->
<map-to-many class="Course" column="cor_id"></map-to-many>
</set>
course.hbm.xml中的主要配置如下:
<!-- 主要这里没有inverse属性,由course这边维护映射关系 -->
<set name="student" cascade="save-update" table="sc_table">
<key column="cou_id" not-null="true"></key>
<map-to-many class="student" column="stu_id"></map-to-many>
</set>
四、Hibernate对数据库的操作——增删改查
1.Hibernate的初始化
使用Hibernate操作数据库时首先应该创建和初始化Hibernate。
1.1创建Hibernate——使用SessionFactory
默认情况下,Hibernate会加载classpath目录下的Hibernate.cfg.xml文件,格式如下:
Configuration cfg = new Configuration().configure();
实例化SessionFactory的代码如下:
SessionFactory factory = cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());
2.获取session
代码如下:
Session session = (Session)threadLocal.get();
if( session == null || !session.isOpen() ){
session = (sessionFactory != null)sessionFactory.openSession() : null;
}
3.开启事务
session.beginTransaction();
还有一个提交事务:session.getTransaction().commit();
4.添加数据
添加数据的语法格式如下:
public Serializable save(Object obj) throws HibernateException
比如添加student的代码:session.save(student);
5.删除数据
删除数据的语法格式如下:
public void delete(Object obj) throws HibernateException
但是因为要删除的对象并不在Session的管理之中,通过Session并不能对其进行删除操作,所以需要将要删除的对象转换为持久状态,使其处于Session的管理之内,再用上述方法将数据删除。
比如删除student的代码:
Student student = (Student)session.load(Student.class,new Integer(001));
session.delete(student);
6.查询数据
Session接口提供了两个加载数据的方法,即get()和load()方法。这两个方法都可用于加载数据,但是两者之间存在一定的区别。get()方法返回实际对象;load()方法返回对象的代理,只有在被调用时,Hibernate才会发出SQL语句去查询对象。
6.1 get()方法
get()方法的语法格式如下:
public Object get(Class entityClass, Serializable id) throws HibernateExcetion
其中,entityClass:持久化对象的类;id:标识;返回值:持久化对象或null值。
例如:Student student = (Student)session.get(Student.class,new Integer(1));
6.2 load()方法
load()方法的语法格式如下:
public Object load(Class entityClass, Serializable id) throws HibernateException
各个参数的解释同上。
例如:Student student = (Student)session.load(Student.class,new Integer(1));
当调用Session的load()方法时,Hibernate并不会立刻发出SQL语句进行查询,只有在引用对象时才会发出SQL语句。
7.修改数据
Hibernate对数据的修改主要有两种情况:1)当实例对象处于Persistent(持久)状态时,对于它所发生的任何更新操作,Hibernate在更新缓存时都会对其进行自动更新;2)Session接口提供了update()方法,调用此方法可对数据进行手动更新。
7.1自动更新
自动更新在操作之前需要加载数据,因为要修改的数据并没有处于Session的管理之内。
Student student = (Student)session.load(Student.class,new Integer(1)); //加载Student对象
student.setName("test"); //修改名称
session.getTransaction().commit(); //提交事务
7.2手动更新
手动更新语法格式如下:
public void update(Object obj) throws HibernateException
例如:
//手动创建的Detached状态的药品对象
Student student = new Student();
student.setId(1);
student.setName("test");
student.setSex(true);
//更新student信息
session.update(student);
//提交事务
session.getTransaction().commit();
五、写在最后
关于Hibernate的基础知识就这些了,或许不够全面,但是根据这些知识足够建立一个Hibernate项目了。
Hibernate还有些高级应用,例如一级缓存、二级缓存、HQL检索方式等等,以后有时间在写学习笔记。