目录
一、SessionFactory 接口
SessionFactory是生成Session的工厂,构造 SessionFactory 很消耗资源,一般情况下一个应用中只初始化一个 SessionFactory 对象。
1、初始化hibernate
先声明SessionFactory:
private static SessionFactory sessionFactory;
hibernate4.3之前的初始化方式:
Configuration cfg = new Configuration().configure(); //读取配置文件 StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); //创建服务注册对象 sessionFactory = cfg.buildSessionFactory(serviceRegistry); //创建会话工厂对象SessionFactory
hibernate4.3之后的初始化方式:
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build(); //读取配置文件 sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); //创建会话工厂对象
2、获取SessionFactory实例
// 获得SessionFactory的实例
public static SessionFactory getsSessionFactory() {
return sessionFactory;
}
3、创建获取Session
// 获得ThreadLocal对象管理的Session
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
// 通过SessionFactory对象创建Session对象
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
// 将Session对象保存到线程局部变量threadLocal中
threadLocal.set(session);
}
return session;
}
4、关闭Session和SessionFactory
// 关闭Session实例
public static void closeSession() {
// 从线程局部变量threadLocal中获取之前存入的Session实例
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
// 关闭缓存和连接池
public static void shutdown() {
getsSessionFactory().close();
}
最终配置
package com.utils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class LanUtils {
private static SessionFactory sessionFactory;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
// 创建线程局部变量threadLocal,用来保存Hibernate的Session
static { // 使用静态代码块初始化Hibernate
try {
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();
//读取配置文件
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
//创建会话工厂对象
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
// 获得SessionFactory的实例
public static SessionFactory getsSessionFactory() {
return sessionFactory;
}
// 获得ThreadLocal对象管理的Session
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
// 通过SessionFactory对象创建Session对象
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
// 将Session对象保存到线程局部变量threadLocal中
threadLocal.set(session);
}
return session;
}
// 关闭Session实例
public static void closeSession() {
// 从线程局部变量threadLocal中获取之前存入的Session实例
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
// 重建SessionFactory
public static void rebuildSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
// 关闭缓存和连接池
public static void shutdown() {
getsSessionFactory().close();
}
}
二、Session 接口
Session 是应用程序与数据库之间交互操作的一个单线程对象,生命周期很短,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。
Session 接口是 Hibernate 向应用程序提供的操作数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载 Java 对象的方法。
Session可能处于以下三种状态:
临时状态(transient): 不曾进行持久化,未与任何Session相关联,新建的对象。
持久化状态(persistent): 仅与一个Session相关联,从数据库读数据。脱管状态(detached): 已经进行过持久化,但当前未与任何Session相关联,数据库内未读的数据。
1、get()方法和load()方法:
二者区别:
当数据库中不存在与OID对应的记录时,load()方法抛出ObjectNotFoundException异常,而get()方法返回为NULL。
load方法采用配置的加载策略(默认为延迟加载),而get()方法则会忽略配置,总是采用立即加载方法。
Session接口提供了4个重载的get方法和重载的load()方法,分别通过“持久类+主键”和“全类名+主键”以及“锁选项”来获取实体对象。
public Object get(Class clazz, Serializable id);
public Object get(Class clazz, Serializable id, LockOptions lockOptions);
public Object get(String entityName, Serializable id);
public Object get(String entityName, Serializable id, LockOptions lockOptions);
Object load(String entityName, Serializable id, LockOptions lockOptions);
2、查询
Query createQuery(String hql)方法: 根据hql的查询语法查询表的内容,返回值为Query。
实例:
public List<User> findByHQL(String hql) {
List<User> list = new ArrayList<>();
Session session = HibernateUtil.getsSession();
list = session.createQuery(hql).list();
//list()方法:将上面方法返回的Query对象转换成List对象。
session.close();
return list;
}
3、保存
Session接口提供save()方法,将会将临时对象保存在Session缓存中,使其进入持久化,再选用映射文件指定的标识符生成器,为持久化对象分配唯一的ID,最后会计划执行一个insert语句将缓存内的对象存入数据库,其需要事务管理。
实例:
@Override
public void save(User user) {
// 创建Session实例
Session session = HibernateUtil.getsSession();
// 创建Transaction实例相当于事务
Transaction tx = session.beginTransaction();
try {
// 使用Session的save方法将持久化对象保存到数据库
session.save(user);
// 提交事务
tx.commit();
} catch (Exception e) {
e.printStackTrace();
// 出现异常,回滚事务
tx.rollback();
} finally {
// 关闭Session连接
HibernateUtil.closeSession();
}
}
4、删除
Session的delete()方法用于从数据库中删除一个java对象,其需要事务管理。delete()方法既可以删除持久化对象,也可以删除脱管对象。其处理过程如下:
(1)如果传入的参数是脱管对象,则先使脱管对象与Session关联,使它变为持久化对象。如果参数是持久化对象,则忽略该步。
(2)计划执行一个delete语句。
(3)把对象从Session缓存中删除,该对象进入删除状态。
实例:
public void delete(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
//事务开始
try {
session.delete(user);
tx.commit();
//提交事务
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
//回滚
} finally {
HibernateUtil.closeSession();
}
}
5、更新
Session的update()方法使一个脱管对象转变为持久化对象,其需要事务管理。它完成以下操作:
先将脱管对象加入到Session缓存中,使其转变为持久化对象,再计划执行一个update语句,将缓存内的对象与数据库同步。
实例:
@Override
public void update(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
try {
session.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
}
6、一个完整的DAO接口实现类
package org.hibernate.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.entity.HibernateUtil;
import org.hibernate.entity.User;
public class UserDAOImpl implements UserDAO {
// 添加用户,需要事务管理
@Override
public void save(User user) {
// 创建Session实例
Session session = HibernateUtil.getsSession();
// 创建Transaction实例
Transaction tx = session.beginTransaction();
try {
// 使用Session的save方法将持久化对象保存到数据库
session.save(user);
// 提交事务
tx.commit();
} catch (Exception e) {
e.printStackTrace();
// 出现异常,回滚事务
tx.rollback();
} finally {
// 关闭Session连接
HibernateUtil.closeSession();
}
}
// 根据id查找用户 ,可以不需要事务管理 Get方式
@Override
public User findByIdGet(int id) {
User user = null;
Session session = HibernateUtil.getsSession();
// 使用session的get方法获取指定id的用户
user = (User) session.get(User.class, id);
if (user == null || "".equals(user)) {
System.out.println("查询id为:" + id + "无结果....");
}
session.close();
return user;
}
// 根据id查找用户 ,可以不需要事务管理 Load方式
@Override
public User findByIdLoad(int id) {
User user = null;
Session session = HibernateUtil.getsSession();
// 使用session的方法获取指定id的用户
user = (User) session.load(User.class, id);
if (user == null || "".equals(user)) {
System.out.println("查询id为:" + id + "无结果....");
}
session.close();
return user;
}
// 根据HQl语句查询
@Override
public List<User> findByHQL(String hql) {
List<User> list = new ArrayList<>();
Session session = HibernateUtil.getsSession();
list = session.createQuery(hql).list();
session.close();
return list;
}
// 删除用户 ,需要事务管理
@Override
public void delete(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
try {
session.delete(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
// 修改用户
@Override
public void update(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
try {
session.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
}
三、Transaction事务管理
Transaction对象用于管理对数据库的事务操作。通过Transaction对象,可以控制和管理一系列数据库操作,确保它们作为一个原子操作进行执行,以确保数据的一致性和完整性。
其中插入(保存)、删除、更新操作需要事务进行管理。
具体代码结构
// 获取当前线程绑定的Session
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
try {
// 执行数据库操作(增删改查)
// 提交事务
tx.commit();
} catch (Exception e) {
// 发生异常时回滚事务
if (tx != null) {
tx.rollback();
}
} finally {
// 关闭Session
session.close();
}