一、Hibernate持久化类的编写规则
持久化类:
一个Java对象与数据库的表建立了映射关系,那么这个类在hibernate中成为持久化类
编写规则:
- 对持久化类提供一个无参的构造方法(Hibernate底层需要使用反射生成实例)
- 属性为private,对私有属性提供public的get和set方法(Hibernate中获取,设置对象的值)
- 对持久化类提供一个唯一标识OID与数据库主键对应(Java中通过对象地址区分是否是同一个对象,数据库通过主键值确定是否是同一个纪录,Hibernate通过持久化类的OID的属性区分是否是同一个对象)
- 持久化类不能使用final进行修饰(如为final,则load方法无法返回代理对象,因为不能继承这个类进行代理。此时load和get方法一致)
二、主键生成策略
2.1 主键分类
-
自然主键:主键本省就是表中所用的字段,即实体中的一个具体的属性
-
代理主键:主键本省不是表中的字段,即不是实体中某个具体的属性
使用代理主键较好,方便后期修改属性
2.2 主键的生成策略
在Hibernate中,id元素的子元素用于生成持久化类的对象的主键生成策略
<!-- 主键生成策略 -->
<generator class="native"></generator>
hibernate提供了多种主键生成策略:
increment :
Hibernate中的自动增长机制,适用于short、int、long类型的主键。在单线程程序中使用。
identity :
数据库底层的自动增长机制,适合short、int、long类型的主键
sequence :
采用序列方式,适用于short、int、long类型的主键
uuid :
采用Hibernate中随机方式生成字符串主键,适用于字符串类型主键
native :
本地策略,在identity和sequence之间进行自动切换
assigned :
Hibernate不管理外键,需用户设置
foreign :
外部的,一对一的关系映射下使用
三、持久化类的三种状态
3.1 瞬时态(transient)
瞬时态:没有唯一标识OID,没有被session管理
3.2 持久态(persistent)
持久态:有唯一标识OID,被session管理
3.3 托管态(detached)
托管态:有唯一标识OID,没有被session管理
3.4 状态列子:
package com.hibernate.user.demo;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.hibernate.utils.HibernateUtils;
/**
* hibernate测试案例
*
* @author cf
*
*/
public class HibernateTestDemo01 {
@Test
// 保存用户
public void demo01() {
//获取连接
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 执行代码
User user = new User(); //瞬时态对象:无OID,无session管理
user.setName("星星");
Serializable id = session.save(user); //持久态对象:有OID,被session管理
session.get(User.class, id);
// 事务提交
transaction.commit();
//资源释放
session.close();
System.out.println(user);//托管态对象:有OID,无session管理
}
}
3.5 持久态对象特征:
持久态对象可以自动更新数据库
@Test
// 自动更新数据库
public void demo02() {
//获取连接
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 执行代码
User user = session.get(User.class, 1);
user.setEmail("123456789@qq.com");
user.setPassword("654321");
user.setTelephone("13388888888");
//session.update(user); 自动更新,此句可以省略
// 事务提交
transaction.commit();
//资源释放
session.close();
}
结果如下:
以上代码再重复执行一次,结果如下:
并无更新,仅执行查询。
底层原理为一级缓存,下一节介绍
四、一级缓存
Hibernate提供了一级缓存和二级缓存来提供应用程序的性能。本章先介绍一级缓存。
一级缓存:
session对象保存了一级缓存,默认情况下启用。不可用于整个应用程序,生命周期同session一致。
@Test
// 一级缓存
public void demo03() {
// 获取连接
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 执行代码
//第一次查询user
User user = session.get(User.class, 1);
System.out.println(user);
//第二次查询user
User user1 = session.get(User.class, 1);
System.out.println(user1);
//判断两次user是否相同
System.out.println(user == user1);
// 事务提交
transaction.commit();
// 资源释放
session.close();
}
结果如下:
可以看出,结果查询语句仅执行了一次,第二次从一级缓存中取出。
使用session.clear()可以清空一级缓存
五、事务
事务具有ACID属性(原子性,一致性,隔离性和持久性)。
5.1 设置事务的隔离级别:
在核心配置文件hibernate.cfg.xml中使用一下语句配置隔离级别
<!-- 事务隔离级别
hibernate.connection.isolation - 4
1 - Read uncommitted isolation
2 - Read committed isolation
4 - Repeatable read isolation
8 - Serializable isolation
-->
<property name="hibernate.connection.isolation">4</property>
5.2 Service层使用事务
dao层和Service层需保证连接对象是同一个
1.HibernateUtils.java中增加getCurrentSession方法
package com.hibernate.utils;
/**
* Hibernate的工具类
* @author cf
*
*/
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
2.核心配置文件增加以下配置
<!-- 配置当前线程绑定的session -->
<property name="hibernate.current_session_context_class">thread</property>
此时session在线程结束后会自动关闭,session.close()语句可以省略。