您的位置:首页 > 其它

基于hibernate的泛型Dao框架

2015-05-04 20:56 337 查看
这个东西是一年前弄的,不过一直没用到,里面有些东西已经记不太清了,还好注释应该可以看懂。

目的是希望设计一个基于hibernate的泛型Dao框架

推荐一个J2EE的群:46176507

首先创建一个java项目GenericDao

我们创建一个包com.hb.generic.dao

该包用来作为我们的基础dao包

首先我们创建一个针对单个实体操作的泛型EntityDao<T>接口。

Java代码


/**

* @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,定义一个回调接口。

Java代码


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接口

Java代码


import org.hibernate.Session;

/**

* @author llying

* @company qm

*/

public interface HibernateDaoHandler {

Session getSession();

}

在用户使用的时候需要实现该接口获取session

接下来我们会创建HibernateDaoSupport类

Dao的基类: 提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.

Java代码


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:最终面向用户使用的类。

Java代码


/**

*

* @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

Sql代码


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

Java代码


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映射文件

Java代码


<?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

Java代码


<?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就可以。

Java代码


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方法进行测试。

Java代码


/**

* 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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: