以前写的一个改进版泛型dao,在这里 。基本实现了0代码编写dao。现在又加入了spring jdbc的支持,使得dao即可以用实体对象进行数据存取,有可以用jdbc的底层化操作删除,更新。结构见图:
具体代码和上图对应:
DaoTest.java
view plaincopy to clipboardprint?
package com.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hibernate.entityclass.Daotest;
import com.tinylight.dao.base.IBaseDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class DaoTest {
@Resource(name="demoDao")
private IBaseDao<Daotest,Integer> demoDao;
@Test
public void test(){
}
}
package com.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hibernate.entityclass.Daotest;
import com.tinylight.dao.base.IBaseDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class DaoTest {
@Resource(name="demoDao")
private IBaseDao<Daotest,Integer> demoDao;
@Test
public void test(){
}
}
BaseDao.java
view plaincopy to clipboardprint?
/**
*
*/
package com.tinylight.dao.base;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.tinylight.dao.hibernate.GenericDao;
import com.tinylight.dao.hibernate.GenericEntityDao;
import com.tinylight.dao.jdbc.SimpleJdbcDao;
import com.tinylight.dao.support.Page;
/**
* @author scott.Cgi
* @since 2009-5-12
* 提供dao的所有操作<br>
* 实现类由spring注入:<br>
* {@link com.tinylight.dao.hibernate.GenericEntityDao}
* {@link com.tinylight.dao.hibernate.GenericDao}
* {@link com.tinylight.dao.jdbc.SimpleJdbcDao}
*/
public class BaseDao<T,PK extends Serializable> implements IBaseDao<T,PK>{
protected Class<T> entityClass;// DAO所管理的Entity类型.
private GenericEntityDao<T,PK> gedao;
private GenericDao gdao;
private SimpleJdbcDao sjdao;
public Class<T> getEntityClass() {return entityClass;}
public void setEntityClass(Class<T> entityClass) {this.entityClass = entityClass;}
public GenericEntityDao<T, PK> getGedao() {return gedao;}
public void setGedao(GenericEntityDao<T, PK> gedao) {this.gedao = gedao;}
public GenericDao getGdao() {return gdao;}
public void setGdao(GenericDao gdao) {this.gdao = gdao;}
public SimpleJdbcDao getSjdao() {return sjdao;}
public void setSjdao(SimpleJdbcDao sjdao) {this.sjdao = sjdao;}
/**
*让spring提供构造函数注入
*/
public BaseDao(Class<T> type) {
this.entityClass = type;
}
public BaseDao(){}
public void clear() {
gdao.clear();
}
public Query createQuery(String hql, Object... values) {
return gdao.createQuery(hql, values);
}
public void delete(T entityObject) {
gedao.delete(entityObject);
}
public void deleteById(PK id) {
gedao.deleteById(id);
}
public void evict(T entityObject) {
gedao.evict(entityObject);
}
public List<T> find(String hql, Object... values) {
return gdao.find(hql, values);
}
public List<T> findByNamedParams(String hql, String[] paramNames,
Object... values) {
return gdao.findByNamedParams(hql, paramNames, values);
}
public void flush() {
gdao.flush();
}
public List<T> getAll() {
return gedao.getAll();
}
public T getById(PK id) {
return gedao.getById(id);
}
public Session getNativeHibernateSession() {
return gdao.getNativeHibernateSession();
}
public StatelessSession getNativeStatelessHibernateSession() {
return gdao.getNativeStatelessHibernateSession();
}
public HibernateTemplate getSpringHibernateTemplate() {
return gdao.getSpringHibernateTemplate();
}
public Iterator<T> iterator(String hql, Object... values) {
return gdao.iterator(hql, values);
}
public SimpleJdbcDao jdbc() {
return sjdao;
}
public T load(PK id) {
return gedao.load(id);
}
public void load(T entityObject, PK id) {
gedao.load(entityObject, id);
}
public T merge(T entityObject) {
return gedao.merge(entityObject);
}
public SQLQuery nativeSqlQuery(String sql) {
return gdao.nativeSqlQuery(sql);
}
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize,
Object... values) {
return gdao.pagedQuery(countHql,hql, pageNo, pageSize, values);
}
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize,
Object... values) {
return gdao.pagedQueryByStartNo(countHql,hql, startNo, pageSize, values);
}
public void refresh(T entityObject) {
gedao.refresh(entityObject);
}
public void save(T entityObject) {
gedao.save(entityObject);
}
}
/**
*
*/
package com.tinylight.dao.base;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.tinylight.dao.hibernate.GenericDao;
import com.tinylight.dao.hibernate.GenericEntityDao;
import com.tinylight.dao.jdbc.SimpleJdbcDao;
import com.tinylight.dao.support.Page;
/**
* @author scott.Cgi
* @since 2009-5-12
* 提供dao的所有操作<br>
* 实现类由spring注入:<br>
* {@link com.tinylight.dao.hibernate.GenericEntityDao}
* {@link com.tinylight.dao.hibernate.GenericDao}
* {@link com.tinylight.dao.jdbc.SimpleJdbcDao}
*/
public class BaseDao<T,PK extends Serializable> implements IBaseDao<T,PK>{
protected Class<T> entityClass;// DAO所管理的Entity类型.
private GenericEntityDao<T,PK> gedao;
private GenericDao gdao;
private SimpleJdbcDao sjdao;
public Class<T> getEntityClass() {return entityClass;}
public void setEntityClass(Class<T> entityClass) {this.entityClass = entityClass;}
public GenericEntityDao<T, PK> getGedao() {return gedao;}
public void setGedao(GenericEntityDao<T, PK> gedao) {this.gedao = gedao;}
public GenericDao getGdao() {return gdao;}
public void setGdao(GenericDao gdao) {this.gdao = gdao;}
public SimpleJdbcDao getSjdao() {return sjdao;}
public void setSjdao(SimpleJdbcDao sjdao) {this.sjdao = sjdao;}
/**
*让spring提供构造函数注入
*/
public BaseDao(Class<T> type) {
this.entityClass = type;
}
public BaseDao(){}
public void clear() {
gdao.clear();
}
public Query createQuery(String hql, Object... values) {
return gdao.createQuery(hql, values);
}
public void delete(T entityObject) {
gedao.delete(entityObject);
}
public void deleteById(PK id) {
gedao.deleteById(id);
}
public void evict(T entityObject) {
gedao.evict(entityObject);
}
public List<T> find(String hql, Object... values) {
return gdao.find(hql, values);
}
public List<T> findByNamedParams(String hql, String[] paramNames,
Object... values) {
return gdao.findByNamedParams(hql, paramNames, values);
}
public void flush() {
gdao.flush();
}
public List<T> getAll() {
return gedao.getAll();
}
public T getById(PK id) {
return gedao.getById(id);
}
public Session getNativeHibernateSession() {
return gdao.getNativeHibernateSession();
}
public StatelessSession getNativeStatelessHibernateSession() {
return gdao.getNativeStatelessHibernateSession();
}
public HibernateTemplate getSpringHibernateTemplate() {
return gdao.getSpringHibernateTemplate();
}
public Iterator<T> iterator(String hql, Object... values) {
return gdao.iterator(hql, values);
}
public SimpleJdbcDao jdbc() {
return sjdao;
}
public T load(PK id) {
return gedao.load(id);
}
public void load(T entityObject, PK id) {
gedao.load(entityObject, id);
}
public T merge(T entityObject) {
return gedao.merge(entityObject);
}
public SQLQuery nativeSqlQuery(String sql) {
return gdao.nativeSqlQuery(sql);
}
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize,
Object... values) {
return gdao.pagedQuery(countHql,hql, pageNo, pageSize, values);
}
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize,
Object... values) {
return gdao.pagedQueryByStartNo(countHql,hql, startNo, pageSize, values);
}
public void refresh(T entityObject) {
gedao.refresh(entityObject);
}
public void save(T entityObject) {
gedao.save(entityObject);
}
}
IBaseDao.java
view plaincopy to clipboardprint?
/**
*
*/
package com.tinylight.dao.base;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.tinylight.dao.jdbc.SimpleJdbcDao;
import com.tinylight.dao.support.Page;
/**
* @author scott.Cgi
* @since 2009-5-12
*
*/
public interface IBaseDao<T,PK extends Serializable> {
/**
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
*/
public T getById(PK id);
/**
* 获取实体类型的全部对象
*/
public List<T> getAll();
/**
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
* @param id
* @return
*/
public T load(PK id);
/**
* 把数据加载到指定的非持久化实例上
* @param entityObject
* @param id
*/
public void load(T entityObject,PK id);
/**
* 删除对象.
*/
public void delete(T entityObject);
/**
* 根据id删除对象
* @param id
*/
public void deleteById(PK id);
/**
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
* @param entityObject
*/
public void refresh(T entityObject);
/**
* 消除与 Hibernate Session 的关联
* @param entityObject
*/
public void evict(T entityObject);
/**
* 保存对象.<br>
* 如果对象已在本session中持久化了,不做任何事。<br>
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
* 如果没有持久化标识属性,调用save()。<br>
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
* 否则调用update()重新关联托管对象
* @param entityObject
*/
public void save(T entityObject);
/**
* 如果对象已在本session中持久化了,覆盖原有的<br>
* 如果session中没有对应对象,从数据库加载<br>
* 如果是脱管对象,则什么都不做
* @param entityObject
* @return
*/
public T merge(T entityObject);
/**
* 根据hql查询,直接使用HibernateTemplate的find函数.
* @param <T>
* @param hql
* @param values
* @return
*/
public List<T> find(String hql, Object... values);
/**
* 根据命名参数查询
* @param <T>
* @param hql 带有命名参数的hql语句
* @param paramNames 命名参数的名字
* @param values 命名参数的值<br>
* <b>例如:</b><br>
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
* @return
*/
public List<T> findByNamedParams(String hql,String[] paramNames,Object...values);
/**
* 创建Query对象.<br>
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
* @param hql
* @param values
* @return
*/
public Query createQuery(String hql,Object... values);
/**
* 执行一些必须的sql语句把内存中的对象同步到数据库中
*/
public void flush();
/**
* 清除对象缓存
*/
public void clear();
/**
* 返回iterator接口类型的结果
* @param <T>
* @param hql
* @param values
* @return
*/
public Iterator<T> iterator(String hql,Object...values);
/**
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
*/
public Session getNativeHibernateSession();
/**
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
*/
public StatelessSession getNativeStatelessHibernateSession();
/**
* 执行本地查询获得SQLQuery对象<br>
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
* 更多用法见google
* @param sql
* @return
*/
public SQLQuery nativeSqlQuery(String sql);
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param pageNo 页面号
* @param pageSize 页面容量
* @param values
* @return
*/
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values);
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param startNo 分页从哪一条数据开始
* @param pageSize 页面容量
* @param values
* @return
*/
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values);
/**
* @return 获得spring的HibernateTemplate拥有更多的功能
*/
public HibernateTemplate getSpringHibernateTemplate();
/**
* @return 获得jdbc操作的超绚酷dao
*/
public SimpleJdbcDao jdbc();
}
/**
*
*/
package com.tinylight.dao.base;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.tinylight.dao.jdbc.SimpleJdbcDao;
import com.tinylight.dao.support.Page;
/**
* @author scott.Cgi
* @since 2009-5-12
*
*/
public interface IBaseDao<T,PK extends Serializable> {
/**
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
*/
public T getById(PK id);
/**
* 获取实体类型的全部对象
*/
public List<T> getAll();
/**
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
* @param id
* @return
*/
public T load(PK id);
/**
* 把数据加载到指定的非持久化实例上
* @param entityObject
* @param id
*/
public void load(T entityObject,PK id);
/**
* 删除对象.
*/
public void delete(T entityObject);
/**
* 根据id删除对象
* @param id
*/
public void deleteById(PK id);
/**
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
* @param entityObject
*/
public void refresh(T entityObject);
/**
* 消除与 Hibernate Session 的关联
* @param entityObject
*/
public void evict(T entityObject);
/**
* 保存对象.<br>
* 如果对象已在本session中持久化了,不做任何事。<br>
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
* 如果没有持久化标识属性,调用save()。<br>
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
* 否则调用update()重新关联托管对象
* @param entityObject
*/
public void save(T entityObject);
/**
* 如果对象已在本session中持久化了,覆盖原有的<br>
* 如果session中没有对应对象,从数据库加载<br>
* 如果是脱管对象,则什么都不做
* @param entityObject
* @return
*/
public T merge(T entityObject);
/**
* 根据hql查询,直接使用HibernateTemplate的find函数.
* @param <T>
* @param hql
* @param values
* @return
*/
public List<T> find(String hql, Object... values);
/**
* 根据命名参数查询
* @param <T>
* @param hql 带有命名参数的hql语句
* @param paramNames 命名参数的名字
* @param values 命名参数的值<br>
* <b>例如:</b><br>
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
* @return
*/
public List<T> findByNamedParams(String hql,String[] paramNames,Object...values);
/**
* 创建Query对象.<br>
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
* @param hql
* @param values
* @return
*/
public Query createQuery(String hql,Object... values);
/**
* 执行一些必须的sql语句把内存中的对象同步到数据库中
*/
public void flush();
/**
* 清除对象缓存
*/
public void clear();
/**
* 返回iterator接口类型的结果
* @param <T>
* @param hql
* @param values
* @return
*/
public Iterator<T> iterator(String hql,Object...values);
/**
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
*/
public Session getNativeHibernateSession();
/**
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
*/
public StatelessSession getNativeStatelessHibernateSession();
/**
* 执行本地查询获得SQLQuery对象<br>
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
* 更多用法见google
* @param sql
* @return
*/
public SQLQuery nativeSqlQuery(String sql);
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param pageNo 页面号
* @param pageSize 页面容量
* @param values
* @return
*/
public Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values);
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param startNo 分页从哪一条数据开始
* @param pageSize 页面容量
* @param values
* @return
*/
public Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values);
/**
* @return 获得spring的HibernateTemplate拥有更多的功能
*/
public HibernateTemplate getSpringHibernateTemplate();
/**
* @return 获得jdbc操作的超绚酷dao
*/
public SimpleJdbcDao jdbc();
}
GenericDao.java
view plaincopy to clipboardprint?
/**
*
*/
package com.tinylight.dao.hibernate;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.tinylight.dao.support.Page;
/**
* 继承自spring的HibernateDaoSupport<br>
* 提供了和具体实体类无关的数据库操作
* @author scott.Cgi
* @since 2009-5-10
*
*/
public class GenericDao extends HibernateDaoSupport {
/**
* 根据hql查询,直接使用HibernateTemplate的find函数.
* @param <T>
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> List<T> find(String hql, Object... values) {
return this.getHibernateTemplate().find(hql, values);
}
/**
* 根据命名参数查询
* @param <T>
* @param hql 带有命名参数的hql语句
* @param paramNames 命名参数的名字
* @param values 命名参数的值<br>
* <b>例如:</b><br>
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
* @return
*/
@SuppressWarnings("unchecked")
public <T> List<T> findByNamedParams(String hql,String[] paramNames,Object...values){
return this.getHibernateTemplate().findByNamedParam(hql, paramNames, values);
}
/**
* 创建Query对象.<br>
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
* @param hql
* @param values
* @return
*/
public Query createQuery(String hql,Object... values) {
//这里的false表示不创建session保证,当前操作在spring同一个事务的管理下
Query query = this.getSession(false).createQuery(hql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
return query;
}
/**
* 执行一些必须的sql语句把内存中的对象同步到数据库中
*/
public void flush() {
this.getHibernateTemplate().flush();
}
/**
* 清除对象缓存
*/
public void clear() {
this.getHibernateTemplate().clear();
}
/**
* 返回iterator接口类型的结果
* @param <T>
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Iterator<T> iterator(String hql,Object...values){
return this.getHibernateTemplate().iterate(hql, values);
}
/**
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
*/
public Session getNativeHibernateSession(){
return this.getSessionFactory().getCurrentSession();
}
/**
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
*/
public StatelessSession getNativeStatelessHibernateSession(){
return this.getSessionFactory().openStatelessSession();
}
/**
* 执行本地查询获得SQLQuery对象<br>
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
* 更多用法见google
* @param sql
* @return
*/
public SQLQuery nativeSqlQuery(String sql){
return this.getSession(false).createSQLQuery(sql);
}
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param pageNo 页面号
* @param pageSize 页面容量
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values) {
// Count查询
List<T> countlist = this.getHibernateTemplate().find(countHql, values);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return new Page<T>();
// 当前页的开始数据索引
long startIndex = Page.getStartOfPage(pageNo, pageSize);
Query query = this.createQuery(hql, values);
List<T> list = query.setFirstResult((int) startIndex).setMaxResults(pageSize).list();
return new Page<T>(startIndex, totalCount, pageSize, list);
}
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param startNo 分页从哪一条数据开始
* @param pageSize 页面容量
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values){
// Count查询
List<T> countlist = getHibernateTemplate().find(countHql, values);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return new Page();
int startIndex = startNo;
Query query = createQuery(hql, values);
List<T> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page<T>(startIndex, totalCount, pageSize, list);
}
/**
* @return 获得spring的HibernateTemplate拥有更多的功能
*/
public HibernateTemplate getSpringHibernateTemplate(){
return this.getHibernateTemplate();
}
}
/**
*
*/
package com.tinylight.dao.hibernate;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.tinylight.dao.support.Page;
/**
* 继承自spring的HibernateDaoSupport<br>
* 提供了和具体实体类无关的数据库操作
* @author scott.Cgi
* @since 2009-5-10
*
*/
public class GenericDao extends HibernateDaoSupport {
/**
* 根据hql查询,直接使用HibernateTemplate的find函数.
* @param <T>
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> List<T> find(String hql, Object... values) {
return this.getHibernateTemplate().find(hql, values);
}
/**
* 根据命名参数查询
* @param <T>
* @param hql 带有命名参数的hql语句
* @param paramNames 命名参数的名字
* @param values 命名参数的值<br>
* <b>例如:</b><br>
* findByNamedParams("from Test where t1 = :t",new String[]{"t"},tValue);
* @return
*/
@SuppressWarnings("unchecked")
public <T> List<T> findByNamedParams(String hql,String[] paramNames,Object...values){
return this.getHibernateTemplate().findByNamedParam(hql, paramNames, values);
}
/**
* 创建Query对象.<br>
* 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
* @param hql
* @param values
* @return
*/
public Query createQuery(String hql,Object... values) {
//这里的false表示不创建session保证,当前操作在spring同一个事务的管理下
Query query = this.getSession(false).createQuery(hql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
query.setParameter(i, values[i]);
}
}
return query;
}
/**
* 执行一些必须的sql语句把内存中的对象同步到数据库中
*/
public void flush() {
this.getHibernateTemplate().flush();
}
/**
* 清除对象缓存
*/
public void clear() {
this.getHibernateTemplate().clear();
}
/**
* 返回iterator接口类型的结果
* @param <T>
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Iterator<T> iterator(String hql,Object...values){
return this.getHibernateTemplate().iterate(hql, values);
}
/**
* @return 当前上下文的原生Hibernate session对象,依然受到spring事务管理不需要手动close
*/
public Session getNativeHibernateSession(){
return this.getSessionFactory().getCurrentSession();
}
/**
* @return 当前上下文的原生Hibernate StatelessSession对象<br>
* 此对象不级联关联实例,忽略集合不触发Hibernate事件模型和拦截器,没有一级缓存,没有持久化上下文,接近JDBC.
*/
public StatelessSession getNativeStatelessHibernateSession(){
return this.getSessionFactory().openStatelessSession();
}
/**
* 执行本地查询获得SQLQuery对象<br>
* 可以调用addEntity(*.class).list();获得对应实体list集合<br>
* addEntity.add(*.class).addJoin(*.class).list();获得一对多代理对象<br>
* 更多用法见google
* @param sql
* @return
*/
public SQLQuery nativeSqlQuery(String sql){
return this.getSession(false).createSQLQuery(sql);
}
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param pageNo 页面号
* @param pageSize 页面容量
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Page<T> pagedQuery(String countHql,String hql, int pageNo, int pageSize, Object... values) {
// Count查询
List<T> countlist = this.getHibernateTemplate().find(countHql, values);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return new Page<T>();
// 当前页的开始数据索引
long startIndex = Page.getStartOfPage(pageNo, pageSize);
Query query = this.createQuery(hql, values);
List<T> list = query.setFirstResult((int) startIndex).setMaxResults(pageSize).list();
return new Page<T>(startIndex, totalCount, pageSize, list);
}
/**
* @param <T>
* @param countHql 计算数据总条数的hql语句(就是带count(*)的hql)
* @param hql
* @param startNo 分页从哪一条数据开始
* @param pageSize 页面容量
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public <T> Page<T> pagedQueryByStartNo(String countHql,String hql, int startNo, int pageSize, Object... values){
// Count查询
List<T> countlist = getHibernateTemplate().find(countHql, values);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return new Page();
int startIndex = startNo;
Query query = createQuery(hql, values);
List<T> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page<T>(startIndex, totalCount, pageSize, list);
}
/**
* @return 获得spring的HibernateTemplate拥有更多的功能
*/
public HibernateTemplate getSpringHibernateTemplate(){
return this.getHibernateTemplate();
}
}
GenericEntityDao.java
view plaincopy to clipboardprint?
/**
*
*/
package com.tinylight.dao.hibernate;
import java.io.Serializable;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.<br>
* 子类只要在类定义时指定所管理Entity的Class<br>
* 即拥有对单个Entity对象的CRUD操作.
* @author scott.Cgi
* @since 2009-5-11
*
*/
public class GenericEntityDao<T,PK extends Serializable> extends HibernateDaoSupport {
protected Class<T> entityClass;// DAO所管理的Entity类型.
public void setEntityClass(Class<T> type){//注入实体类型
this.entityClass=type;
}
public Class<T> getEntityClass(){
return this.entityClass;
}
public GenericEntityDao(){}
public GenericEntityDao(Class<T> entityClass){this.entityClass = entityClass;}
/**
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
*/
@SuppressWarnings("unchecked")
public T getById(PK id) {
return (T)this.getHibernateTemplate().get(this.entityClass, id);
}
/**
* 获取实体类型的全部对象
*/
@SuppressWarnings("unchecked")
public List<T> getAll() {
return (List<T>)(this.getHibernateTemplate().loadAll(this.entityClass));
}
/**
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
* @param id
* @return
*/
@SuppressWarnings("unchecked")
public T load(PK id){
return (T)this.getHibernateTemplate().load(this.entityClass, id);
}
/**
* 把数据加载到指定的非持久化实例上
* @param entityObject
* @param id
*/
public void load(T entityObject,PK id){
this.getHibernateTemplate().load(entityObject, id);
}
/**
* 删除对象.
*/
public void delete(T entityObject) {
this.getHibernateTemplate().delete(entityObject);
}
/**
* 根据id删除对象
* @param id
*/
public void deleteById(PK id){
this.delete(this.getById(id));
}
/**
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
* @param entityObject
*/
public void refresh(T entityObject){
this.getHibernateTemplate().refresh(entityObject);
}
/**
* 消除与 Hibernate Session 的关联
* @param entityObject
*/
public void evict(T entityObject){
this.getHibernateTemplate().evict(entityObject);
}
/**
* 保存对象.<br>
* 如果对象已在本session中持久化了,不做任何事。<br>
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
* 如果没有持久化标识属性,调用save()。<br>
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
* 否则调用update()重新关联托管对象
* @param entityObject
*/
public void save(T entityObject){
this.getHibernateTemplate().saveOrUpdate(entityObject);
}
/**
* 如果对象已在本session中持久化了,覆盖原有的<br>
* 如果session中没有对应对象,从数据库加载<br>
* 如果是脱管对象,则什么都不做
* @param entityObject
* @return
*/
@SuppressWarnings("unchecked")
public T merge(T entityObject){
return (T)this.getHibernateTemplate().merge(entityObject);
}
}
/**
*
*/
package com.tinylight.dao.hibernate;
import java.io.Serializable;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.<br>
* 子类只要在类定义时指定所管理Entity的Class<br>
* 即拥有对单个Entity对象的CRUD操作.
* @author scott.Cgi
* @since 2009-5-11
*
*/
public class GenericEntityDao<T,PK extends Serializable> extends HibernateDaoSupport {
protected Class<T> entityClass;// DAO所管理的Entity类型.
public void setEntityClass(Class<T> type){//注入实体类型
this.entityClass=type;
}
public Class<T> getEntityClass(){
return this.entityClass;
}
public GenericEntityDao(){}
public GenericEntityDao(Class<T> entityClass){this.entityClass = entityClass;}
/**
* 根据主键类型的id获取实体对象,立即执行查询返回对象,数据库没有匹配则返回null
*/
@SuppressWarnings("unchecked")
public T getById(PK id) {
return (T)this.getHibernateTemplate().get(this.entityClass, id);
}
/**
* 获取实体类型的全部对象
*/
@SuppressWarnings("unchecked")
public List<T> getAll() {
return (List<T>)(this.getHibernateTemplate().loadAll(this.entityClass));
}
/**
* 获取实体对象的代理,如果数据库没有匹配则异常,实体类有关联其它对象则延时加载
* @param id
* @return
*/
@SuppressWarnings("unchecked")
public T load(PK id){
return (T)this.getHibernateTemplate().load(this.entityClass, id);
}
/**
* 把数据加载到指定的非持久化实例上
* @param entityObject
* @param id
*/
public void load(T entityObject,PK id){
this.getHibernateTemplate().load(entityObject, id);
}
/**
* 删除对象.
*/
public void delete(T entityObject) {
this.getHibernateTemplate().delete(entityObject);
}
/**
* 根据id删除对象
* @param id
*/
public void deleteById(PK id){
this.delete(this.getById(id));
}
/**
* 强迫装载对象和它的集合,使用了触发器的数据字段比较适合使用
* @param entityObject
*/
public void refresh(T entityObject){
this.getHibernateTemplate().refresh(entityObject);
}
/**
* 消除与 Hibernate Session 的关联
* @param entityObject
*/
public void evict(T entityObject){
this.getHibernateTemplate().evict(entityObject);
}
/**
* 保存对象.<br>
* 如果对象已在本session中持久化了,不做任何事。<br>
* 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
* 如果没有持久化标识属性,调用save()。<br>
* 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
* 如果是附带版本信息的(version或timestamp)且版本属性表明为新的实例化对象就save()。<br>
* 否则调用update()重新关联托管对象
* @param entityObject
*/
public void save(T entityObject){
this.getHibernateTemplate().saveOrUpdate(entityObject);
}
/**
* 如果对象已在本session中持久化了,覆盖原有的<br>
* 如果session中没有对应对象,从数据库加载<br>
* 如果是脱管对象,则什么都不做
* @param entityObject
* @return
*/
@SuppressWarnings("unchecked")
public T merge(T entityObject){
return (T)this.getHibernateTemplate().merge(entityObject);
}
}
SimpleJdbcDao.java
view plaincopy to clipboardprint?
/**
*
*/
package com.tinylight.dao.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.rowset.SqlRowSet;
/**
* 继承spring的SimpleJdbcDaoSupport
* 提供对数据库jdbc级别的操作
* 内部使用spring的SimpleJdbcTemplate与JdbcTemplate
* @author scott.Cgi
* @since 2009-5-7
*/
public class SimpleJdbcDao extends SimpleJdbcDaoSupport {
/**
* 提供对表的更改和删除操作
* @param sql 要执行的sql语句
* @param args 变参
* @return 影响的行数
*/
public int update(String sql,Object...args){
return this.getSimpleJdbcTemplate().update(sql, args);
}
/**
* 批量更新多条记录
* @param sql 多条sql组成的数组(不带参数的)
* @see 带参数的见: <br>
* getJdbcTemplate().batchUpdate(String[] sql,BatchPreparedStatementSetter pss)
* @return 影响行数数组
*/
public int[] batchUpdate(String[] sql){
return this.getJdbcTemplate().batchUpdate(sql);
}
/**
* 获取行数
* @param countSql 计算行数的sql语句
* @return
*/
public long countRows(String countSql){
return this.getJdbcTemplate().queryForLong(countSql);
}
/**
* 获取本地的Connection对象
* @return
*/
public Connection getNativeConn(){
//从当前线程绑定的数据连接获取连接
Connection conn = DataSourceUtils.getConnection(this.getJdbcTemplate().getDataSource());
try {
conn = this.getJdbcTemplate().getNativeJdbcExtractor().getNativeConnection(conn);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
return conn;
}
/**
* 获得断开数据库连接的行集,大结果集会消耗内存,受到maxSize的限制
* @param sql 要执行的sql语句带?占位符
* @param params 填充占位符的数组
* @param types 填充参数类型(java.sql.Types中的常量)
* 例如:new int[]{Types.VARCHAR,Types.DATE}
* @return 影响的行数<br>
* <b>注:</b> params和types同时为空,sql为不带?占位符;仅仅types为空时,由spring去猜测类型
*/
public SqlRowSet queryForRowSet(String sql,Object[] params,int[] types){
if(params != null && types != null){
return this.getJdbcTemplate().queryForRowSet(sql, params, types);
}else if(params != null && types == null){
return this.getJdbcTemplate().queryForRowSet(sql, params);
}else {
return this.getJdbcTemplate().queryForRowSet(sql);
}
}
/**
* 提供对表的更改和删除操作
* @param hql 使用了命名参数的sql语句
* @param sps 例如:<br>
* new BeanPropertySqlParamterSource(javaBean其属性要和命名参数对应);<br>
* new MapSqlParameterSource().add("命名参数",参数对应的值).add()...可以链式调用
* @return KeyHolder主键持有者对象;如果是新增数据,KeyHolder持有新增的主键值<br>
* 有3个方法可调用:<br>getKey()一个数字主键<br>
* getKeys()复合主键Map结构<br>
* getKeyList()多个主键由多个Map组成的List
*/
public KeyHolder updateNamedParamer(String hql,SqlParameterSource sps){
KeyHolder keyHolder = new GeneratedKeyHolder();
this.getSimpleJdbcTemplate().getNamedParameterJdbcOperations().update(hql, sps, keyHolder);
return keyHolder;
}
/**
* 执行sql语句,如创建表等
* @param sql
*/
public void executeSql(String sql){
this.getJdbcTemplate().execute(sql);
}
/**
* @return 获得spring的JdbcTemplate使用更多功能
*/
public JdbcTemplate getSpringJdbcTemplate(){
return this.getJdbcTemplate();
}
/**
* 引入jdk5.0语法的JdbcTemplate的简化版本
* @return 获得spring的SimpleJdbcTemplate使用更多功能
*/
public SimpleJdbcTemplate getSpringSimplaJdbcTemplate(){
return this.getSimpleJdbcTemplate();
}
}
/**
*
*/
package com.tinylight.dao.jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.rowset.SqlRowSet;
/**
* 继承spring的SimpleJdbcDaoSupport
* 提供对数据库jdbc级别的操作
* 内部使用spring的SimpleJdbcTemplate与JdbcTemplate
* @author scott.Cgi
* @since 2009-5-7
*/
public class SimpleJdbcDao extends SimpleJdbcDaoSupport {
/**
* 提供对表的更改和删除操作
* @param sql 要执行的sql语句
* @param args 变参
* @return 影响的行数
*/
public int update(String sql,Object...args){
return this.getSimpleJdbcTemplate().update(sql, args);
}
/**
* 批量更新多条记录
* @param sql 多条sql组成的数组(不带参数的)
* @see 带参数的见: <br>
* getJdbcTemplate().batchUpdate(String[] sql,BatchPreparedStatementSetter pss)
* @return 影响行数数组
*/
public int[] batchUpdate(String[] sql){
return this.getJdbcTemplate().batchUpdate(sql);
}
/**
* 获取行数
* @param countSql 计算行数的sql语句
* @return
*/
public long countRows(String countSql){
return this.getJdbcTemplate().queryForLong(countSql);
}
/**
* 获取本地的Connection对象
* @return
*/
public Connection getNativeConn(){
//从当前线程绑定的数据连接获取连接
Connection conn = DataSourceUtils.getConnection(this.getJdbcTemplate().getDataSource());
try {
conn = this.getJdbcTemplate().getNativeJdbcExtractor().getNativeConnection(conn);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
return conn;
}
/**
* 获得断开数据库连接的行集,大结果集会消耗内存,受到maxSize的限制
* @param sql 要执行的sql语句带?占位符
* @param params 填充占位符的数组
* @param types 填充参数类型(java.sql.Types中的常量)
* 例如:new int[]{Types.VARCHAR,Types.DATE}
* @return 影响的行数<br>
* <b>注:</b> params和types同时为空,sql为不带?占位符;仅仅types为空时,由spring去猜测类型
*/
public SqlRowSet queryForRowSet(String sql,Object[] params,int[] types){
if(params != null && types != null){
return this.getJdbcTemplate().queryForRowSet(sql, params, types);
}else if(params != null && types == null){
return this.getJdbcTemplate().queryForRowSet(sql, params);
}else {
return this.getJdbcTemplate().queryForRowSet(sql);
}
}
/**
* 提供对表的更改和删除操作
* @param hql 使用了命名参数的sql语句
* @param sps 例如:<br>
* new BeanPropertySqlParamterSource(javaBean其属性要和命名参数对应);<br>
* new MapSqlParameterSource().add("命名参数",参数对应的值).add()...可以链式调用
* @return KeyHolder主键持有者对象;如果是新增数据,KeyHolder持有新增的主键值<br>
* 有3个方法可调用:<br>getKey()一个数字主键<br>
* getKeys()复合主键Map结构<br>
* getKeyList()多个主键由多个Map组成的List
*/
public KeyHolder updateNamedParamer(String hql,SqlParameterSource sps){
KeyHolder keyHolder = new GeneratedKeyHolder();
this.getSimpleJdbcTemplate().getNamedParameterJdbcOperations().update(hql, sps, keyHolder);
return keyHolder;
}
/**
* 执行sql语句,如创建表等
* @param sql
*/
public void executeSql(String sql){
this.getJdbcTemplate().execute(sql);
}
/**
* @return 获得spring的JdbcTemplate使用更多功能
*/
public JdbcTemplate getSpringJdbcTemplate(){
return this.getJdbcTemplate();
}
/**
* 引入jdk5.0语法的JdbcTemplate的简化版本
* @return 获得spring的SimpleJdbcTemplate使用更多功能
*/
public SimpleJdbcTemplate getSpringSimplaJdbcTemplate(){
return this.getSimpleJdbcTemplate();
}
}
Page.java
view plaincopy to clipboardprint?
package com.tinylight.dao.support;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
/**
* 分页对象.包含当前页数据及分页信息如总记录数.
*
* @author scott.Cgi
* @since 2008-6-29
*/
public class Page<T> implements Serializable {
private static final long serialVersionUID = -5624189033006412710L;
private static long DEFAULT_PAGE_SIZE = 20;
private long pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
private long start; // 当前页第一条数据在List中的位置,从0开始
private List<T> data = Collections.emptyList(); // 当前页中存放的记录
private long totalCount = 0; // 总记录数
/**
* 构造方法,只构造空页.
*/
public Page() {
this(0l, 0l, DEFAULT_PAGE_SIZE, Collections.<T>emptyList());
}
/**
* 默认构造方法.
*
* @param start 本页数据在数据库中的起始位置
* @param totalSize 数据库中总记录条数
* @param pageSize 本页容量
* @param data 本页包含的数据
*/
public Page(long start, long totalSize, long pageSize, List<T> data) {
this.pageSize = pageSize;
this.start = start;
this.totalCount = totalSize;
this.data = data;
}
/**
* 取总记录数.
*/
public long getTotalCount() {
return this.totalCount;
}
/**
* 取总页数.
*/
public long getTotalPageCount() {
if (totalCount % pageSize == 0)
return totalCount / pageSize;
else
return totalCount / pageSize + 1;
}
/**
* 取每页数据容量.
*/
public Long getPageSize() {
return pageSize;
}
/**
* 取当前页中的记录.
*/
public List<T> getResult() {
return data;
}
/**
* 取该页当前页码,页码从1开始.
*/
public long getCurrentPageNo() {
return start / pageSize + 1;
}
/**
* 该页是否有下一页.
*/
public boolean hasNextPage() {
return this.getCurrentPageNo() < this.getTotalPageCount();
}
/**
* 该页是否有上一页.
*/
public boolean hasPreviousPage() {
return this.getCurrentPageNo() > 1;
}
/**
* 获取任一页第一条数据在数据集的位置,每页条数使用默认值.
*
*/
protected static long getStartOfPage(long pageNo) {
return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
}
/**
* 获取任一页第一条数据在数据集的位置.
*
* @param pageNo 从1开始的页号
* @param pageSize 每页记录条数
* @return 该页第一条数据
*/
public static long getStartOfPage(long pageNo, long pageSize) {
return (pageNo - 1) * pageSize;
}
}