对数据库SQL的操作不外乎就是增删查改,我们通过JBDC连接数据库后,对其进行这些操作.
我们在没有封装方法之前,对这些操作都是单条逐一写SQL语句进行增删查改操作.但封装后,我们可以调用该方法很方便的对数据库进行操作,下面来看方法:
这个方法是基于DBHelper类里已经连接好数据库,在DAO层的封装.
/**
* 执行所有的insert、delete、update语句(without transaction)
* @param sql
* @param params
* @return int 影响数据库的行数
*/
public int executeUpdate(String sql,Object...params) {
//用来向数据库发送sql语句的
PreparedStatement pstm = null;
//Connection 是一个数据连接
Connection conn = null;
try {
//连接数据库
conn = DBHelper.getInstance().getConnection();
//实例化pstm
pstm = conn.prepareStatement(sql);
//给sql语句中的占位符赋值,根据params中元素的数量推断sql语句中占位符(?)的数量
if(params != null && params.length > 0) {
for(int i = 0 ; i < params.length ; i++) {
pstm.setObject(i+1, params[i]);
}
}
//发送sql语句
int i = pstm.executeUpdate();
return i;
} catch (Exception e) {
e.printStackTrace();
}
finally {
DBHelper.getInstance().close(pstm, conn);
}
return 0;
}
以上方法是对数据库进行增删改操作的.
下面来看对数据库的查询,以下方法只能对单表进行查询:
/**
* 执行所有的单表查询,(条件,分页)
* @param sql
* @param clz
* @param params
* @return List<T>
*/
public <T> List<T> executeQuery(String sql,Class<T> clz,Object...params){
ResultSet rs = null;
PreparedStatement pstm = null;
Connection conn = null;
//保存查询到的结果
List<T> data = new ArrayList<T>();
try {
//连接数据库
conn = DBHelper.getInstance().getConnection();
//实例化pstm
pstm = conn.prepareStatement(sql);
//给sql语句中的占位符赋值,根据params中元素的数量推断sql语句中占位符(?)的数量
if(params != null && params.length > 0) {
for(int i = 0 ; i < params.length ; i++) {
pstm.setObject(i+1, params[i]);
}
}
//发送sql语句
rs = pstm.executeQuery();
//创建结果集rs 的元数据对象
ResultSetMetaData rsmd = rs.getMetaData();
//使用元数据对象,查询结果集中的列的数量
int columnCount = rsmd.getColumnCount();
//创建一个List类型的集合,保存结果集中列的名称
List<String> columns = new ArrayList<String>(columnCount);
//使用循环从元数据对象中提取结果集中每列的列名,并将列名保存到集合
for(int i = 0 ; i < columnCount ; i++) {
//注意这里调用的是getColumnLabel方法,而不是getColumnName方法
String columnName = rsmd.getColumnLabel(i+1);
columns.add(columnName);
}
//遍历结果集
while(rs.next()) {
T t = clz.newInstance();
//根据列的名称,遍历行中的列
for(String columnName : columns) {
//获取类中的所有属性,包含private属性
Field [] fields = clz.getDeclaredFields();
for(Field field : fields ) {
//用列名和属性名进行比较(忽略大小写)
if(field.getName().equalsIgnoreCase(columnName)) {
Object value = null;
Class type = field.getType();
if(type == java.lang.Integer.class) {
value = rs.getInt(columnName);
}
else if(type == Double.class) {
value = rs.getDouble(columnName);
}
else if(type == Long.class) {
value = rs.getLong(columnName);
}
else if(type == String.class) {
value = rs.getString(columnName);
}
else if(type == Boolean.class) {
value = rs.getBoolean(columnName);
}
else if(type == Date.class || type == java.util.Date.class) {
value = rs.getDate(columnName);
}
else {
value = rs.getObject(columnName);
}
//强制访问属性
field.setAccessible(true);
//给 t 对象的 field属性赋值
field.set(t, value);
break;
}
}
}
data.add(t);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
finally {
//释放资源
DBHelper.getInstance().close(rs, pstm, conn);
}
return null;
}
下面来看可以多表查询的方法:
/**
* 执行所有的查询
* @param sql
* @param clz
* @param params
* @return List<T>
*/
public <T> List<T> executeQuery(String sql,ResultHandler<T> handler,Object...params){
ResultSet rs = null;
PreparedStatement pstm = null;
Connection conn = null;
try {
//连接数据库
conn = DBHelper.getInstance().getConnection();
//实例化pstm
pstm = conn.prepareStatement(sql);
//给sql语句中的占位符赋值,根据params中元素的数量推断sql语句中占位符(?)的数量
if(params != null && params.length > 0) {
for(int i = 0 ; i < params.length ; i++) {
pstm.setObject(i+1, params[i]);
}
}
//发送sql语句
rs = pstm.executeQuery();
List<T> data = handler.handResult(rs);
return data;
} catch (Exception e) {
e.printStackTrace();
}
finally {
//释放资源
DBHelper.getInstance().close(rs, pstm, conn);
}
return null;
}