JDBC底层增删改的返回值都是布尔类型,可以把增删改封装为同一个方法,查询封装为另一个方法。
通用的增删改代码如下:
public void update(Connection connection, String sql, Object... objects) {
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
for (int i = 1; i <= objects.length; i++) {
preparedStatement.setObject(i, objects[i-1]);
}
preparedStatement.execute();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
该方法形参接受一个Connection对象,该对象用于生成PreparedStatement 对象,另一个形参为要预编译的sql语句,用“?”来占位,因为占位符的类型和个数不确定,另一个参数故使用Object类型的可变参数,其实该参数最后封装为一个Object数组。然后在方法中循环该数组使用preparedStatement.setObject赋值到占位符中。
最后执行execute方法,如果返回false则更新失败,反之则成功。
通用的查询代码如下:
public <T> List<T> query(Connection connection, String sql, Class<T> clazz, Object... objects) {
PreparedStatement preparedStatement = null;
List<T> list = null;
try {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < objects.length; i++) {
preparedStatement.setObject(i+1, objects[i]);
}
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
list = new ArrayList<T>();
while (resultSet.next()) {
try {
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {
Object object = resultSet.getObject(i + 1);
Field declaredField = clazz.getDeclaredField(metaData.getColumnLabel(i + 1));
declaredField.setAccessible(true);
declaredField.set(t, object);
}
list.add(t);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return list;
}
该方法第一个参数传入Connection对象,第二个传入要查询的预编译sql语句,第三个传入要返回的类型的Class对象,第四个传入要预编译占位符的值,该参数是个可变参数。使用了泛型方法使该方法具有通用性,该方法与增删改不同的是增加了返回值的处理。
ResultSet resultSet = preparedStatement.executeQuery();返回的是结果集对象,该对象可以利用next方法判断下一行有没有值;
ResultSetMetaData metaData = resultSet.getMetaData();该方法返回元数据对象,该对象可以获取结果集有多少列和获取指定列的字段名等。
在while循环中首先根据Class对象创建该类的实例(该类必须包含无参构造),然后利用列数循环为该对象的属性赋值,利用反射的原理获取Field对象赋值,赋值后添加到List集合中。
最后返回List集合对象。

本文介绍了一种基于JDBC的通用增删改查方法实现,通过预编译SQL语句和反射机制,实现了对数据库操作的高度封装。适用于快速开发场景。

171

被折叠的 条评论
为什么被折叠?



