以前写的一个改进版泛型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;
}
}
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;
}
}
applicationContext-annotation.xml
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.directwebremoting.org/schema/spring-dwr
http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config/>
</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.directwebremoting.org/schema/spring-dwr
http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<context:annotation-config/>
</beans>
applicationContext-list.xml
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<description>导入applicationContext文件列表,可随时通过注释disable不需要的模块</description>
<!-- 导入spring aop配置文件 -->
<import resource="applicationContext-tx.xml" />
<!-- 导入spring dao配置文件 -->
<import resource="tinylight-dao.xml" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<description>导入applicationContext文件列表,可随时通过注释disable不需要的模块</description>
<!-- 导入spring aop配置文件 -->
<import resource="applicationContext-tx.xml" />
<!-- 导入spring dao配置文件 -->
<import resource="tinylight-dao.xml" />
</beans>
applicationContext-tx.xml
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="UTF-8"?>
<!-- 使用aop/tx命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- 为事务管理器注入sessionFactory" -->
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 通过aop定义事务增强切面 -->
<aop:config>
<!-- 使用强大的切点表达式语言轻松定义目标方法 -->
<aop:pointcut id="serviceMethod"
expression="execution(* com.tinylight.dao.base.IBaseDao.*(..))" />
<!-- 引用事务增强 -->
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
</aop:config>
<!-- 事务增强 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- 属性事务定义 -->
<tx:attributes>
<!--OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。
然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,
在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。
在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,
并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有 -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!-- 使用aop/tx命名空间 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置事务管理器bean,使用HibernateTransactionManager事务管理器 -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- 为事务管理器注入sessionFactory" -->
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 通过aop定义事务增强切面 -->
<aop:config>
<!-- 使用强大的切点表达式语言轻松定义目标方法 -->
<aop:pointcut id="serviceMethod"
expression="execution(* com.tinylight.dao.base.IBaseDao.*(..))" />
<!-- 引用事务增强 -->
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
</aop:config>
<!-- 事务增强 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- 属性事务定义 -->
<tx:attributes>
<!--OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。
然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,
在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。
在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,
并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有 -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
</beans>
applicationContext.xml
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 使用外部文件配置数据源的属性 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- 外部文件地址 -->
<value>classpath:database_conn.properties</value>
</list>
</property>
<property name="fileEncoding" value="utf-8" />
</bean>
<!-- 配置数据源 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${driverClassName}" />
<property name="jdbcUrl" value="${url}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize" value="5" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="20" />
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="10" />
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
<property name="maxStatements" value="0"/>
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60"/>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="0" />
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
<property name="breakAfterAcquireFailure" value="true" />
<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout" value="false" />
</bean>
<!-- hibernate3 sessionfactory配置
使用AnnotationSessionFactoryBean创建基于JPA注解的SessionFactory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!-- 引用数据源 -->
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<!-- hibernate的属性具体见hibernate文档 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<!-- 非0值 指定jdbc抓取数量的大小调用Statement.setFetchSize() -->
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<!-- jdbc批量更新 建议5到30 -->
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<!--说明一下:如果不设置查询缓存,那么hibernate只会缓存使用load()方法获得的单个持久化对象
如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()
等方法获得的数据结果集的话就需要设置hibernate.cache.use_query_cache true 才行 -->
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">
${hibernate.ehcache_config_file}
</prop>
</props>
</property>
<property name="packagesToScan" value="com.hibernate.entityclass" />
</bean>
<!-- 加载spring功能列表文件 -->
<import resource="applicationContext-list.xml"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 使用外部文件配置数据源的属性 -->
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- 外部文件地址 -->
<value>classpath:database_conn.properties</value>
</list>
</property>
<property name="fileEncoding" value="utf-8" />
</bean>
<!-- 配置数据源 -->
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${driverClassName}" />
<property name="jdbcUrl" value="${url}"/>
<property name="user" value="${username}"/>
<property name="password" value="${password}"/>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize" value="5" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="20" />
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="10" />
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="5" />
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
<property name="maxStatements" value="0"/>
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="60"/>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="0" />
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
<property name="breakAfterAcquireFailure" value="true" />
<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout" value="false" />
</bean>
<!-- hibernate3 sessionfactory配置
使用AnnotationSessionFactoryBean创建基于JPA注解的SessionFactory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<!-- 引用数据源 -->
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<!-- hibernate的属性具体见hibernate文档 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<!-- 非0值 指定jdbc抓取数量的大小调用Statement.setFetchSize() -->
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<!-- jdbc批量更新 建议5到30 -->
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<!--说明一下:如果不设置查询缓存,那么hibernate只会缓存使用load()方法获得的单个持久化对象
如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()
等方法获得的数据结果集的话就需要设置hibernate.cache.use_query_cache true 才行 -->
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">
${hibernate.ehcache_config_file}
</prop>
</props>
</property>
<property name="packagesToScan" value="com.hibernate.entityclass" />
</bean>
<!-- 加载spring功能列表文件 -->
<import resource="applicationContext-list.xml"/>
</beans>
database_conn.properties
view plaincopy to clipboardprint?
#jdbc settings
driverClassName=org.gjt.mm.mysql.Driver
url=jdbc/:mysql/://127.0.0.1/:3306/mytest
username=root
password=123456
#hibernate settings
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.use_query_cache=false
hibernate.jdbc.fetch_size=10
hibernate.jdbc.batch_size=5
hibernate.ehcache_config_file=ehcache.xml
#jdbc settings
driverClassName=org.gjt.mm.mysql.Driver
url=jdbc/:mysql/://127.0.0.1/:3306/mytest
username=root
password=123456
#hibernate settings
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.cache.use_query_cache=false
hibernate.jdbc.fetch_size=10
hibernate.jdbc.batch_size=5
hibernate.ehcache_config_file=ehcache.xml
ehcache.xml
view plaincopy to clipboardprint?
<ehcache>
<!-- Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir" />
&nbs