基于hibernate的泛型Dao框架

这个东西是一年前弄的,不过一直没用到,里面有些东西已经记不太清了,还好注释应该可以看懂。
目的是希望设计一个基于hibernate的泛型Dao框架
推荐一个J2EE的群:46176507

首先创建一个java项目GenericDao

我们创建一个包com.hb.generic.dao
该包用来作为我们的基础dao包
首先我们创建一个针对单个实体操作的泛型EntityDao<T>接口。


/**
* @author llying
* @company qm
*/
public interface EntityDao<T> {

T get(Serializable id);

List<T> getAll();

void save(T newInstance);

void remove(T transientObject);

void removeById(Serializable id);

String getIdName(Class clazz);
}

用于定义针对单个实体的CRUD操作。
接着我们在定义一个接口类HibernateCallback,定义一个回调接口。

import org.hibernate.Session;
/**
* @author llying
* @company qm
*/
public interface HibernateCallback {
Object doInHibernate(Session session);
}


接下来我们定义一个com.hb.generic.dao.utils包,
该包的目的是用于防治一些常用方法的抽取,该包中的一些类是我平时的收集和积累。
我们这里只对关键类进行说明
BeanUtils :工具类,通过反射机制对对象进行存取值
GenericUtils:工具类,取得类中的泛型类型
里面基本上都有都有注释
我们在com.hb.generic.dao.support包下创建一个分页类(不做具体介绍,基本上分页都差不多)
我们需要在com.hb.generic.dao包下创建HibernateDaoHandler接口

import org.hibernate.Session;
/**
* @author llying
* @company qm
*/
public interface HibernateDaoHandler {
Session getSession();
}

在用户使用的时候需要实现该接口获取session
接下来我们会创建HibernateDaoSupport类
Dao的基类: 提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.

package com.hb.generic.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.impl.CriteriaImpl.OrderEntry;

import com.hb.generic.dao.support.Page;
import com.hb.generic.dao.utils.Assert;
import com.hb.generic.dao.utils.BeanUtils;

/**
* Dao的基类.
*
* 提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.
* @author llying
* @company qm
*/
public abstract class HibernateDaoSupport<T> implements HibernateDaoHandler {

private static final Log log = LogFactory.getLog(HibernateDaoSupport.class);
public Object execute(HibernateCallback action){
Assert.notNull(action, "Callback object 对象不能为 Null ");
Session session = getSession();
Transaction tr = session.beginTransaction();
Object result = action.doInHibernate(session);
tr.commit();
session.close();
return result;
}

/**
* 获取全部的对象
* @param <T>
* @param entityClass 对象类型
* @return
*/
@SuppressWarnings("unchecked")
public <T>List<T> getAll(final Class<T> entityClass) {
return (List<T>)execute(new HibernateCallback(){
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(entityClass);
return criteria.list();
}
});
}

/**
* 获取全部对象,带排序功能
* @param <T>
* @param entityClass 实体对象
* @param orderBy 排序字段
* @param isAsc 升序或降序
* @return
*/
@SuppressWarnings({ "hiding", "hiding", "unchecked" })
public <T> List <T> getAll(final Class<T> entityClass,final String orderBy,final boolean isAsc){
Assert.hasText(orderBy);
return (List<T>) execute(new HibernateCallback(){

public Object doInHibernate(Session session) {

if (isAsc)
return session.createCriteria(entityClass).addOrder(Order.asc(orderBy)).list();
return session.createCriteria(entityClass).addOrder(Order.desc(orderBy)).list();
}

});

}
/**
* 保存对象
* @param newInstance
*/
@SuppressWarnings("unused")
public void saveOrUpdate(final T newInstance){
execute(new HibernateCallback(){
public Object doInHibernate(Session session) {
session.saveOrUpdate(newInstance);
return null;
}
});
}
/**
* 删除对象
* @param transientObject
*/
public void remove(final T transientObject) {
execute(new HibernateCallback(){
public Object doInHibernate(Session session) {
session.delete(transientObject);
return null;
}

});
}



/**
*
* @param entityClass
* @param id
*/
public void removeById(Class<T> entityClass, Serializable id) {
remove( get(entityClass, id));
}

/**
* 根据Id获取对象。
* @param <T>
* @param entityClass
* @param id 实体Id
* @return 实体对象
*/
@SuppressWarnings({ "hiding", "unchecked" })
public <T> T get(final Class<T> entityClass,final Serializable id) {
return (T) execute(new HibernateCallback(){
public Object doInHibernate(Session session) {
return session.get(entityClass, id);
}
});
}

/**
* 创建一个Query对象。
* @param hql
* @param values
* @return
*/
public Query createQuery(String hql,Object...values){
Assert.hasText(hql);
Query query = getSession().createQuery(hql);
for(int i = 0;i<values.length;i++){
query.setParameter(i, values[i]);
}
return query;
}

/**
* 创建Criteria对象。
* @param <T>
* @param entityClass
* @param criterions
* @return
*/
public <T>Criteria createCriteria(Class<T> entityClass,Criterion...criterions){
Criteria criteria = getSession().createCriteria(entityClass);
for(Criterion c:criterions){
criteria.add(c);
}
return criteria;
}
/**
* 创建Criteria对象,有排序功能。
* @param <T>
* @param entityClass
* @param orderBy
* @param isAsc
* @param criterions
* @return
*/
public <T>Criteria createCriteria(Class<T> entityClass,String orderBy,boolean isAsc,Criterion...criterions){
Assert.hasText(orderBy);
Criteria criteria = createCriteria(entityClass,criterions);
if(isAsc){
criteria.addOrder(Order.asc(orderBy));
}else{
criteria.addOrder(Order.desc(orderBy));
}
return criteria;
}

/**
* 根据hql查询
* @param hql
* @param values
* @return
*/
public List find(final String hql,final Object...values){
Assert.hasText(hql);

return createQuery(hql, values).list();

/* return (List) execute(new HibernateCallback(){

public Object doInHibernate(Session session) {
Query query = session.createQuery(hql);
for(int i = 0;i<values.length;i++){
query.setParameter(i, values[i]);
}
return query.list();
}

});*/
}

/**
* 根据属性名和属性值查询.
*
* @return
*/
public <T>List<T> findBy(Class<T> entityClass,String propertyName,Object value){
Assert.hasText(propertyName);
return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();
}

/**
* 根据属性名和属性值查询. 有排序
* @param <T>
* @param entityClass
* @param propertyName
* @param value
* @param orderBy
* @param isAsc
* @return
*/
public <T>List<T> findBy(Class<T> entityClass,String propertyName,Object value,String orderBy,boolean isAsc){
Assert.hasText(propertyName);
Assert.hasText(orderBy);
return createCriteria(entityClass, orderBy, isAsc, Restrictions.eq(propertyName, value)).list();
}

/**
* 根据属性名和属性值 查询 且要求对象唯一.
*
* @return 符合条件的唯一对象.
*/
public <T>T findUniqueBy(Class<T> entityClass,String propertyName,Object value){
Assert.hasText(propertyName);
return (T)createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();
}
/**
* 分页 通过hql进行
* @param hql
* @param pageNo
* @param pageSize
* @param values
* @return
*/
public Page pagedQuery(String hql,int pageNo,int pageSize,Object...values){
Assert.hasText(hql);
Assert.isTrue(pageNo>=1);
String countQueryString = "select count(*)" + removeSelect(removeOrders(hql));
System.out.println(countQueryString);
List countList = find(countQueryString, values);
long totalCount = (Long) countList.get(0);
System.out.println(totalCount);
if(totalCount<1){
return new Page();
}
int startIndex = Page.getStartOfPage(pageNo, pageSize);
Query query = createQuery(hql,values);
List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page(startIndex,totalCount,pageSize,list);
}
/**
* 分页 通过criteria
* @param criteria
* @param pageNo
* @param pageSize
* @return
*/
public Page pagedQuery(Criteria criteria,int pageNo,int pageSize){
Assert.notNull(criteria);
Assert.isTrue(pageNo>=1);
CriteriaImpl criteriaImpl = (CriteriaImpl) criteria;

//先把Projection和OrderBy条件取出来,清空两者来执行Count操作
Projection projection = criteriaImpl.getProjection();
List<CriteriaImpl.OrderEntry> orderEntitys = null;
try {
orderEntitys=(List<OrderEntry>) BeanUtils.forceGetProperty(criteriaImpl, "orderEntries");
BeanUtils.forceSetProperty(criteriaImpl, "orderEntries", new ArrayList());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
//取得总的数据数
long totalCount = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();
//将之前的Projection和OrderBy条件重新设回去
criteria.setProjection(projection);
if (projection == null) {
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
}

try {
BeanUtils.forceSetProperty(criteriaImpl, "orderEntries", orderEntitys);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
if(totalCount<1)
return new Page();
int startIndex = Page.getStartOfPage(pageNo, pageSize);
List data = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page( startIndex, totalCount, pageSize, data);
}

/**
* 分页查询函数
* @param entityClass
* @param pageNo
* @param pageSize
* @param criterions
* @return
*/
public Page pagedQuery(Class<T> entityClass,int pageNo,int pageSize,Criterion...criterions){
Criteria criteria = createCriteria(entityClass, criterions);
return pagedQuery(criteria, pageNo, pageSize);
}

/**
* 分页查询带排序
* @param entityClass
* @param pageNo
* @param pageSize
* @param orderBy
* @param isAsc
* @param criterions
* @return
*/
public Page pagedQuery(Class<T> entityClass,int pageNo,int pageSize,String orderBy,boolean isAsc,Criterion...criterions){
Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);
return pagedQuery(criteria, pageNo, pageSize);
}

/**
* 去除hql的select子句。
* @param hql
* @return
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeSelect(String hql){
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos!=-1,hql);
return hql.substring(beginPos);
}

/**
* 去除hql的orderBy子句。
* @param hql
* @return
* @see #pagedQuery(String,int,int,Object[])
*/
private static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}

}

HibernateGenericDao:最终面向用户使用的类。

/**
*
* @author llying
* @company qm
*/
@SuppressWarnings("unchecked")
public abstract class HibernateGenericDao<T> extends HibernateDaoSupport<T> implements EntityDao<T>{
protected Class<T> entityClass;

public HibernateGenericDao(){
/**
* this.getClass()的目的是返回当前对象运行时的类
* 通过工具类GenericUtils返回泛型T的实际类对象
*/

entityClass = GenericUtils.getSuperClassGenericType(getClass());
}

public T get(Serializable id) {
return get(entityClass,id);
}

public List<T> getAll() {
return getAll(entityClass);
}

public String getIdName(Class clazz) {
return null;
}

public void removeById(Serializable id) {
removeById(entityClass,id);
}

public void save(T newInstance) {
saveOrUpdate(newInstance);
}
/**
* 查询全部,带排序
* @param orderBy
* @param isAsc
* @return
*/
public List<T> getAllByOrder(String orderBy,boolean isAsc){
return getAll(entityClass,orderBy,isAsc);
}

/**
* 根据属性名和属性值查询对象
* @param propertyName
* @param value
* @return
*/
public List<T> findBy(String propertyName,Object value){
return findBy(entityClass, propertyName, value);
}

/**
* 根据属性名和属性值进行查询对象,带排序
* @param propertyName
* @param value
* @param isAsc
* @param orderBy
* @return
*/
public List<T> findBy(String propertyName,Object value,boolean isAsc,String orderBy){
return findBy(entityClass, propertyName, value, orderBy, isAsc);
}

/**
* 根据属性名和属性值进行查询对象,返回符合条件的唯一对象。
* 如果对象不唯一将抛出异常
* @param <T>
* @param propertyName
* @param value
* @return
*/
public <T> T findUniqueBy(String propertyName,Object value){
return (T) findUniqueBy(entityClass, propertyName, value);
}
}

现在我们的dao泛型框架已经完成,我们进行测试一下
我现在数据库中创建表Person

CREATE TABLE `person` (
`p_id` int(11) NOT NULL auto_increment,
`p_name` varchar(255) NOT NULL,
`p_age` int(11) NOT NULL,
PRIMARY KEY (`p_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我们创建person.test包
我们创建实体bean

package person.test;

import java.io.Serializable;

public class Person implements Serializable{
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

我们设置Person.hbm.xml映射文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="person.test.Person" table="person">
<id name="id" type="java.lang.Integer">
<column name="p_id"></column>
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="p_name" length="255" not-null="true"></column>
</property>
<property name="age" type="java.lang.Integer">
<column name="p_age" not-null="true"></column>
</property>
</class>
</hibernate-mapping>

接下来我们配置hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/genericdao
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="myeclipse.connection.profile">mysql</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<mapping resource="person/test/Person.hbm.xml" />
</session-factory>

</hibernate-configuration>

接下来我们创建SessionFactory
这个会话工厂是由工具生成的这里不做详细介绍。
接下来我们创造PersonManager所有的Person操作都由他完成,神奇吧只需继承我们之前的HibernateGenericDao并实现getSession就可以。

package person.test;

import org.hibernate.Session;

import com.hb.generic.dao.HibernateGenericDao;

public class PersonManager extends HibernateGenericDao<Person> {

@Override
public Session getSession() {
// TODO Auto-generated method stub
return HibernateSessionFactory.getSession();
}

}


下面我们写一个main方法进行测试。

/**
* 1.测试save方法
*/
public void testSave(){
for(int i=1;i<100;i++){
Person p = new Person();
p.setName("pname"+i);
p.setAge(i);
pm.save(p);
}
}
/**
* 2.测试getAll方法
*/
public void testGetAll(){
List<Person> list = pm.getAll();
System.out.println(list.size());
for(Person p: list){
System.out.println("------------------------");
System.out.println("id :" + p.getId());
System.out.println("name :" + p.getName());
System.out.println("age :" + p.getAge());
}
}
/**
* 3.测试get方法
*/
public void testGet(){
Person p = pm.get(new Integer(20));
System.out.println("id :" + p.getId());
System.out.println("name :" + p.getName());
System.out.println("age :" + p.getAge());
}
/**
* 4.测试排序方法 getAllByOrder
*/
public void testGetAllByOrder(){
List<Person> list = pm.getAllByOrder("age", true);
System.out.println("-- Asc --");
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
System.out.println("-- Desc --");
list = pm.getAllByOrder("age", false);
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
}
/**
* 5.测试find方法 即hql查询
*/
public void testFind(){
List<Person>list = pm.find("from Person p where p.age = ?", 50);
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
list = pm.find("from Person p where p.age > ? and p.age < ?",30,50);
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
}
/**
* 6.测试findBy方法 即简单查询
*/
public void testFindBy(){
List<Person>list = pm.findBy("age", 11);
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}

//如果多个按name字段排序
list = pm.findBy("age", 15, false, "name");
for(Person p: list){
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
}
/**
* 7.findUniqueBy查询 仅返回单个对象
*/
public void testFindUniqueBy(){
Person p = pm.findUniqueBy("age", 16);
System.out.println("id :" + p.getId());
System.out.println("name :" + p.getName());
System.out.println("age :" + p.getAge());
}
/**
* 8.分页查询测试 pageQuery
*/
public void testPagedQuery(){
Page page = pm.pagedQuery("from Person p where p.age > ?", 1, 20, 11);
System.out.println("currentPageNo " + page.getCurrentPageNo());
System.out.println("totalCount " + page.getTotalCount());
List<Person> list = (List<Person>) page.getResult();
for(Person p: list){
System.out.println("id :" + p.getId());
System.out.println("name :" + p.getName());
System.out.println("age :" + p.getAge());
}
}
/**
* 9.更新方法 测试saveOrUpdate
*/
public void testUpdate(){
Person p = pm.findUniqueBy("age", 16);
p.setName("16per");
pm.saveOrUpdate(p);
p = pm.findUniqueBy("age", 16);
System.out.println(p.getName());
}
/**
* 10.测试通过id删除方法 removeById
*/
public void testRemoveById(){
pm.removeById(23);
Person p = pm.get(new Integer(23));
System.out.println(p==null);
}
/**
* 11.测试通过对象删除 remove
*/
public void testRemove(){
Person p = pm.get(new Integer(24));
pm.remove(p);
p = pm.get(new Integer(24));
System.out.println(p==null);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值