描述:本篇博客,主要是对于目前实际web项目开发中,对于数据库操作的一些基本方法的封装,通过这样的方式,可以使得开发更加简单,减少代码量,也便于维护和阅读。其中,主要是讲解了三种不同情况的封装方法,都是自身实际开发过程中,进行积累的,当然,还有很多不足之处,但是基本够项目的基本开发。
一:非框架的DAO层封装
其中包含的知识点:
1:连接池
2:数据源
3:反射
4:数据库元数据对象
5:基本的jdbc知识
封装步骤:
(1)导入dbcp数据源包
当然也可以用其他的数据源,比如c3p0,如果想了解更多,可以阅读我的另外一篇文章:
(2)编写properties文件,并且命令为dbcpconfig.properties
扫描二维码关注公众号,回复:
145013 查看本文章
#连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/填写要使用的数据库 username=填写自己的mysql账号 password=填写自己的mysql密码 #<!-- 初始化连接 --> initialSize=10 #最大连接数量 maxActive=50 #<!-- 最大空闲连接 --> maxIdle=20 #<!-- 最小空闲连接 --> minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --> maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。 connectionProperties=useUnicode=true;characterEncoding=gbk #指定由连接池所创建的连接的自动提交(auto-commit)状态。 defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix) defaultReadOnly=false #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_UNCOMMITTED
(3)编写DBCP工具类
package com.hnu.scw.utils; import java.awt.image.DataBuffer; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class DBCPUtils { private static DataSource ds ; static { //将配置文件加载进来 InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties") ; Properties props = new Properties() ; try { props.load(in) ; ds = BasicDataSourceFactory.createDataSource(props) ; } catch (Exception e) { throw new RuntimeException("服务器忙") ; } } //提供获取连接的方法 public static Connection getConnection(){ try { return ds.getConnection() ; } catch (SQLException e) { throw new RuntimeException("服务器忙") ; } } }
(4)编写基本DAO层方法封装
package com.hnuscw.BaseDao; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.hnu.scw.handler.ResultHandler; import com.hnu.scw.handler.impl.ResultSetHandlerImpl; import com.hnu.scw.handler.impl.ResultSetListenerHandlerImpl; import com.hnu.scw.utils.DBCPUtils; //自定义框架 public class BaseDao{ // 执行添改删语句 public boolean update(String sql, Object... params) { // 拿到连接对象 Connection conn = DBCPUtils.getConnection(); int t = 0; try { // 创建预处理命令对象 PreparedStatement pstmt = conn.prepareStatement(sql); // 对?进行赋值 // 获取ParameterMetaData对象 ParameterMetaData pmd = pstmt.getParameterMetaData(); // 拿到?的个数 int n = pmd.getParameterCount(); if (n > 0) { // sql语句里有?号 if (params == null || params.length != n) { throw new RuntimeException("参数的个数不匹配"); } // 依次给每个?赋值 for (int i = 0; i < n; i++) { pstmt.setObject(i + 1, params[i]); } } t = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { try { conn.close(); // 还回池中了 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return t > 0 ? true : false; } // 执行查询(返回的结果可能是一个或者多个,或者为null,这个就具体根据返回结果再进行处理即可) public Object queryOne(String sql,Class clazz, Object... params) { // 拿到连接对象 Connection conn = DBCPUtils.getConnection(); try { // 创建预处理命令对象 PreparedStatement pstmt = conn.prepareStatement(sql); // 对?进行赋值 // 获取ParameterMetaData对象 ParameterMetaData pmd = pstmt.getParameterMetaData(); // 拿到?的个数 int n = pmd.getParameterCount(); if (n > 0) { // sql语句里有?号 if (params == null || params.length != n) { throw new RuntimeException("参数的个数不匹配"); } // 依次给每个?赋值 for (int i = 0; i < n; i++) { pstmt.setObject(i + 1, params[i]); } } ResultSet rs = pstmt.executeQuery(); //返回的结果可能是一个或者多个,或者为null return new ResultSetListenerHandlerImpl().handler(rs, clazz) ; } catch (SQLException e) { throw new RuntimeException() ; } finally { try { conn.close(); // 还回池中了 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
(5)查询返回结果集与实体bean的封装对象--------ResultSetListenerHandlerImpl
package com.hnu.scw.handler.impl; import java.lang.reflect.Field; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.ArrayList; import java.util.List; //只适用于结果集有多条记录的情况 //对象的属性名和表中的字段名应当一致 public class ResultSetListenerHandlerImpl{ public Object handler(ResultSet rs, Class clazz) { List<Object> list = new ArrayList<Object>() ; //拿到结果集的元数据对象 try { while(rs.next()){ ResultSetMetaData rsmd = rs.getMetaData() ; //拿到公有多少列 int columnCount = rsmd.getColumnCount() ; //先创建对象 Object obj = clazz.newInstance() ; for (int i = 0; i < columnCount; i++) { //拿到列名 String columnName = rsmd.getColumnName(i+1) ; //拿到对象对应的属性 Field field = clazz.getDeclaredField(columnName) ; //设置私有属性可以访问 field.setAccessible(true) ; //拿到此列对应的值 Object objectValue = rs.getObject(i+1) ; //给属性赋值 field.set(obj, objectValue) ; } list.add(obj) ; } return list ; } catch (Exception e) { throw new RuntimeException() ; } } }上面这个是返回一个List的情况,如果只想是返回单个对象,那么很简单,稍微处理一下就可以用下面这个类来实现:
package com.hnu.scw.handler.impl; import java.lang.reflect.Field; import java.sql.ResultSet; import java.sql.ResultSetMetaData; //只适用于结果集只有一条记录的情况 //对象的属性名和表中的字段名应当一致 public class ResultSetHandlerImpl { public Object handler(ResultSet rs, Class clazz) { //拿到结果集的元数据对象 try { if(rs.next()){ ResultSetMetaData rsmd = rs.getMetaData() ; //拿到公有多少列 int columnCount = rsmd.getColumnCount() ; //先创建对象 Object obj = clazz.newInstance() ; for (int i = 0; i < columnCount; i++) { //拿到列名 String columnName = rsmd.getColumnName(i+1) ; //拿到对象对应的属性 Field field = clazz.getDeclaredField(columnName) ; //设置私有属性可以访问 field.setAccessible(true) ; //拿到此列对应的值 Object objectValue = rs.getObject(i+1) ; //给属性赋值 field.set(obj, objectValue) ; } return obj ; }else return null ; } catch (Exception e) { throw new RuntimeException() ; } } }
(6)测试实例
package com.hnu.scw.test; /** * create table account //模拟的一个数据库表 * ( * id int primary key, * name varchar(30) , * money float * ) */ import java.util.List; import org.junit.Test; import com.hnu.scw.DBAssist.BaseDao; import com.hnu.scw.bean.Account; //测试自定义框架 public class Test2 { // 测试添加 @Test public void test() { DBAsssist db = new DBAsssist(); db.update("insert into account(id,name,money) values(?,?,?)", 2, "乔峰", 2000); } // 测试更新 @Test public void test1() { DBAsssist db = new DBAsssist(); db.update("update account set money = money + ? where id = ?", 500, 1); } // 测试更新 @Test public void test2() { DBAsssist db = new DBAsssist(); db.update("delete from account where id = ?", 1); } // 测试查询 @Test public void test3() { DBAsssist db = new DBAsssist(); List<Account> list = (List<Account>)db.query("select * from account", Account.class) ; for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } }对应的一个实体对象bean:
package com.hnu.scw.bean; import java.io.Serializable; public class Account implements Serializable{ private int id ; private String name ; private float money ; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getMoney() { return money; } public void setMoney(float money) { this.money = money; } @Override public String toString() { return "Account [id=" + id + ", name=" + name + ", money=" + money + "]"; } }
二:Mybatis的DAO层封装
(1)一般先写接口:
package com.hnu.scw.dao; import sun.security.provider.VerificationProvider; public interface DAO { /** * 保存对象 * * @param str * @param obj * @return * @throws Exception */ public Object save(String str, Object obj) throws Exception; /** * 修改对象 * * @param str * @param obj * @return * @throws Exception */ public Object update(String str, Object obj) throws Exception; /** * 删除对象 * * @param str * @param obj * @return * @throws Exception */ public Object delete(String str, Object obj) throws Exception; /** * 查找对象 * * @param str * @param obj * @return * @throws Exception */ public Object findForObject(String str, Object obj) throws Exception; /** * 查找对象 * * @param str * @param obj * @return * @throws Exception */ public Object findForList(String str, Object obj) throws Exception; /** * 查找对象封装成Map * * @param s * @param obj * @return * @throws Exception */ public Object findForMap(String sql, Object obj, String key, String value) throws Exception; }
(2)再写实现层:
package com.mbfw.dao; import java.util.List; import javax.annotation.Resource; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.stereotype.Repository; @Repository("daoSupport") public class DaoSupport implements DAO { @Resource(name = "sqlSessionTemplate") private SqlSessionTemplate sqlSessionTemplate; /** * 保存对象 * * @param str * @param obj * @return * @throws Exception */ public Object save(String str, Object obj) throws Exception { return sqlSessionTemplate.insert(str, obj); } /** * 批量更新 * * @param str * @param obj * @return * @throws Exception */ public Object batchSave(String str, List objs) throws Exception { return sqlSessionTemplate.insert(str, objs); } /** * 修改对象 * * @param str * @param obj * @return * @throws Exception */ public Object update(String str, Object obj) throws Exception { return sqlSessionTemplate.update(str, obj); } /** * 批量更新 * * @param str * @param obj * @return * @throws Exception */ public void batchUpdate(String str, List objs) throws Exception { SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory(); // 批量执行器 SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false); try { if (objs != null) { for (int i = 0, size = objs.size(); i < size; i++) { sqlSession.update(str, objs.get(i)); } sqlSession.flushStatements(); sqlSession.commit(); sqlSession.clearCache(); } } finally { sqlSession.close(); } } /** * 批量更新 * * @param str * @param obj * @return * @throws Exception */ public Object batchDelete(String str, List objs) throws Exception { return sqlSessionTemplate.delete(str, objs); } /** * 删除对象 * * @param str * @param obj * @return * @throws Exception */ public Object delete(String str, Object obj) throws Exception { return sqlSessionTemplate.delete(str, obj); } /** * 查找对象 * * @param str * @param obj * @return * @throws Exception */ public Object findForObject(String str, Object obj) throws Exception { return sqlSessionTemplate.selectOne(str, obj); } /** * 查找对象 * * @param str * @param obj * @return * @throws Exception */ public Object findForList(String str, Object obj) throws Exception { return sqlSessionTemplate.selectList(str, obj); } public Object findForMap(String str, Object obj, String key, String value) throws Exception { return sqlSessionTemplate.selectMap(str, obj, key); } }
三:Hibernate的DAO层
备注:这里就不用接口去编写了,在实际的开发过程中,可以将下面的方法写在一个接口中,然后用该类去实现接口,这样的话就更加面向接口编程了。
package com.hnu.scw.dao; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import javax.sql.DataSource; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.SessionFactoryImpl; import org.hibernate.query.NativeQuery; import org.hibernate.query.Query; import org.springframework.beans.factory.annotation.Autowired; @SuppressWarnings("unchecked") public class BaseDAO<T> { protected static Logger logger = Logger.getLogger(BaseDAO.class); //session获取工厂,这个主要是为了能够保证整个里面只存在一个对象,减少消耗 @Autowired private SessionFactory sessionFactory; //数据库的数据源 @Autowired private DataSource dataSource; /** * 泛型类,主要是为了后面的方法返回不同的model类型 */ protected Class<T> clz; private List list; public BaseDAO() { clz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } /** * 获取session,主要是用来进行增删改查操作,hibernate都是基于这个 * 这样的方式还可以改成于单例设计模式, */ protected Session getSession() { try { return sessionFactory.getCurrentSession(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 获取单个model数据(hql语句) * @param hql:hql数据库语句 * @param paras:参数 * @return:返回对应的查询结果,如果没有查询到就是返回null */ public T findOne(String hql, Object[] paras) { Page page = new Page(); page.setPage(1); page.setPageSize(1); List<T> list = find(hql, paras, page); if (CollectionUtils.isEmpty(list)) { return null; } else { //因为可能list里面存在多个数据条目,但是这里就取第一个,所以就是返回一个了 return list.get(0); } } /** * 这是一个find方法的重载 * 分页处理,获取对应条目的数据内容 * @param hql:hql查询语句 * @param paras:参数 * @param start:从哪里开始查询的索引 * @param limit:从开始索引的间隔数 * @return:返回分页获取到的数据条目 */ public List<T> find(String hql, Object[] paras, Integer start, Integer limit) { Query<T> query = getSession().createQuery(hql); if (logger.isDebugEnabled()) { String str = ""; str += "hql: " + hql; for (int i = 0; i < paras.length; i++) { str += ", 参数 " + i + ": " + paras[i]; } logger.debug(str); } if (paras != null) { for (int i = 0; i < paras.length; i++) { query.setParameter(i, paras[i]); } } if (start != null && start >= 0 && limit != null && limit >= 0) { query.setFirstResult(start); query.setMaxResults(limit); } return query.list(); } /** * 获取分页的数据内容 * @param hql * @param paras * @param page:page对象,这就是分页对象,里面有总条数和总页数,当前页数等内容 * @param <K> * @return */ public <K> K find2(String hql, Object[] paras, Page page) { Query query = getSession().createQuery(hql); if (logger.isDebugEnabled()) { String str = ""; str += "hql: " + hql; for (int i = 0; i < paras.length; i++) { str += ", 参数 " + i + ": " + paras[i]; } logger.debug(str); } if (paras != null) { for (int i = 0; i < paras.length; i++) { query.setParameter(i, paras[i]); } } if (page != null) { if (StringUtils.isNotBlank(page.getSort())) { } //获取对应查询语句的数据总条数 int totalCount = queryTotalCount(hql, paras); page.setTotalRecords(totalCount); int totalPages = totalCount % page.getPageSize() == 0 ? (totalCount / page.getPageSize()) : (totalCount / page.getPageSize() + 1); page.setTotalPages(totalPages); query.setFirstResult((page.getPage() - 1) * page.getPageSize()); query.setMaxResults(page.getPageSize()); } return (K) query.list(); } /** * 返回多条数据 * @param hql:hql数据库语句 * @param paras:参数 * @param page:分页处理 * @return 返回多个数据 */ public List<T> find(String hql, Object[] paras, Page page) { Query<T> query = getSession().createQuery(hql); if (logger.isDebugEnabled()) { String str = ""; str += "hql: " + hql; for (int i = 0; i < paras.length; i++) { str += ", 参数 " + i + ": " + paras[i]; } logger.debug(str); } if (paras != null) { for (int i = 0; i < paras.length; i++) { query.setParameter(i, paras[i]); } } if (page != null) { if (StringUtils.isNotBlank(page.getSort())) { } int totalCount = queryTotalCount(hql, paras); page.setTotalRecords(totalCount); int totalPages = totalCount % page.getPageSize() == 0 ? (totalCount / page.getPageSize()) :(totalCount / page.getPageSize() + 1); page.setTotalPages(totalPages); query.setFirstResult((page.getPage() - 1) * page.getPageSize()); query.setMaxResults(page.getPageSize()); } return query.list(); } /** * 查询数据的总条数 * @param hql:查询语句 * @param paras:查询参数 * @return:返回符合查询语句的总条数 */ public int queryTotalCount(String hql, Object[] paras) { int beginPos = hql.toLowerCase().indexOf("from"); String countHql = "select count(*) " + hql.substring(beginPos); Query<Object> query = getSession().createQuery(countHql); if (paras != null) { for (int i = 0; i < paras.length; i++) { query.setParameter(i, paras[i]); } } return Integer.parseInt(query.uniqueResult().toString()); } /** * 保存数据 * @param t:泛型,一般就是用model类 * @return */ public Long create(T t) { return (Long) getSession().save(t); } /** * 采取懒加载获取数据(延迟加载机制,就是只有当使用对象的时候才会真正执行查询操作) * @param id:id字段 * @return 返回对应的数据内容 */ public T load(Serializable id) { return (T) getSession().load(clz, id); } /** * 获取单个对象,根据ID主键,但是和load方法的差别就是,这是立即获取对象的操作 * @param id:主键id * @return */ public T get(Serializable id) { return (T) getSession().get(clz, id); } /** * 更新数据条目(这个会更新所有的字段内容) * 所以一点要先获取到之前对应的数据库内容,否则会把之前的置空,特别注意 * @param t:model类型 */ public void update(T t) { getSession().update(t); } /** * 删除数据条目(根据id) * @param id:主键id */ public void deleteById(Serializable id) { getSession().delete(load(id)); } /** * 进行有条件的更新操作的时候 * @param hql:hql语句 * @param paras:设置参数 * @return 返回受到更新操作的数据条目的数目 */ public int executeUpdate(String hql, Object[] paras) { Query<Object> query = getSession().createQuery(hql); if (paras != null) { for (int i = 0; i < paras.length; i++) { query.setParameter(i, paras[i]); } } return query.executeUpdate(); } /** * 进行有条件的更新操作(和executeUpdate方法作用一样,只是形参不一样) * @param sql:sql语句 * @param paras:参数 * @return 返回受到影响个数据条目数目 */ public int executeSQLUpdate(String sql, Object[] paras) { NativeQuery sqlQuery = getSession().createNativeQuery(sql); if (paras != null) { for (int i = 0; i < paras.length; i++) { sqlQuery.setParameter(i, paras[i]); } } return sqlQuery.executeUpdate(); } /** * 获取session工厂的实例化对象 * @return */ private SessionFactoryImplementor getSessionFactoryImplementor() { SessionFactoryImpl sfi = (SessionFactoryImpl) getSession().getSessionFactory(); return sfi; } /** * 进行删除操作(不可以轻易使用) * 不要乱用这个方法,尤其是在表之间有关联的情况下 */ public void deleteAll() { getSession().createNativeQuery("delete from `" + clz.getSimpleName().toLowerCase() + "`").executeUpdate(); } /** * 这个方法没什么作用 * @param hql * @param paras */ protected void appendManagerSql(StringBuilder hql, List<Object> paras) {} /** * 返回一个对象类型数据 * @param sql:sql语句 * @param paras:设置参数 * @return 返回一个对应的model类型 */ protected Object executeSQLQueryUniqueResult(String sql, List<? extends Object> paras) { SQLQuery sqlQuery = getSession().createNativeQuery(sql); if (CollectionUtils.isNotEmpty(paras)) { for (int i = 0; i < paras.size(); i++) { sqlQuery.setParameter(i, paras.get(i)); } } return sqlQuery.uniqueResult(); } /** * 返回多个对象数据类型 * @param sql * @param paras * @return */ protected List<Object[]> executeSQLQuery(String sql, List<? extends Object> paras) { SQLQuery sqlQuery = getSession().createNativeQuery(sql); if (CollectionUtils.isNotEmpty(paras)) { for (int i = 0; i < paras.size(); i++) { sqlQuery.setParameter(i, paras.get(i)); } } return sqlQuery.list(); } /** * 具有分页处理,返回多个数据对象 * @param sql:sql语句 * @param paras:设置参数 * @param page:分页对象page * @return 返回通过分页处理的多条数据 */ protected List<Object[]> executeSQLQuery(String sql, Object[] paras,Page page) { SQLQuery sqlQuery = getSession().createNativeQuery(sql); if (paras != null && paras.length > 0) { for (int i = 0; i < paras.length; i++) { sqlQuery.setParameter(i, paras[i]); } } if (page != null) { if (StringUtils.isNotBlank(page.getSort())) { } String countSql = "select count(*) from (" + sql + ") as aaaaaaaaaaaaaaa"; int totalCount = countBySql(countSql, paras); page.setTotalRecords(totalCount); int totalPages = totalCount % page.getPageSize() == 0 ? (totalCount / page.getPageSize()) :(totalCount / page.getPageSize() + 1); page.setTotalPages(totalPages); sqlQuery.setFirstResult((page.getPage() - 1) * page.getPageSize()); sqlQuery.setMaxResults(page.getPageSize()); } return sqlQuery.list(); } /** * 比较原始的获取多条数据的方法 * @param sql:sql语句 * @param paras:设置参数 * @param class1:设置返回的对象的model类型 * @return 返回多条数据 */ @SuppressWarnings("rawtypes") public List findBySQL(String sql, Object[] paras, Class<? extends Object> class1) { if (logger.isDebugEnabled()) { logger.debug("sql: " + sql); logger.debug("paras: " + Arrays.toString(paras)); } Connection connection = null; try { connection = dataSource.getConnection(); PreparedStatement stmt = connection.prepareStatement(sql); if (paras != null) { for (int i = 0; i < paras.length; i++) { stmt.setObject(i + 1, paras[i]); } } ResultSet rs = stmt.executeQuery(); List list = new ArrayList(); ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); List<String> dbColumnNames = new ArrayList<String>(); for (int i = 1; i <= columnCount; i++) { dbColumnNames.add(md.getColumnName(i)); } while (rs.next()) { List<Object> dbColumns = new ArrayList<Object>(); for (int i = 1; i <= columnCount; i++) { dbColumns.add(rs.getObject(i)); } Object t = toModel(dbColumnNames, dbColumns, class1); list.add(t); } if (logger.isDebugEnabled()) { logger.debug("sql: " + sql); logger.debug("paras: " + Arrays.toString(paras)); logger.debug("results: " + list); } return list; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { if (connection != null) { try { connection.close(); } catch (SQLException e) { } } } } /** * 将对象转为model类 * @param dbColumnNames * @param dbColumns * @param class1 * @return */ private Object toModel(List<String> dbColumnNames, List<Object> dbColumns, Class<? extends Object> class1) { try { Object t = class1.newInstance(); for (int i = 0; i < dbColumnNames.size(); i++) { String name = dbColumnNames.get(i); Method m = getSetter(name, class1); Class<? extends Object> type = m.getParameterTypes()[0]; Object value = dbColumns.get(i); if (value == null) { return null; } if (type == Long.class || type == long.class) { value = Long.valueOf(value.toString()); } else if (type == Integer.class || type == int.class) { value = Integer.valueOf(value.toString()); } else if (type == String.class) { value = value.toString(); } else if (type == BigDecimal.class) { value = new BigDecimal(value.toString()); } else if (type == Date.class) { value = (Date) value; } else if (type == Timestamp.class) { value = (Timestamp) value; } else if (type == Double.class || type == double.class) { value = Double.valueOf(value.toString()); } else if (type == Boolean.class || type == boolean.class) { value = Boolean.valueOf(value.toString()); } m.invoke(t, value); } return t; } catch (IllegalArgumentException e) { logger.error(e, e); e.printStackTrace(); } catch (InstantiationException e) { logger.error(e, e); e.printStackTrace(); } catch (IllegalAccessException e) { logger.error(e, e); e.printStackTrace(); } catch (InvocationTargetException e) { logger.error(e, e); e.printStackTrace(); } return null; } /** * 获取数据列XXX的model中的setXXX的方法 * @param name * @param clazz * @return */ private Method getSetter(String name, Class<? extends Object> clazz) { //反射获取对应clazz中model的所有的方法名 Method[] ms = clazz.getDeclaredMethods(); for (Method m : ms) { if (("set" + name).equalsIgnoreCase(m.getName())) { return m; } } return null; } /** * 获取查询语句对应的获取数据的条目数 * @param hql:hql语句 * @param params:设置参数 * @return 返回查询到的数据的个数 */ public int countByHql(String hql, Object[] params) { Query query = getSession().createQuery(hql); if (params != null) { for (int i = 0; i < params.length; i++) { query.setParameter(i, params[i]); } } //query.uniqueResult()注意返回的是一个Long型,如果要转为Integer型,那么可以采取先转为string,然后再转为Integer,或者直接先转为Long,再转Integer return Integer.parseInt(query.uniqueResult().toString()); } /** * 返回查询语句的查询结果的个数 * @param sql:sql语句 * @param params:设置参数 * @return 返回查询的结果总个数 */ protected int countBySql(String sql, Object[] params) { SQLQuery query = getSession().createNativeQuery(sql); if (params != null) { for (int i = 0; i < params.length; i++) { query.setParameter(i, params[i]); } } return Integer.parseInt(query.uniqueResult().toString()); } /** * 获取到多个对应model的对象 * @param sql:sql语句 * @param paras:设置参数 * @param page:页面对象 * @return 返回多个model对象 */ public List<T> findModelBySql(String sql, Object[] paras, Page page) { NativeQuery sqlQuery = getSession().createNativeQuery(sql); setQueryParameters(paras, sqlQuery); sqlQuery.addEntity(clz); if (page != null) { String countSql = "select count(*) from (" + sql + ") "; int totalCount = countBySql(countSql, paras); page.setTotalRecords(totalCount); int totalPages = totalCount % page.getPageSize() == 0 ? (totalCount / page.getPageSize()) : (totalCount / page.getPageSize() + 1); page.setTotalPages(totalPages); sqlQuery.setFirstResult((page.getPage() - 1) * page.getPageSize()); sqlQuery.setMaxResults(page.getPageSize()); } return sqlQuery.list(); } /** * 传入sql,返回一个model * @param sql sql语句, 比如select * from e_sys_user * @param paras:设置参数 * @return 返回一个model对象 */ public <K> K findOneModelBySql(String sql, Object[] paras, Class<? extends BaseModel> clzz) { NativeQuery<K> sqlQuery = getSession().createNativeQuery(sql); setQueryParameters(paras, sqlQuery); sqlQuery.addEntity(clzz); sqlQuery.setFirstResult(0); sqlQuery.setMaxResults(1); List<K> list = sqlQuery.list(); return CollectionUtils.isEmpty(list) ? null : list.get(0); } /** * 设置sql语句中的参数 * @param paras:参数 * @param sqlQuery:sql查询对象NativeQuery */ private void setQueryParameters(Object[] paras, NativeQuery sqlQuery) { if (paras == null) { return; } for (int i = 0; i < paras.length; i++) { sqlQuery.setParameter(i, paras[i]); } } /** * 通过userid找到对应的员工信息 * @param userid * @return */ public Employee findByUserId(String hql , Long userid) { Query query = getSession().createQuery(hql); query.setParameter(0, userid); return (Employee) query.uniqueResult(); } }(2)使用的测试实例:
package com.hnu.scw.salary.dao; import java.util.ArrayList; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Repository; import com.hnu.scw.salary.dto.DepartmentDTO; import com.hnu.scw.salary.model.Department; import com.hnu.scw.salary.support.Page; @Repository public class DepartmentDAO extends BaseDAO<Department> { public List<Department> find(DepartmentDTO dto, Page page) { StringBuilder hql = new StringBuilder(); List<Object> paras = new ArrayList<Object>(); hql.append("From Department n where 1 = 1 "); if (dto.getId() != null) { hql.append(" and n.id = ? "); paras.add(dto.getId()); } if (StringUtils.isNotBlank(dto.getCode())) { hql.append(" and n.code = ? "); paras.add(dto.getCode()); } if (StringUtils.isNotBlank(dto.getName())) { hql.append(" and n.name like ? "); paras.add("%" + dto.getName() + "%"); } if (dto.getManager() != null && dto.getManager().getId() != -1) { if (dto.getManager().getId() != null) { hql.append(" and n.manager.id = ? "); paras.add(dto.getManager().getId()); } } hql.append(" order by n.id desc "); return super.find(hql.toString(), paras.toArray(), page); } public Department findOne(DepartmentDTO dto) { Page page = new Page(); page.setPageSize(1); page.setPage(1); List<Department> list = this.find(dto, page); return CollectionUtils.isEmpty(list) ? null : list.get(0); } @Override public Long create(Department department) { return super.create(department); } @Override public void update(Department department) { super.update(department); } }