public class JdbcHandler {
private JdbcHandler() {
}
/**
* 专门用来完成需要返回自增主键的insert操作
*
* @param sql
* @param keyCoulmnName 主键列
* @param params
* @return
*/
public static int insert(String sql, String keyCoulmnName, Object... params) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = DBUtils.getConnection();
ps = con.prepareStatement(sql, new String[]{keyCoulmnName});
//设置占位符参数
setParameter(ps, sql, params);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
if (rs.next()) {
return rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.closeResource(con, ps, rs);
}
return -1;
}
/**
* 定义DML操作
*
* @param sql
* @param params
* @return 返回受影响的行数
*/
public static int update(String sql, Object... params) {
Connection con = null;
PreparedStatement ps = null;
try {
con = DBUtils.getConnection();
ps = con.prepareStatement(sql);
//设置占位符参数
setParameter(ps, sql, params);
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.closeResource(con, ps,null );
}
return -1;
}
/**
* 可以查询单个对象:先以列表方式查询,如果长度不为0,就获取第一个元素
*
* @param sql
* @param clazz
* @param params
* @param <T>
* @return
*/
public static <T> T queryForObject(String sql, Class<T> clazz, Object... params) {
List<T> list = queryForList(sql, clazz, params);
if (list.size() != 0) {
return list.get(0);
}
return null;
}
/**
* @param clazz 指定返回集合泛型对应的类信息,方便在结果集遍历中通过反射进行实例化
* @param sql 要执行的sql语句
* @param <T> 可以是Emp,Dept,……
* @param params 要传递的占位符参数的值
* @return 返回查询后的列表
*/
public static <T> List<T> queryForList(String sql, Class<T> clazz, Object... params) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
try {
con = DBUtils.getConnection();
ps = con.prepareStatement(sql);
setParameter(ps, sql, params);
rs = ps.executeQuery();
//ResultSetMetaData:结果集元数据对象,在这个对象中封装了结果集的具体信息
//例如结果集中字段的名字,以及字段的数量等内容
ResultSetMetaData rsmd = rs.getMetaData();
while (rs.next()) {
T t = null;
//如果没有无参构造方法
if (String.class == clazz) {
t = (T) rs.getString(1);
} else if (int.class == clazz || Integer.class == clazz) {
t = (T) new Integer(rs.getInt(1));
} else if (double.class == clazz || Double.class == clazz) {
t = (T) new Double(rs.getDouble(1));
} else if (java.util.Date.class == clazz || Date.class == clazz) {
t = (T) rs.getDate(1);
}
//TODO: 其它数据类型
else {
//如果是有无参构造方法的类型则通过下面的方式进行实例化
//通过无参构造进行实例化
t = clazz.newInstance();
//为当前对象的属性进行赋值
//思路:将结果集中对应字段的值赋值给对象的属性值
//例如:empno字段对应empno属性
//ename字段对应ename属性
//……
//根据结果集中所有的列名分别获取所有对应的属性名,然后对每一个属性都来进行赋值
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
//获取列名
String columnName = rsmd.getColumnLabel(i);
//根据列名获取类中的属性对象
Field field = getFieldByName(clazz, columnName);
//如果能找到属性,则对属性进行赋值操作
if (field != null) {
field.setAccessible(true);
//获取属性的类型
Class<?> fieldType = field.getType();
if (String.class == fieldType) {
field.set(t, rs.getString(i));
}
if (int.class == fieldType || Integer.class == fieldType) {
field.set(t, rs.getInt(i));
}
if (double.class == fieldType || Double.class == fieldType) {
field.set(t, rs.getDouble(i));
}
if (java.util.Date.class == fieldType || Date.class == fieldType) {
//TODO 重新处理date型的逻辑
// field.set(t, rs.getDate(i));
try {
field.set(t, new Date(rs.getTimestamp(i).getTime()));
} catch (Exception e) {
e.printStackTrace();
field.set(t, rs.getDate(i));
}
}
//TODO;其它数据类型
if (Timestamp.class == fieldType) {
field.set(t, rs.getTimestamp(i));
}
field.setAccessible(false);
}
}
}
list.add(t);
}
} catch (SQLException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
} finally {
DBUtils.closeResource(con, ps,rs );
}
return list;
}
/**
* 根据列名获取属性对象
*
* @param clazz 当前要获取属性对象的类
* @param columnName 列名
* @return
*/
private static Field getFieldByName(Class<?> clazz, String columnName) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//考虑列名和属性名存在大小写不同的情况
if (field.getName().equalsIgnoreCase(columnName)) {
return field;
}
}
return null;
}
/**
* 从sql语句中获取占位符参数的个数
*
* @param sql
* @return
*/
private static int getPlaceHolderCount(String sql) {
int count = 0;
Matcher matcher = Pattern.compile("\\?").matcher(sql);
while (matcher.find()) {
count++;
}
return count;
}
/**
* 设置占位符参数
*/
private static void setParameter(PreparedStatement ps, String sql, Object... params) throws SQLException {
int placeHolderCount = getPlaceHolderCount(sql);
if (params != null) {
if (params.length != placeHolderCount) {
throw new SQLException("有" + params.length + "个参数,但是占位符个数为:" + placeHolderCount);
}
}
//设置占位符参数的值
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
}
}
jdbchandler
最新推荐文章于 2023-05-25 12:56:51 发布