Created
August 1, 2012 03:58
-
-
Save fankay/3223506 to your computer and use it in GitHub Desktop.
SSH中BaseDao的写法
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kaishengit.dao.core; | |
import java.io.Serializable; | |
import java.lang.reflect.ParameterizedType; | |
import java.lang.reflect.Type; | |
import java.util.List; | |
import java.util.Map; | |
import org.hibernate.Criteria; | |
import org.hibernate.Query; | |
import org.hibernate.Session; | |
import org.hibernate.SessionFactory; | |
import org.hibernate.criterion.Criterion; | |
import org.hibernate.criterion.Disjunction; | |
import org.hibernate.criterion.MatchMode; | |
import org.hibernate.criterion.Order; | |
import org.hibernate.criterion.Projections; | |
import org.hibernate.criterion.Restrictions; | |
import org.hibernate.transform.ResultTransformer; | |
import org.springframework.beans.factory.annotation.Autowired; | |
/** | |
* DAO继承类 | |
* @author Kay | |
* | |
* @param <T> 实体类 | |
* @param <PK> 主键类型 | |
*/ | |
@SuppressWarnings("unchecked") | |
public class BaseDao<T,PK extends Serializable> { | |
private SessionFactory sessionfactory; | |
private Class<?> clazz; | |
public BaseDao() { | |
//根据反射获取T的Class对象 | |
Class<?> c = this.getClass(); | |
ParameterizedType pt = (ParameterizedType) c.getGenericSuperclass(); | |
Type[] types = pt.getActualTypeArguments(); | |
clazz = (Class<?>) types[0]; | |
} | |
/** | |
* Spring注入SessionFactory对象 | |
* @param sessionfactory | |
*/ | |
@Autowired | |
public void setSessionfactory(SessionFactory sessionfactory) { | |
this.sessionfactory = sessionfactory; | |
} | |
/** | |
* 获取Hibernate中的Session对象 | |
* @return | |
*/ | |
public Session getSession() { | |
return sessionfactory.getCurrentSession(); | |
} | |
/** | |
* 添加或修改对象 | |
* @param t | |
*/ | |
public void save(T t) { | |
getSession().saveOrUpdate(t); | |
} | |
/** | |
* 根据主键获取对象 | |
* @param id | |
* @return | |
*/ | |
public T get(PK id) { | |
return (T) getSession().get(clazz, id); | |
} | |
/** | |
* 获取全部对象 | |
* @return | |
*/ | |
public List<T> findAll() { | |
Criteria c = getSession().createCriteria(clazz); | |
return c.list(); | |
} | |
/** | |
* 根据分页参数获取对象 | |
* @param start 起始行数 | |
* @param rows 每页显示的行数 | |
* @return | |
*/ | |
public List<T> findByPage(Integer start,Integer rows) { | |
Criteria c = getSession().createCriteria(clazz); | |
c.setFirstResult(start); | |
c.setMaxResults(rows); | |
return c.list(); | |
} | |
/** | |
* 根据属性名和值获取唯一的对象 | |
* @param propertyName | |
* @param value | |
* @return | |
*/ | |
public T findByUnique(String propertyName,String value) { | |
Criteria c = getSession().createCriteria(clazz); | |
c.add(Restrictions.eq(propertyName, value)); | |
return (T) c.uniqueResult(); | |
} | |
/** | |
* 根据属性名和值获取对象集合 | |
* @param propertyName | |
* @param value | |
* @return | |
*/ | |
public List<T> findBy(String propertyName,String value) { | |
Criteria c = getSession().createCriteria(clazz); | |
c.add(Restrictions.eq(propertyName, value)); | |
return c.list(); | |
} | |
/** | |
* 根据HQL获取对象集合 | |
* @param hql | |
* @param args | |
* @return | |
*/ | |
public List<T> find(String hql,Object...args) { | |
return createQuery(hql, args).list(); | |
} | |
/** | |
* 根据HQL获取对象集合 HQL使用的是引用占位符 | |
* @param hql | |
* @param map | |
* @return | |
*/ | |
public List<T> find(String hql,Map<String,Object> map) { | |
return createQuery(hql, map).list(); | |
} | |
/** | |
* 根据HQL获取唯一对象 | |
* @param hql | |
* @param args | |
* @return | |
*/ | |
public T findUnique(String hql,Object...args) { | |
return (T) createQuery(hql, args).uniqueResult(); | |
} | |
/** | |
* 根据HQL获取唯一对象 HQL使用的是引用占位符 | |
* @param hql | |
* @param map | |
* @return | |
*/ | |
public T findUnique(String hql,Map<String,Object> map) { | |
return (T) createQuery(hql, map).uniqueResult(); | |
} | |
/** | |
* 根据Criterion列表获取集合对象 | |
* @param criterions | |
* @return | |
*/ | |
public List<T> find(Criterion... criterions) { | |
return createCriteria(criterions).list(); | |
} | |
/** | |
* 根据Criterion列表获取唯一对象 | |
* @param criterions | |
* @return | |
*/ | |
public T findUnique(Criterion... criterions) { | |
return (T) createCriteria(criterions).uniqueResult(); | |
} | |
/** | |
* 根据Where集合获取对象集合 | |
* @param wheres | |
* @return | |
*/ | |
public List<T> find(List<Where> wheres){ | |
return builderCriteriaByWhereList(wheres).list(); | |
} | |
/** | |
* 根据Where集合和分页对象Page进行分页查询 | |
* @param wheres | |
* @param page | |
* @return | |
*/ | |
public Page<T> find(List<Where> wheres,Page<T> page){ | |
Criteria c = builderCriteriaByWhereList(wheres); | |
//根据当前where查询出的数据总数 | |
Long totalcount = findCountByCriteria(c); | |
page.setTotalCount(totalcount); | |
c.setFirstResult(page.getOffSet()); | |
c.setMaxResults(page.getPageSize()); | |
//设置排序 | |
if(page.getOrder() != null && page.getOrderBy() != null) { | |
String[] orders = page.getOrder().split(","); | |
String[] orderBys = page.getOrderBy().split(","); | |
if(orders != null && orderBys != null) { | |
if(orders.length != orderBys.length) { | |
throw new IllegalArgumentException("排序属性和排序方式数量不对应!"); | |
} else { | |
for(int i = 0;i < orderBys.length;i++) { | |
String orderBy = orderBys[i]; | |
if(orderBy.equalsIgnoreCase("asc")) { | |
c.addOrder(Order.asc(orders[i])); | |
} else if (orderBy.equalsIgnoreCase("desc")) { | |
c.addOrder(Order.desc(orders[i])); | |
} else { | |
throw new IllegalArgumentException("排序方式必须是asc或desc"); | |
} | |
} | |
} | |
} | |
} | |
List<T> result = c.list(); | |
page.setResult(result); | |
return page; | |
} | |
/** | |
* 获取当前结果的记录数 | |
* @param c | |
* @return | |
*/ | |
private Long findCountByCriteria(Criteria c) { | |
@SuppressWarnings("static-access") | |
ResultTransformer t = c.ROOT_ENTITY; | |
c.setProjection(Projections.rowCount()); | |
Long result = (Long) c.uniqueResult(); | |
c.setProjection(null); | |
c.setResultTransformer(t); | |
return result != null ? result : 0; | |
} | |
/** | |
* 根据Where集合获取唯一对象 | |
* @param wheres | |
* @return | |
*/ | |
public T findUnique(List<Where> wheres) { | |
return (T) builderCriteriaByWhereList(wheres).uniqueResult(); | |
} | |
/** | |
* 根据Wheres集合构建Criteria对象(工具方法) | |
* @param wheres | |
* @return | |
*/ | |
private Criteria builderCriteriaByWhereList(List<Where> wheres) { | |
Criteria c = getSession().createCriteria(clazz); | |
for(Where where : wheres) { | |
//如果多个属性之间使用or来进行查询 写法例如:username_OR_loginname_OR_firstname | |
if(where.getProperty().contains("_OR_")) { | |
Criterion criterion = builderORCriterionByWhere(where); | |
c.add(criterion); | |
} else { | |
Criterion criterion = builderCriterionByWhere(where); | |
if(criterion != null) { | |
c.add(criterion); | |
} | |
} | |
} | |
return c; | |
} | |
/** | |
* 根据OR关系构建Criterion对象(工具方法) | |
* @param where | |
* @return | |
*/ | |
private Criterion builderORCriterionByWhere(Where where) { | |
String[] propertyNames = where.getProperty().split("_OR_"); | |
//Disjunction对象可以将多个Criterion条件使用or关系连接起来 | |
Disjunction disjunction = Restrictions.disjunction(); | |
for(String property : propertyNames) { | |
Criterion criterion = builderCriterionByWhere(where.getMatchType(), property, where.getValue()); | |
disjunction.add(criterion); | |
} | |
return disjunction; | |
} | |
/** | |
* 根据Where对象构建Criterion对象(工具方法) | |
* @param where | |
* @return | |
*/ | |
private Criterion builderCriterionByWhere(Where where) { | |
if(where != null) { | |
String matchType = where.getMatchType(); | |
String property = where.getProperty(); | |
String value = where.getValue(); | |
return builderCriterionByWhere(matchType, property, value); | |
} | |
return null; | |
} | |
/** | |
* 根据比较类型、属性名和值构建Criterion对象(工具方法) | |
* @param matchType 比较类型 可以从MatchType接口中获取 | |
* @param property | |
* @param value | |
* @return | |
*/ | |
public Criterion builderCriterionByWhere(String matchType, String property, String value) { | |
if(MatchType.EQ.equalsIgnoreCase(matchType)) { | |
return Restrictions.eq(property, value); | |
} else if(MatchType.GE.equalsIgnoreCase(matchType)) { | |
return Restrictions.ge(property, value); | |
} else if(MatchType.GT.equalsIgnoreCase(matchType)) { | |
return Restrictions.gt(property, value); | |
} else if(MatchType.LE.equalsIgnoreCase(matchType)) { | |
return Restrictions.le(property, value); | |
} else if(MatchType.LT.equalsIgnoreCase(matchType)) { | |
return Restrictions.lt(property, value); | |
} else if(MatchType.LIKE.equalsIgnoreCase(matchType)) { | |
return Restrictions.like(property, value, MatchMode.ANYWHERE); | |
} | |
return null; | |
} | |
/** | |
* 根据Criterion列表构建Criteria对象(工具方法) | |
* @param criterions | |
* @return | |
*/ | |
public Criteria createCriteria(Criterion... criterions) { | |
Criteria c = getSession().createCriteria(clazz); | |
for(Criterion cri : criterions) { | |
c.add(cri); | |
} | |
return c; | |
} | |
/** | |
* 根据HQL及参数构建Query对象(工具方法) | |
* @param hql | |
* @param args | |
* @return | |
*/ | |
public Query createQuery(String hql,Object...args) { | |
Query query = getSession().createQuery(hql); | |
for (int i = 0; i < args.length; i++) { | |
query.setParameter(i, args[i]); | |
} | |
return query; | |
} | |
/** | |
* 根据HQL及参数构建Query对象(工具方法) | |
* @param hql | |
* @param map | |
* @return | |
*/ | |
public Query createQuery(String hql,Map<String,Object> map) { | |
Query query = getSession().createQuery(hql); | |
query.setProperties(map); | |
return query; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kaishengit.dao.core; | |
public interface MatchType { | |
public static final String EQ = "eq"; | |
public static final String LIKE = "like"; | |
public static final String GT = "gt"; | |
public static final String GE = "ge"; | |
public static final String LT = "lt"; | |
public static final String LE = "le"; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kaishengit.dao.core; | |
import java.util.List; | |
public class Page<T> { | |
private int pageSize = 5; | |
private int pageNum = 1; | |
private int offSet = 0; | |
private Long totalPages = 1L; | |
private Long totalCount = 1L; | |
private List<T> result; | |
private String order; | |
private String orderBy; | |
public Page(){} | |
/** | |
* 获取每页显示的数据量 | |
* @return | |
*/ | |
public int getPageSize() { | |
return pageSize; | |
} | |
/** | |
* 设置每页显示的数据量 | |
* @param pageSize | |
*/ | |
public void setPageSize(int pageSize) { | |
this.pageSize = pageSize; | |
} | |
/** | |
* 获取当前页码 | |
* @return | |
*/ | |
public int getPageNum() { | |
return pageNum; | |
} | |
/** | |
* 设置当前页码 | |
* @param pageNum | |
*/ | |
public void setPageNum(int pageNum) { | |
this.pageNum = pageNum; | |
if(pageNum < 1) { | |
this.pageNum = 1; | |
} | |
} | |
/** | |
* 获取起始行号 | |
* @return | |
*/ | |
public int getOffSet() { | |
return offSet; | |
} | |
/** | |
* 设置起始行号 | |
* @param offSet | |
*/ | |
public void setOffSet(int offSet) { | |
this.offSet = offSet; | |
} | |
/** | |
* 获取总页数 | |
* @return | |
*/ | |
public Long getTotalPages() { | |
return totalPages; | |
} | |
/** | |
* 设置总页数 | |
* @param totalPages | |
*/ | |
private void setTotalPages(Long totalPages) { | |
this.totalPages = totalPages; | |
} | |
/** | |
* 获取总记录数 | |
* @return | |
*/ | |
public Long getTotalCount() { | |
return totalCount; | |
} | |
/** | |
* 设置总记录数 | |
* @param totalCount | |
*/ | |
public void setTotalCount(Long totalCount) { | |
this.totalCount = totalCount; | |
//根据总记录数自动计算总页数 | |
Long result = totalCount / getPageSize(); | |
if(totalCount % pageSize != 0) { | |
result += 1; | |
} | |
setTotalPages(result); | |
//根据当前页码自动计算起始行号 | |
setOffSet((this.pageNum - 1) * getPageSize()); | |
} | |
/** | |
* 获取当前页的数据集 | |
* @return | |
*/ | |
public List<T> getResult() { | |
return result; | |
} | |
/** | |
* 设置当前页的数据集 | |
* @param result | |
*/ | |
public void setResult(List<T> result) { | |
this.result = result; | |
} | |
/** | |
* 获取排序属性名,多个属性之间采用,分割 | |
* @return | |
*/ | |
public String getOrder() { | |
return order; | |
} | |
/** | |
* 设置排序属性名,多个属性之间采用,分割 | |
* @return | |
*/ | |
public void setOrder(String order) { | |
this.order = order; | |
} | |
/** | |
* 获取排序方式,多个方式之间采用,分割 | |
* @return | |
*/ | |
public String getOrderBy() { | |
return orderBy; | |
} | |
/** | |
* 设置排序方式,多个方式之间采用,分割 | |
* @return | |
*/ | |
public void setOrderBy(String orderBy) { | |
this.orderBy = orderBy; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.kaishengit.dao.core; | |
import java.io.UnsupportedEncodingException; | |
import java.util.ArrayList; | |
import java.util.Enumeration; | |
import java.util.List; | |
import javax.servlet.http.HttpServletRequest; | |
public class Where { | |
public Where(){} | |
public Where(String property, String value, String matchType) { | |
this.property = property; | |
this.value = value; | |
this.matchType = matchType; | |
} | |
private String property; | |
private String value; | |
private String matchType; | |
public String getProperty() { | |
return property; | |
} | |
public void setProperty(String property) { | |
this.property = property; | |
} | |
public String getValue() { | |
return value; | |
} | |
public void setValue(String value) { | |
this.value = value; | |
} | |
public String getMatchType() { | |
return matchType; | |
} | |
public void setMatchType(String matchType) { | |
this.matchType = matchType; | |
} | |
/** | |
* 根据HttpServletRequest对象构建多条件查询<br/> | |
* 表单元素必须的name值必须以"q_"为前缀<br/> | |
* 前缀后面紧跟查询类型 例如"q_eq_"说明为"="查询方式<br/> | |
* 查询方式后为属性的名称,多个属性直接使用"or"方式查询时请采用"_OR_"进行分割<br/> | |
* 例如:<br/> | |
* q_eq_username → 根据username属性进行"="查询 | |
* q_like_address → 根据address属性进行"like"查询 | |
* q_like_firstname_OR_lastname → firstname like '%xx%' or lastname like '%xx%' | |
* @param request | |
* @return | |
*/ | |
@SuppressWarnings("unchecked") | |
public static List<Where> builderWhereListByRequest(HttpServletRequest request) { | |
List<Where> list = new ArrayList<Where>(); | |
Enumeration<String> enumeration = request.getParameterNames(); | |
while(enumeration.hasMoreElements()) { | |
String formName = enumeration.nextElement(); | |
if(formName.startsWith("q_")) { | |
String[] strs; | |
//判断是否含有_OR_ | |
if(formName.contains("_OR_")) { | |
//q_eq_username_OR_lastname | |
strs = formName.split("_", 3); | |
} else { | |
//q_like_username | |
strs = formName.split("_"); | |
} | |
if(strs.length < 3) { | |
throw new IllegalArgumentException("未按照约束来写查询参数:" + formName); | |
} else { | |
String matchType = strs[1]; //比较类型 | |
String property = strs[2]; //属性名称 | |
String value = request.getParameter(formName); //属性值 | |
if(value != null && !value.isEmpty()) { | |
try { | |
value = new String(value.getBytes("ISO8859-1"),"UTF-8"); | |
//将查询参数放回request存储空间中 | |
request.setAttribute(formName, value); | |
Where where = new Where(property,value,matchType); | |
list.add(where); | |
} catch (UnsupportedEncodingException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} | |
} | |
return list; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
添加对分页和排序的支持