import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
/**
* 表操作通用类
* 抽象:不能实例化,让外界无法实例化
* 也少用了内存空间,因为实例化就会占空间
* @author Administrator
* @param <T>
*
*/
public abstract class BaseDao<T> {
//这里为了要跟查询的?一一对应,
//即有序的,可采用数组,List和可变参数,也可以一个个写但这样麻烦
//增删改操作
//protected:外界不能访问,只能给子类访问
//final:不允许被其他类修改
protected final void edit(String sql,Object... objs){
Connection conn = null;
PreparedStatement pre = null;
try {
conn = DBUtil.getConn();
pre = conn.prepareStatement(sql);
//此处也可以把objs != null && objs.length > 0提到if条件中
//数组长度可能为0但不会报错,为null则会报错
for(int x = 0 ; objs != null && objs.length > 0 && x < objs.length ; x++){
//设置参数和结果集都是从1开始,而不是从0开始
pre.setObject(x + 1, objs[x]);
}
pre.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.close(conn, pre, null);
}
}
protected final void edit(Connection conn,String sql,Object... objs){
PreparedStatement pre = null;
try {
conn = DBUtil.getConn();
pre = conn.prepareStatement(sql);
//此处也可以把objs != null && objs.length > 0提到if条件中
//数组长度可能为0但不会报错,为null则会报错
for(int x = 0 ; objs != null && objs.length > 0 && x < objs.length ; x++){
//设置参数和结果集都是从1开始,而不是从0开始
pre.setObject(x + 1, objs[x]);
}
pre.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.close(conn, pre, null);
}
}
//获取总记录数
//Object[] objs跟设置参数值一一对应
protected final int getRecords(String sql,Object[] objs){
Connection conn = null;
PreparedStatement pre = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
pre = conn.prepareStatement(sql);
//设置查询参数
if(objs != null && objs.length > 0){
for(int x = 0 ; x < objs.length ; x++){
pre.setObject(x + 1, objs[x]);
}
}
//执行查询
rs = pre.executeQuery();
//有记录才取出来
if(rs.next()){
return rs.getInt(1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.close(conn, pre, rs);
}
return 0;
}
//查询所有
//Class<T> clazz用于实例化
protected final List<T> findAll(String sql,Object[] objs,Class<T> clazz){
List<T> list = new ArrayList<T>();
Connection conn = null;
PreparedStatement pre = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
pre = conn.prepareStatement(sql);
//设置查询参数
if(objs != null && objs.length > 0){
for(int x = 0 ; x < objs.length ; x++){
pre.setObject(x + 1, objs[x]);
}
}
//执行查询
rs = pre.executeQuery();
//有记录才取出来
while(rs.next()){
//实例化
T bean = clazz.newInstance();
getRecord(rs, bean);
//每次添加一个
list.add(bean);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.close(conn, pre, rs);
}
return list;
}
/**
* @param sql
* @param objs
* @param clazz
* @return
*/
//获取值对象,即entity,按参数查询获取值对象
//Class<T> clazz用于实例化
protected final T getVO(String sql,Object[] objs,Class<T> clazz){
Connection conn = null;
PreparedStatement pre = null;
ResultSet rs = null;
try {
conn = DBUtil.getConn();
pre = conn.prepareStatement(sql);
//设置查询参数
if(objs != null && objs.length > 0){
for(int x = 0 ; x < objs.length ; x++){
pre.setObject(x + 1, objs[x]);
}
}
//执行查询
rs = pre.executeQuery();
//有记录才取出来
if(rs.next()){
T bean = clazz.newInstance();
getRecord(rs, bean);
return bean;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.close(conn, pre, rs);
}
return null;
}
//获取一行记录(从结果集中获取)
//Object bean用于装一行记录
private void getRecord(ResultSet rs,Object bean){
//只获取到日期
Map<String, Object> map = new HashMap<String, Object>();
// Map<String, String> map = new HashMap<String, String>();
try {
//获取结果集元数据
ResultSetMetaData metaData = rs.getMetaData();
//获取列数
int columnCount = metaData.getColumnCount();
// ConvertUtil.getDateConverter();
for(int x = 1 ; x <= columnCount ; x++){
// Oracle的列名都是大写的,所以要转成小写
//String colName = metaData.getColumnName(i).toLowerCase();
//获取列名和对应的数据
String columnName = metaData.getColumnName(x);
//这种也可以,不过这种取日期时要使用转换器ConvertUtil.getDateConverter();
// String columnValue = rs.getString(x);
Object columnValue = rs.getObject(x);
// System.out.println(columnName + "-----------" + columnValue);
map.put(columnName, columnValue);
}
//把map的数据复制到值对象中,数据库的列名要和该实体的属性对应
BeanUtils.populate(bean, map);
// System.out.println(bean);
} catch (Exception e) {
// e.printStackTrace();
}
}
//获取分页中一页数据
//StringBuffer recordsSql是可变的,由于用户查询参数不定导致记录数可变,用于拼接带参数查询的记录数语句
//StringBuffer querys拼接查询参数
//查询所有列表List的子集和对应的总记录数,所以这些所带的参数查询是一样的
//这里用list,因为还要添加sql分页查询的两个参数,一个开始值和一个每页条数,
//用Object[]就大小固定了,这里就不能再添加了,才能查询所有列表List的子集
//Class<T> clazz用于利用反射做实例化对象
//int pageSize,int currentPage这两个为了计算开始索引和设置每页条数
protected final PageUtil getPaeUtil(int pageSize,int currentPage,StringBuffer recordsSql
,List params,StringBuffer querySql,Class<T> clazz){
//select count(*) from shop
int records = this.getRecords(recordsSql.toString(), params.toArray());
//多添加两个参数带给所有列表去得到子集,好做分页数据用
//如select * from shop where id>=(select id from shop limit ?,1) limit ?
params.add((currentPage-1) * pageSize);
params.add(pageSize);
List<T> list = this.findAll(querySql.toString(), params.toArray(), clazz);
return new PageUtil(currentPage,records,list,pageSize);
}
}
通用BaseDao设计
最新推荐文章于 2024-03-27 17:06:34 发布