Hibernate简介
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
那么为什么要使用hibernate呢?
使用hibernate是为了简化开发,从设计上来说,目的是为了解决面向对象语言操作关系型数据库出现的不匹配问题(模型不匹配、阻抗不匹配):
Java面向对象语言,对象模型,主要的概念有:继承、关联、多态等;数据库是关系模型,主要概念有:表、外键、主键等。
这个问题可以通过jdbc手工实现这种映射,但是这种映射工作量比较大,特别当对象模型比较复杂的时候,比如说有继承,有关联的时候,用jdbc实现会非常的复杂,所以最终引入了ORM(Object Relation Mapping,对象关系映射)框架来解决,主流的ORM框架有Hibernate、TopLink、OJB等。
Hibernate开发环境搭建
这里使用的hibernate版本是3.5.3
1.引入相关的jar文件:一般包括hibernate3.jar、antlr-2.7.6.jar、commons-collections-3.1.jar、dom4j-1.6.1.jar、javassist-3.9.0.GA.jar、jta-1.1.jar、slf4j-api-1.5.8.jar和slf4j-nop-1.5.8.jar。
2.编写映射文件(可以从hibernate解压路径下面的project\tutorials\eg下面拷贝User.hbm.xml),然后根据自己的需要在此基础上修改。
3.编写配置文件(可以从hibernate解压路径下面的project\etc下面拷贝hibernate.cfg.xml),然后在这个基础上根据自己的实际需要去修改。
注意:配置文件有XML和properties两个格式的,即hibernate.cfg.xml和hibernate.properties,这两个文件的作用一样,提供一个即可,推荐XML格式,刚才拷贝的那个hibernate.cfg.xml就是一个例子。
在配置文件中需要指定:
数据库的URL、用户名、密码、JDBC驱动、方言等等。
启动时hibernate会在CLASSPATH下面找这个文件。
开发流程
使用hibernate的时候会牵扯到几种文件:java文件(java类|对象)、映射文件和数据库表结构ddl文件。这三个文件一般有一个,就可以创建出其他的两个。有以下几种流程:
1.由Domain Object->mapping->db(官方推荐)
2.由db开始,用工具生成mapping和Domain Object(使用较多)
2.由映射文件开始
Domain Object的限制
1.默认的构造方法(必须有)
2.有无意义的标示符id(主键)
3.非final的,对懒加载有影响
例如:
public class User {
private int id;
private String username;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
映射文件示例(User.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="zhchljr.domain">
<class name="User">
<id name="id">
<generator class="native"/>
</id>
<property name="username"></property>
<property name="birthday"></property>
</class>
</hibernate-mapping>
这是个简单的例子,配置文件的详细说明,参见hibernate官方文档。
相关的一些代码
1.初始化代码(只做一次,可以放在工具类的static块中)
Configuration cfg = new Configuration();
cfg.configure();//当配置文件的名字和默认的不一样时,可以在这里指定。
SessionFactory sessionFactory = cfg.buildSessionFactory();
2.通用代码
Session s = null;
Transaction tx = null;
try {
s = sessionFactory.openSession();
tx = s.beginTransaction();
//操作数据的代码,save、update、delete、get等
tx.commit();
} catch (HibernateException e) {
if(tx != null) {
tx.rollback();
throw e;//这里最好能抛出异常
}
} finally {
if(s != null) {
s.close();
}
}
Session的几个主要方法
1.save,persist 保存数据,persist在事务外不会产生sql语句。
2.delete 删除对象
3.update 更新对象,如果数据库中没有记录,会报异常
4.get 根据ID,会立即查询数据库
5.load 根据ID,返回的是代理,不会立即访问数据库
6.saveOrUpdate,merge 根据ID和version的值来确定是save,还是update,调用merge,你的对象还是脱管的。
7.lock把对象变成持久对象,但不会同步对象的状态。
对象状态
瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象
持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交。持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)
脱管(detached):数据库中有数据与之对应,但当前没有session与之相关联。脱管对象状态发生改变,hibernate不能检测到。
判断对象状态的两个依据:是否在数据库中有记录,是否与session相关联。
对象之间状态的转换如下图所示:
HQL和Criteria
1.HQL(Hibernate Query Language)
面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了java类和属性其他部分不区分大小写);HQL中查询的是对象,而不是表,并且支持多态;HQL主要通过Query来操作,Query的创建方式如下:
Query q = session.createQuery(hql);
(1)from Person
(2)from User user where user.username=:username
(3)from User user where user.username=:username and user.birthday<:birthday
2.Criteria
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式如下:
Criteria crit = s.createCriteria(DomainClass.class);
简单属性条件添加,如:
crit.add(Restrictions.eq("username", name));
crit.add(Restrictions.eqProperty(propertyName, otherPropertyName));