既然Hibernate 实现了对JDBC的轻量级封装,增加了可移植性,那么在CRUD操作上是否也可将起封装,增加其扩展性。答案肯定是可以的。所以就有了今天的基于泛型DAO,网上有很多是在Spring 和 Hibernate 混合框架的泛型DAO,其实就是Spring 在对 Hibernate 的Session 做了一个封装,此博文是针对以Hibernate框架的泛型DAO设计。
由于我们通常要读取hibernate.cfg.xml,创建一个session factory,在取出一个session 对其进行CRUD操作,所以,这部分代码一般可以写在static块中,但为了模块化,我们将其中写在一个单独的类HibernateUtil(官方建议)中。
package com.feytuo.education.persistence;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
/**
* 获取会话HibernateUtil封装类
*
* @author YangKang
*
* @date 2014/04/27
*
* @version 1.0
*
*
*/
public class HibernateUtil {
private static SessionFactory sessionFactory = null;
/**
*
* @return 获取当前会话工厂
*/
public static SessionFactory getSessionFactory() {
if (null == sessionFactory) {
CreateSessionFactory();
}
return sessionFactory;
}
/**
* 创建会话工厂
*/
private static void CreateSessionFactory() {
// 第一步:读取Hibernate的配置文件 hibernamte.cfg.xml文件
Configuration config = new Configuration().configure();
// 第二步:创建服务注册构建器对象,通过配置对象中加载所有的配置信息
StandardServiceRegistryBuilder regbulider = new StandardServiceRegistryBuilder()
.applySettings(config.getProperties());
// 创建注册服务
ServiceRegistry sry = regbulider.build();
// 第三步:创建会话工厂
sessionFactory = config.buildSessionFactory(sry);
}
public static void createTables(){
Configuration config = new Configuration().configure();
new SchemaExport(config).create(false, true);
}
/**
* @return 获取当前会话对象
*/
public static Session getSession() {
return getSessionFactory().getCurrentSession();
}
public static void sfClose() {
getSessionFactory().close();
}
public static void sessionClear() {
getSession().clear();;
}
}
接下来设计基于泛型DAO的接口
包括常用 的CRUD操作和分页功能。
package com.feytuo.education.persistence;
import java.util.List;
/**
*
* 用hibernate框架HQL检索
*
* 对数据库中表各个表的增删查改CRUD操作接口
*
* @author YangKang
*
* @param <T>
* 泛型 ,实体类
* @param <PK>
* 泛型,实体类的主键类型
*
* @date 2014/04/25
*
* @version 1.0
*
* @revise 2014/04/30 V1.1
*
*/
public interface IBaseDAO<T, PK> {
/**
* 保存指定实体
*
* @param entity
* 实体对象
*/
public void save(T entity);
/**
* 更新指定实体
*
* @param entity
* 实体对象
*/
public void update(T entity);
/**
* 删除指定实体
*
* @param entity
* 实体对象
*
*/
public void delete(T entity);
public void saveOrUpdate(T entity);
/**
* 删除实体
*
* @param entityClass
* 实体类名
* @param id
* 实体的id
*/
public void deteleById(Class<T> entityClass, PK id);
/**
* 更新实体 可用于添加 ,修改,删除操作
*
* @param hql
* 执行的的hql语句
* @param params
* 参数,可有对象或多个对象,代替Hql中的"?"号
*/
public void execute(final String hql, final Object[] params);
/**
* 获取所有实体集合
*
* @param entityClass
* 实体类名
* @return 结果集合
*/
public List<T> query(Class<T> entityClass);
/**
* 按HQL条件查询列表
*
* @param entityClass
* 实体类名
* @param id
* 实体id
* @return 实体对象
*/
public T findById(Class<T> entityClass, PK id);
/**
* 按具体属性内容查询
*
* @param entityClass
* @param propertyName
* @param value
* @return
*/
public T findByProperty(Class<T> entityClass, String propertyName,
Object value);
/**
* 按hql条件查询列表
*
* @param hql
* 查询语句 支持连接查询和多条件查询
* @param params
* @return
*/
public List<T> findByHql(String hql, Object[] params);
/**
* 查询指定sql语句的分页数据集合
*
* @param entityClass
* @param start
* @param limit
* @return
*/
public List<T> findByPage(Class<T> entityClass, int start, int limit);
/**
* 查询指定sql语句的分页数据集合
*
* @param hql
* @param params
* @param start
* @param limit
* @return
*/
public List<T> findByPage(String hql, Object[] params, int start, int limit);
}
DAO类的实现。
package com.feytuo.education.persistence;
import java.io.Serializable;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
/**
* Hibernate 框架<br />
*
* 实体类的增删查改实现类
*
* @author YangKang
*
* @param <T>
* 实体类名
* @param <PK>
* 实体类的主键类型
*
* @date 2014/04/30
*
* @version 1.0
*
* @revise 2014/05/02 V1.1
*/
public class BaseDAO<T, PK extends Serializable> implements
IBaseDAO<T, PK> {
/**
* 添加实体
*/
@Override
public void save(T entity) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.save(entity);
session.getTransaction().commit();
}
/**
* 更新实体
*/
@Override
public void update(T entity) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.update(entity);
session.getTransaction().commit();
}
/**
* 更新实体
*/
@Override
public void saveOrUpdate(T entity) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.saveOrUpdate(entity);
session.getTransaction().commit();
}
/**
* 删除实体
*/
@Override
public void delete(T entity) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.delete(entity);
session.getTransaction().commit();
}
/**
* 按id删除实体
*/
@Override
public void deteleById(Class<T> entityClass, PK id) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.delete(findById(entityClass, id));
session.getTransaction().commit();
}
/**
* 执行自定义的sql语句,实现其中的添加,更新,删除的方法
*/
@Override
public void execute(String hql, Object[] params) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
if (null != params && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
}
// 执行hql语句
query.executeUpdate();
session.getTransaction().commit();
}
/**
* 获取所有实体
*/
@SuppressWarnings("unchecked")
@Override
public List<T> query(Class<T> entityClass) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
String hql = "from " + entityClass.getName();
Query query = session.createQuery(hql);
List<T> list = query.list();
session.getTransaction().commit();
return list;
}
@SuppressWarnings("unchecked")
@Override
public T findByProperty(Class<T> entityClass, String propertyName,
Object value) {
String hql = "from " + entityClass.getName() + " as model where model."
+ propertyName + "=?";
Session session = HibernateUtil.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
query.setParameter(0, value);
List<T> list = query.list();
session.getTransaction().commit();
if (null != list) {
return list.get(0);
} else {
return null;
}
}
/**
* 按实体名和id获取实体
*
* @param entityClass
* @param id
* @return
*/
@SuppressWarnings("unchecked")
@Override
public T findById(Class<T> entityClass, PK id) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
T entity = (T) session.get(entityClass, id);
session.getTransaction().commit();
return entity;
}
/**
* 按自定义的hql取得结果集
*/
@Override
@SuppressWarnings("unchecked")
public List<T> findByHql(String hql, Object[] params) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
Query query = session.createQuery(hql);
if (null != params && params.length > 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
}
List<T> list = query.list();
session.getTransaction().commit();
return list;
}
/**
* 分页使用
*
* @param entityClass
* @param start
* @param limit
* @return
*/
@SuppressWarnings("unchecked")
@Override
public List<T> findByPage(String hql, Object[] params, int start, int limit) {
Session session = HibernateUtil.getSession();
session.beginTransaction();
List<T> list = null;
try {
Query query = session.createQuery(hql);
if (params != null && params.length != 0) {
for (int i = 0; i < params.length; i++) {
query.setParameter(i, params[i]);
}
}
if (limit != 0) {
query.setFirstResult(start).setMaxResults(limit);
}
list = query.list();
session.getTransaction().commit();
} catch (Exception ef) {
ef.printStackTrace();
session.getTransaction().rollback();
}
return list;
}
/**
* 分页使用
*
* @param entityClass
* @param start
* @param limit
* @return
*/
@SuppressWarnings("unchecked")
@Override
public List<T> findByPage(Class<T> entityClass, int start, int limit) {
Session session = HibernateUtil.getSession();
String hql = "select from o " + entityClass.getName() + " o";
session.beginTransaction();
Query query = session.createQuery(hql);
query.setFirstResult(start).setMaxResults(limit);
List<T> list = query.list();
session.getTransaction().commit();
return list;
}
}
我在HibernateUtil 获取Session的方法是getCurrentSession(),所以在DAO实现类里是无需close session的,若使用的是openSession(),则实现类必须要close session。至于为什么要close,这和文件一样,你懂得。
在此Hibernate 基于泛型DAO类设计完成,如还有其他的需求,可在接口中扩展。