package com.code.util; import static java.util.Locale.ENGLISH; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.jdbc.Work; import org.springframework.orm.hibernate4.support.HibernateDaoSupport; /** * * @author LGF 2014-11-17 * BaseHibernateDAO 工具类 * @param <T> 类型 */ @SuppressWarnings("all") public class HibernateDAO<T> extends HibernateDaoSupport { //统计条数语句 private String countHql; //基本的 hql 语句 private String baseHql; //统计条数,条件验证正则表达式 private final static String WHERE_CHECK = ".+[\\s]+[w|W][h|H][e|E][r|R][e|E]+[\\s]+.*"; //hql语句验证正则表达式 private final static String HQL_QUERY = ".*\\s+.+"; //类型 private Class<T> type; public HibernateDAO(){ initial(); } //初始化方法 private void initial(){ //获取类型 type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; if(type == null){ new RuntimeException("ERROR: [ the <T> type is null ]"); }else{ countHql = "SELECT COUNT(1) FROM "+ type.getName(); baseHql = "FROM " + type.getName(); } } /** * 获取session * @return Session */ protected Session getSession(){ return super.getSessionFactory().getCurrentSession(); } //----------------------------------------------------------- 按 id 查询一个对象 ------------------------------------------- /** * 按 id 获取一个对象 * @param id * @return T */ protected T get(Serializable id){ return (T) getSession().get(type, id); } /** * 按 id 加载一个对象 * @param id * @return T */ protected T load(Serializable id){ return (T) getSession().load(type, id); } //----------------------------------------------------------- 查询一个对象列表 ------------------------------------------- /** * 查询一个对象列表 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param params 参数集合 * @return List<T> */ protected List<T> query(String nameOrHQL,Object... params){ return query(nameOrHQL,null,params); } /** * 查询一个对象列表 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param page 分页工具 * @param params 参数集合 * @return List<T> */ protected List<T> query(String nameOrHQL,Page page,Object... params){ return getQuery(nameOrHQL, page,params).list(); } /** * 查询一个对象列表 * @return List<T> */ protected List<T> query(){ return query(null); } /** * 按页数查询一个对象列表 * @param page 分页工具 * @return List<T> */ protected List<T> query(Page page){ return getQuery(baseHql, page).list(); } //------------------------------------------------ 动态条件查询 ------------------------------------------------- /* and */ /** * 动态条件查询,如果对象字段有值将会用 and 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaAnd(T obj) throws Exception{ return queryByCriteriaAnd(obj,null); } /** * 动态条件查询,如果对象字段有值将会用 and 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @param page 分页工具 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaAnd(T obj,Page page) throws Exception{ Criteria criteria = getSession().createCriteria(type); Map<String, Object> values = getFieldValues(obj); for (String key : values.keySet()) { criteria.add(Restrictions.eq(key, values.get(key))); } return setCriteriaPage(criteria,page).list(); } /* or */ /** * 动态条件查询,如果对象字段有值将会用 or 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaOption(T obj) throws Exception{ return queryByCriteriaOption(obj,null); } /** * 动态条件查询,如果对象字段有值将会用 or 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @param page 分页工具 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaOption(T obj,Page page) throws Exception{ Criteria criteria = getSession().createCriteria(type); Map<String, Object> values = getFieldValues(obj); Criterion[] conditions = new Criterion[values.size()]; int index = 0; for (String key : values.keySet()) { conditions[index] = Restrictions.eq(key,values.get(key)); index++; } criteria.add(Restrictions.disjunction(conditions)); return setCriteriaPage(criteria,page).list(); } /* like */ /** * 动态条件查询,如果对象字段有值将会用 like 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @param page 分页工具 * @param ignore 是否忽略大小写 * @param mode 模式 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaLike(T obj,Page page,boolean ignore,MatchMode mode) throws Exception{ Criteria criteria = getSession().createCriteria(type); Map<String, Object> values = getFieldValues(obj); System.out.println(values); for (String key : values.keySet()) { if(key.getClass()!=String.class){continue;} if(ignore){ criteria.add(Restrictions.ilike(key,values.get(key).toString(),mode)); }else{ criteria.add(Restrictions.like(key,values.get(key).toString(),mode)); } } return setCriteriaPage(criteria,page).list(); } /** * 动态条件查询,如果对象字段有值将会用 like 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @param page 分页工具 * @param ignore 是否忽略大小写 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaLike(T obj,Page page,boolean ignore) throws Exception{ return queryByCriteriaLike(obj,page,ignore,MatchMode.ANYWHERE); } /** * 动态条件查询,如果对象字段有值将会用 like 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @param page 分页工具 * @param mode 模式 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaLike(T obj,Page page,MatchMode mode) throws Exception{ return queryByCriteriaLike(obj,page,false,mode); } /** * 动态条件查询,如果对象字段有值将会用 like 连接条件查询 * @param obj 传入需要动态查询的类型对象 * @return List<T> * @throws Exception */ protected List<T> queryByCriteriaLike(T obj) throws Exception{ return queryByCriteriaLike(obj,null,false,MatchMode.ANYWHERE); } /* criteria page */ /** * 设置分页参数 * @param criteria * @param page 分页对象 * @return Criteria */ protected Criteria setCriteriaPage(Criteria criteria,Page page){ if(page!=null){ page.setTotal((long)criteria.setProjection(Projections.rowCount()).uniqueResult()); criteria.setFirstResult(page.getPageSize()*(page.getPageNumber()-1)).setMaxResults(page.getPageSize()); } return criteria; } //------------------------------------------------ 查询一个对象 ----------------------------------------------------- /** * 查询一个对象 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param params 参数集合 * @return T */ protected T queryUniqueResult(String nameOrHQL,Object... params){ return (T) getQuery(nameOrHQL, params).uniqueResult(); } //------------------------------------------------ 增删改 ----------------------------------------------------- /** * 更新一个对象 * @param o 对象 * @throws Exception */ protected int update(T transientInstance) throws Exception{ getSession().update(transientInstance); return 1; } /** * 删除一个对象 * @param o 对象 * @throws Exception */ protected int delete(T transientInstance) throws Exception{ getSession().delete(transientInstance); return 1; } /** * 批量删除操作 * @param transientInstances 删除的对象集合 * @return 更新的记录数 */ protected int batchDelete(T... transientInstances){ int count = 0; Session session = getSession(); for (T transientInstance : transientInstances) { session.delete(transientInstance); if(count%20 == 0){ session.flush(); session.clear(); } count++; } return count; } /** * 添加一个对象 * @param o 对象 * @throws Exception */ protected int save(T transientInstance) throws Exception{ getSession().save(transientInstance); return 1; } /** * 批量保存操作 * @param transientInstances 删除的对象集合 * @return 更新的记录数 */ protected int batchSave(T... transientInstances) throws Exception{ int count = 0; Session session = getSession(); for (T transientInstance : transientInstances) { session.save(transientInstance); if(count%20 == 0){ session.flush(); session.clear(); } count++; } return count; } /** * 更新一个对象 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param params 参数集合 * @return int结果 */ protected int update(String nameOrHQL,Object... params) throws Exception{ return getQuery(nameOrHQL,params).executeUpdate(); } //------------------------------------------------ HQL查询参数设置 ----------------------------------------------------- /** * 设置查询参数 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param params 参数集合 * @return Query */ protected Query getQuery(String nameOrHQL,Object... params){ return getQuery(nameOrHQL,null,params); } /** * 设置 HQL 查询参数 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param page 分页工具 * @param params 参数集合 * @return Query */ protected Query getQuery(String nameOrHQL,Page page,Object... params){ return getQuery(nameOrHQL,page,false,params); } /** * 设置 HQL 查询参数 * @param nameOrHQL * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param page 分页工具 * @param params 参数集合 * @return Query */ protected Query getQuery(String nameOrHQL,Page page,boolean isNamedParam,Object... params){ Query query = null; String qs = null; if(nameOrHQL.trim().matches(HQL_QUERY)){ query = getSession().createQuery(nameOrHQL); }else{ query = getSession().getNamedQuery(nameOrHQL); } qs = query.getQueryString(); int index = 0; for (Object object : params) { query.setParameter(index, object); index++; } if(page!=null){ page.setTotal(getCount(qs,params)); query.setFirstResult((page.getPageNumber()-1)*page.getPageSize()).setMaxResults(page.getPageSize()); } print(qs,params); return query; } /** * 设置配置文件HQL或者SQL查询 * @param queryString 查询字符串,获取配置文件中的名称 * @param page 分页工具 * @param params 参数集合 * @return Query */ protected Query getNamedQuery(String name,Page page,Object... params){ Query query = getSession().getNamedQuery(name); int index = 0; for (Object object : params) { query.setParameter(index, object); index++; } if(page!=null){ page.setTotal(getCount(query.getQueryString(),params)); query.setFirstResult((page.getPageNumber()-1)*page.getPageSize()).setMaxResults(page.getPageSize()); } print(query.getQueryString(),params); return query; } /** * 设置配置文件HQL或者SQL查询 * @param queryString 查询字符串,获取配置文件中的名称 * @param params 参数集合 * @return Query */ protected Query getNamedQuery(String name,Object... params){ return getNamedQuery(name,null,params); } /* 打印 查询语句 和参数 */ private void print(String query,Object... params){ System.out.println("query: [ " + query+" ] params: "+Arrays.asList(params)); } //------------------------------------------------ SQL查询参数设置 ----------------------------------------------------- /** * 设置 SQL 查询参数 * @param sql 语句 * @param page 分页工具 * @param params 参数集合 * @return SQLQuery */ protected SQLQuery getSQLQuery(String sql,Page page,Class<?> entity,Object... params){ return getSQLQuery(sql,page,entity,false,params); } /** * 设置 SQL 查询参数 * @param sql 语句 * @param page 分页工具 * @param isNamedParam 是否是命名参数 ? * @param params 参数集合 * @return SQLQuery */ protected SQLQuery getSQLQuery(String sql,Page page,Class<?> entity,boolean isNamedParam,Object... params){ SQLQuery query = getSession().createSQLQuery(sql); int index = 0; for (Object object : params) { query.setParameter(index, object); index++; } if(entity!=null){ query.addEntity(entity); } return query; } //------------------------------------------------原生SQL操作 ----------------------------------------------------- /** * 原生SQL更新 * @param sql 语句 * @param params 参数集合 * @return 受影响行数 */ protected int sqlUpdate(String sql,Object...params){ return getSQLQuery(sql,null,null,params).executeUpdate(); } /* 存储过程 */ /** * 调用存储过程,默认添加实体类类型:<T> * @param sql 存储过程名称 * @param params 参数集合 * @return List<T> */ protected List<T> callEntity(String sql,Object...params){ return getSQLQuery(sql, null, type, params).list(); } /** * <h3>调用存储过程,带返回值的</h3> * <p style="color:red">注意:存储过程不能有输出参数.有输出参数会报错</p> * <p style="color:red">输出参数用select把参数查询出来</p> * <p style="color:red">输入的参数的值不能为空。</p> * @param sql 存储过程 * @param params 参数集合 * @return List */ protected List call(String sql,Object...params){ return getSQLQuery(sql, null, null, params).list(); } /** * 默认添加泛型<T> * @param name * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|HQL 名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param params 参数集合 * @return List<T> */ protected <T> List<T> callNamedEntity(String name,Object...params){ Query query = getQuery(name, params); if(query instanceof SQLQuery){ ((SQLQuery) query).addEntity(type); } return query.list(); } /** * <h3>调用存储过程,带返回值的</h3> * <p style="color:red">注意:存储过程不能有输出参数.有输出参数会报错</p> * <p style="color:red">输出参数用select把参数查询出来</p> * <p style="color:red">输入的参数的值不能为空。</p> * @param name * <p style="color:red"> * 查询名称或者HQL * 如果传的是配置文件中的 SQL|名称(name) , * 中间空不能有空格,前后可以为空格, * 否则验证错误,会当做HQL语句查询 * </p> * @param name 参数集合 * @return List * */ protected List callNamed(String name,Object...params){ return getQuery(name, params).list(); } /** * JDBC 操作 * @param work */ protected void doWork(Work work){ getSession().doWork(work); } //------------------------------------------------ 统计条数 ----------------------------------------------------- /** * 统计条数 * @param page 分页工具 * @return Long 对象 */ protected Long getCount(String hql,Object... params){ StringBuffer sb = new StringBuffer(); sb.append(countHql) .append(" ") .append(getAlias(hql)) .append(" ") .append(getCondition(hql)); return (Long)getQuery(sb.toString(),params).uniqueResult(); } /** * 获取分页查询条件 * @param hql 语句 * @return 条件 */ private String getCondition(String hql){ int len = checkWhereExist(hql); if(len != -1){ return hql.substring(len); } return ""; } /** * 获取别名 * @param hql 语句 * @return 别名 */ private int checkWhereExist(String hql){ if(hql.matches(WHERE_CHECK)){ return hql.toUpperCase().indexOf("WHERE"); } return -1; } /** * 获取别名 * @param hql 语句 * @return 别名 */ private String getAlias(String hql){ String[] hs = hql.split("\\s+"); for (int i = 0; i < hs.length; i++) { String temp = hs[i].toUpperCase(); if(temp.equals("FROM")&&(i+2)<hs.length){ return hs[i+2].toUpperCase().equals("WHERE")?"":hs[i+2]; }; } return ""; } //------------------------------------------------ 其他 ----------------------------------------------------- /** * 获取字符串(type)类型 * @return */ public String getType() { return type.getName(); } /** * 将名称首字母转换成大写 * @param name 转换名称 * @return String */ private static String capitalize(String name){ if (name == null || name.trim().length() == 0) { return name; } return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1); } /** * 获取类属性get方法 * 没有get方法返回空 * @param cls 类型 * @param field 字段名称 * @return 方法 Method * @throws NoSuchMethodException * @throws SecurityException */ private static Method getReadMethod(Class<?> cls,Field field){ StringBuffer sb = new StringBuffer(); if(field.getType()==boolean.class){ sb.append("is").append(capitalize(field.getName())); }else{ sb.append("get").append(capitalize(field.getName())); } try { return cls.getMethod(sb.toString()); } catch (NoSuchMethodException e) { return null; } catch (SecurityException e) { e.printStackTrace(); } return null; } /** * 获取类属性set方法 * @param cls 类型 * @param field 字段名称 * @return 方法 Method * @throws NoSuchMethodException * @throws SecurityException */ private static Method getWriterMethod(Class<?> cls,Field field) throws NoSuchMethodException, SecurityException{ return cls.getMethod(new StringBuffer().append("set").append(capitalize(field.getName())).toString(),field.getType()); } /** * 获取一个字段的属性值 * 其字段必须有标准的get方法,如果没有返回空 * @param obj 对象 * @param field 字段 * @return 字段属性值 * @throws Exception */ private static Object getFieldValue(Object obj,Field field){ try { Method method = getReadMethod(obj.getClass(), field); if(method!=null){ return method.invoke(obj); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 传入一个对象,动态取值属性值方法 * 如果该对象的属性值不为空,并且有 标准的 get 方法 * 可以使用 HIBERNATE Criteria实 现动态查询 * @param obj 对象 * @return Map键值对的方式,键:字段名称,值:字段值 * @throws Exception */ private static Map<String,Object> getFieldValues(Object obj) throws Exception{ Field[] fs = obj.getClass().getDeclaredFields(); if(fs == null){ return null; } Map<String,Object> fields = new HashMap<>(); for (Field field : fs) { Object value = getFieldValue(obj,field); if(value == null)continue; if(value.getClass()==Integer.class){ int val = Integer.parseInt(value.toString()); if(val<=0)continue; }else if(value.getClass()==String.class){ if(value.toString().trim().length()<=0)continue; }else if(value instanceof Collection)continue; fields.put(field.getName(), value); } return fields; } }
相关推荐
hibernateDao工具类
`HibernateDao.java`是Hibernate框架中一个常见的数据访问对象(DAO,Data Access Object)类,它的主要职责是封装对数据库的操作,提供一套面向对象的接口,使得业务逻辑层可以无需关心底层SQL语句,直接通过对象...
使用Hibernate DAO生成工具,开发者可以自动生成与数据库表对应的DAO接口和实现类,这些类通常包含增删查改的基本方法。例如,对于一个名为`User`的表,工具会生成`UserDAO`接口和`UserDAOImpl`实现类,其中包含`...
本文将深入探讨如何使用代理来实现Hibernate Dao层的自动事务管理,以提高代码的可维护性和事务处理的效率。 首先,理解Dao(Data Access Object)层的作用至关重要。Dao层是应用与数据库之间的一层抽象,它封装了...
《深入理解HibernateDAO的写法》 在Java企业级开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而HibernateDAO则是基于Hibernate进行数据访问的对象,是业务逻辑层和持久层之间...
Hibernate DAO生成器是专门为Hibernate框架设计的工具,能够自动生成与数据库表对应的DAO类。这些DAO类包含了根据Hibernate的配置文件自动创建的CRUD(Create、Read、Update、Delete)方法,使得开发者可以直接调用...
创建一个DAO接口,定义所有需要的方法,然后创建一个实现该接口的类,如`UserDaoImpl`,在这个实现类中使用Hibernate API完成实际的数据库操作。 5. **泛型DAO**: 为了进一步提高代码的复用性,可以使用泛型来...
标题中的“vc生成hibernate的dao类”指的是在Visual C++(vc6.0)环境下,利用特定工具或插件来自动化生成基于Hibernate框架的Data Access Object(DAO)类。DAO模式是软件设计中常用的一种模式,它将业务逻辑与数据...
标题 "使用模式设计及java5新特性在HibernateDAO中的应用" 涉及到的是软件开发中的两个关键领域:设计模式和Java编程语言的新特性,特别是在数据访问对象(DAO)层如何结合使用它们。这篇文章可能详细阐述了如何利用...
- **DAO(Data Access Object)模式**:Spring通常结合DAO模式来处理数据访问,DAO接口定义了业务逻辑,而其实现类则利用Hibernate进行数据库操作。 - **事务管理**:Spring的PlatformTransactionManager接口用于...
在DAO模式中,Hibernate作为持久层工具,能够将Java对象与数据库表进行映射,通过Hibernate API实现CRUD(Create、Read、Update、Delete)操作。 该通用DAO模式的核心在于,它提供了一个基础DAO接口,如`BaseDao<T>...
在传统的Hibernate使用中,针对每个实体类,我们都需要创建一个对应的Dao(Data Access Object)接口及其实现类,这无疑增加了大量重复的代码。泛型Dao的出现,就是为了解决这个问题,它允许开发者通过泛型来定义一...
**标题:“Hibernate的通用DAO”** 在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者以面向对象的方式处理数据库操作,从而减少了对SQL的直接依赖。通用DAO(Data Access Object)是一...
通过Hibernate生成工具,开发者可以快速地自动生成与数据库表对应的Java实体类、配置文件以及DAO层代码,极大地提高了开发效率。 安装该插件的过程非常简单。首先,你需要将压缩包解压,确保得到三个文件夹。这些...
综上所述,`JPA(hibernate) Dao 和 DaoSupport`涉及到Java持久化技术,主要关注如何通过面向对象的方式操作数据库,以及如何设计和使用DAO层来封装数据访问逻辑。在实际项目中,我们还需要了解如何使用Spring Data ...
标题中的“hibernate4 通用dao,service”指的是在Java开发中使用Hibernate框架实现的通用数据访问对象(DAO)和业务服务层(Service)。Hibernate是一个流行的对象关系映射(ORM)工具,它允许开发者使用面向对象的...
本篇文章将深入探讨Hibernate的通用Dao设计,帮助开发者理解如何利用Hibernate提高代码复用性和可维护性。 在传统的Java应用程序中,DAO(Data Access Object)层是用于封装数据库访问逻辑的地方,它隔离了业务逻辑...
MyEclipse与Hibernate反向生成实体类和DAO MyEclipse是一个基于Eclipse平台的集成开发环境(IDE),它提供了很多实用的功能和插件来帮助开发者快速开发Java应用程序。Hibernate是一个流行的对象关系映射(ORM)框架...