每次写一个新的DAO类的时候,都要继承HibernateDaoSupport类用于对数据库进行操作,并且每次都要给dao类中的HibernateSessionFactory赋值(使用XML方式的除外)。dao类写多了自然不太方便。现在就让我们构建一个自己的DAO通用吧。
接口特征:包含常用数据库操作(增删查改)
package com.project.utils; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.security.UnrecoverableEntryException; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.hibernate.Criteria; import org.hibernate.Query; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** * * @Date: 2013-12-3 下午12:37:15 * @Author: Gyh * @TODO: 数据库基本操作类,仅适用于mysql数据库(除非不用本人拙劣的分页函数) */ @SuppressWarnings("unchecked") public class GenericDao<T> extends HibernateDaoSupport implements IGenericDao<T> { private HibernateTemplate template; private JdbcTemplate jdbcTemplate; private Class<T> entityClass; public GenericDao() { this.entityClass = (Class<T>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } public GenericDao(Class<T> entityClass) { this.entityClass = entityClass; } /** * 存储一个实例,成功返回实体id,否则返回-1 * * @param entity * @return */ public int save(T entity) { try { return (Integer) template.save(entity); } catch (DataAccessException e) { e.printStackTrace(); return -1; } finally { template.flush(); } } /** * 删除一个实例,成功返回0,否则返回-1 * * @param entity * @return */ public int delete(T entity) { try { template.delete(entity); return 0; } catch (DataAccessException e) { e.printStackTrace(); return -1; } } /** * 根据id删除一个对象,成功返回0,否则返回-1 * * @param id * @return * @throws Exception */ public int delete(int id) { try { Object obj = template.load(entityClass, id); if (obj == null) { return -1; } template.delete(obj); return 0; } catch (Exception e) { e.printStackTrace(); return -1; } } /** * 根据一连串Id删除实体,成功返回0,否则返回-1 * * @param ids * @return */ public int delete(Serializable... ids) { try { for (Serializable id : ids) { template.delete(template.load(entityClass, id)); } return 0; } catch (DataAccessException e) { e.printStackTrace(); return -1; } } /** * 更新一个实体,成功返回0,否则返回-1 * * @param entity * @return */ public int update(T entity) { try { template.update(entity); return 0; } catch (DataAccessException e) { e.printStackTrace(); return -1; } } /** * 根据ID加载实体 * * @param id * @return */ public T load(int id) { try { return template.load(entityClass, id); } catch (DataAccessException e) { e.printStackTrace(); return null; } } public T get(int id) { return template.get(entityClass, id); } /** * 加载全部实体 * * @return */ public List<T> loadAll() { try { return template.loadAll(entityClass); } catch (DataAccessException e) { e.printStackTrace(); return null; } } /** * 使用hql执行查询 * * @param hql * @return */ public List<T> find(String hql) { return this.find(hql, new Object[] {}); } /** * 执行hql查询 * * @param hql * @param params * @return */ public List<T> find(String hql, Object[] params) { try { return template.find(hql, params); } catch (DataAccessException e) { e.printStackTrace(); return null; } } /** * 使用sql语句执行更新,成功返回0,否则返回-1 * * @param sql * @return */ public int updateBySql(String sql) { return this.updateBySql(sql, new Object[] {}); } /** * 执行sql更新,如果成功返回0,否则返回-1 * * @param sql * 待执行的语句 * @param params * 传入的参数数组 * @return */ public int updateBySql(String sql, Object[] params) { System.out.println(sql); try { jdbcTemplate.update(sql, params); return 0; } catch (DataAccessException e) { e.printStackTrace(); return -1; } } /** * 调用sql查询,返回封装了Map<字段名,对应值>的List * * @param sql * 查询语句 * @return */ public List<Map<String, Object>> findBySql(String sql) { return this.findBySql(sql, new Object[] {}); } /** * 调用sql查询,返回封装了Map<字段名,对应值>的List * * @param sql * 查询语句 * @param params * 传入参数 * @return */ public List<Map<String, Object>> findBySql(String sql, Object[] params) { System.out.println(sql); try { return jdbcTemplate.queryForList(sql, params); } catch (DataAccessException e) { e.printStackTrace(); return null; } } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } @Resource(name = "jdbcTemplate") public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public Class<T> getEntityClass() { return entityClass; } public void setEntityClass(Class<T> entityClass) { this.entityClass = entityClass; } @Resource(name = "hibernateTemplate") public void setTemplate(HibernateTemplate template) { this.template = template; super.setHibernateTemplate(template); } public HibernateTemplate getTemplate() { return template; } }
注:
类中使用了jdbcTemplate与hibernateTemplate两个数据库操作模板,这两个东西需要在spring的配置文件中配置。通常还要给它加上事务(transaction),这样子能够避免同一个对象在操作数据库时,如果同时使用两个模板,会产生两个不同的事务ID。(百度一下“什么是事务的传播特性”,这里截取一小段:“我们一般都是将事务设置在Service层那么当我们调用Service层的一个方法的时候它能够保证我们的这个方法中执行的所有的对数据库的更新操作保持在一个事务中,在事务层里面调用的这些方法要么全部成功,要么全部失败。那么事务的传播特性也是从这里说起的”)。
相关配置在下一篇说明。