自定义JDBC连接,以及实现查询数据库内容转Map、集合、JavaBean
一、自定义JDBC连接
创建util工具包,在util工具包内创建JdbcUtils连接类。
分析:
1.使用JDBC连接数据库需要先准备JdbcUrl,username,password,所以需要预先准备好上述的三个变量,这里需要注意的是,这三个变量使用private static进行修饰
private static String jdbcUrl;
private static String user;
private static String password;
原因为,我们使用JdbcUtils类进行连接时,不希望实例化对象,而直接使用连接方法,所以之后定义的连接方法需要使用static进行修饰,这样上面的三个资源就必须使用static进行修饰
2.上面说到使用JdbcUtils类进行连接时,我们希望直接调用连接方法,那么连接方法使用static修饰即可,但是我们知道在创建JDBC连接时,必须要先加载JDBC连接驱动,所以这里采用了静态代码块的方式进行JDBC连接驱动的类加载。静态代码块修饰的内容在JdbcUtils类加载时执行,这样当后面在使用JdbcUtils中连接方法时,JDBC连接驱动已经加载完成。
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
3.接下来创建JDBC连接方法,在该方法中使用DriverManager驱动管理类进行数据库的连接。
public static Connection getConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcUrl, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
这里出现了另外一个问题,那就是我们上面准备的JdbcUrl,username,password,并没有值,当然我们也不能直接在JdbcUtils类中对其进行赋值,这样就将该连接方式写死了,以后再用就需要修改代码,这是不合理的,在这里需要引入配置文件,可以将JdbcUrl,username,password的信息保存在配置文件中,然后在JdbcUtils类中读取该配置文件中的内容即可
创建db.properties配置文件,文件内容如下:
#JDBC连接驱动
className=com.mysql.jdbc.Driver
#连接地址
jdbcUrl=jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false
#用户名
user=root
#密码
password=123123
更改上诉静态代码块中的内容,在执行连接方法之前将配置文件中的内容加载到JdbcUtils类中
static {
try {
// 利用JdbcUtilsPlus.class对象获取当前类加载器在当前class文件所处项目位置检索指定名称的文件,
// 获取对应文件的InputStream字节输入流对象
InputStream resourceAsStream = JdbcUtilsPlus.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
jdbcUrl = properties.getProperty("jdbcUrl");
user = properties.getProperty("user");
password = properties.getProperty("password");
Class.forName(properties.getProperty("className"));
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
4.创建JDBC关闭方法,在执行完JDBC操作后需要关闭相应资源,在这里需要注意先用后关的基本要求
定义关闭方法如下:
private static void close(AutoCloseable... resources) {
for (AutoCloseable resource : resources) {
try {
if (resource != null) {
resource.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里使用了不定长参数,因为并不能确定用户打开的资源个数,这里就拿常用的三个资源来说:Connection connection, Statement statement, ResultSet resultSet,数据库连接对象,sql语句执行对象,结果集对象,上面三类均实现了AutoCloseable 接口,所以这里可以使用接口多态。
在给用户提供多种关闭资源的方式
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
close(resultSet, statement, connection);
}
public static void close(Connection connection, Statement statement) {
close(statement, connection);
}
public static void close(Connection connection) {
close(connection);
}
这样就完成了JdbcUtils连接工具的创建。
二、自定义BaseDao工具类
/**
* BaseDao
* 基础数据库持久化操作类
* 提供通用的
* 1.update更新方法
* 2.query查询套餐方法
* 2.a.JavaBean规范对象
* 2.b.键值对Map双边队列
* 2.c.仅数据模式的Object数组
* /
代码如下:
package util;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* BaseDao
* 基础数据库持久化操作类
* 提供通用的
* 1.update更新方法
* 2.query查询套餐方法
* 2.a.JavaBean规范对象
* 2.b.键值对Map双边队列
* 2.c.仅数据模式的Object数组
*
*/
public class BaseDao {
/**
* 提供对应的增删改操作
*
* @param sql 指定对应功能的Sql语句
* @param parameters 指定对应的参数列表
* @return 返回影响的行数
* @throws SQLException
*/
public int update(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
connection = JdbcUtils.getConnection();
int affectedRows = 0;
try {
statement = connection.prepareStatement(sql);
/**
* 获取当前数据的元数据
*/
ParameterMetaData parameterMetaData = statement.getParameterMetaData();
/**
* 通过parameterMetaData调用getParameterCount()方法获取Sql语句中的参数个数
* 问号个数
*/
int parameterCount = parameterMetaData.getParameterCount();
if (parameterCount != parameters.length) {
throw new IllegalArgumentException("Sql语句所需参数不符");
}
for (int i = 0; i < parameters.length; i++) {
statement.setObject(i + 1, parameters[i]);
}
affectedRows = statement.executeUpdate();
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement);
}
return affectedRows;
}
/**
* 查询一条记录,返回Map<String, Object>类型双边队列
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的ListMap <String, Object>类型双边队列,查询不到返回NULL,不指定查询条件,返回第一条记录
* @throws SQLException
*/
public Map<String, Object> queryMap(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
Map<String, Object> map = new HashMap<>(16);
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
// 获取结果集元数据
ResultSetMetaData metaData = resultSet.getMetaData();
// 解析结果集
if (resultSet.next()) {
for (int i = 1; i <= metaData.getColumnCount(); i++) {
map.put(metaData.getColumnName(i), resultSet.getObject(i));
}
}
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return map.isEmpty() ? null : map;
}
/**
* 查询多条记录,返回List<Map<String, Object>>类型集合
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的List<Map < String, Object>>类型集合,查询不到返回NULL,不指定查询条件,返回所有记录
* @throws SQLException
*/
public List<Map<String, Object>> queryListMap(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
ArrayList<Map<String, Object>> maps = new ArrayList<>();
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
// 获取结果集元数据
ResultSetMetaData metaData = resultSet.getMetaData();
// 解析结果集
while (resultSet.next()) {
Map<String, Object> map = new HashMap<>(16);
for (int i = 1; i <= metaData.getColumnCount(); i++) {
map.put(metaData.getColumnName(i), resultSet.getObject(i));
}
maps.add(map);
}
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return maps.isEmpty() ? null : maps;
}
/**
* 查询多条记录,返回List<Object[]>类型集合
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的List<Object [ ]>类型集合,查询不到返回NULL,不指定查询条件,返回所有记录
* @throws SQLException
*/
public List<Object[]> queryArrayList(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
ArrayList<Object[]> list = new ArrayList<>();
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
while (resultSet.next()) {
Object[] obj = new Object[metaData.getColumnCount()];
for (int i = 0; i < metaData.getColumnCount(); i++) {
obj[i] = resultSet.getObject(i + 1);
}
list.add(obj);
}
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return list.isEmpty() ? null : list;
}
/**
* 查询单条记录,返回Object类型数组
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的Object类型数组,查询不到返回NULL,不指定查询条件,返回第一条记录
* @throws SQLException
*/
public Object[] queryArray(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
Object[] obj = new Object[metaData.getColumnCount()];
if (resultSet.next()) {
for (int i = 0; i < metaData.getColumnCount(); i++) {
obj[i] = resultSet.getObject(i + 1);
}
}
return obj;
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
}
/**
* 根据指定的sql查询对应的信息,返回对应的JavaBean规范的数据对象集合
*
* @param sql 指定的sql查询信息
* @param cls JavaBean规范的对象
* @param parameters 指定查询参数
* @param <T>
* @return 返回对应的JavaBean规范的数据对象集合
* @throws SQLException
*/
public <T> List<T> queryListBean(String sql, Class<T> cls, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
ArrayList<T> list = new ArrayList<>();
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
Constructor<T> constructor = cls.getConstructor();
int columnCount = resultSet.getMetaData().getColumnCount();
while (resultSet.next()) {
T t = constructor.newInstance();
for (int i = 1; i <= columnCount; i++) {
BeanUtils.setProperty(t, resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
}
list.add(t);
}
} catch (SQLException e) {
throw e;
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return list;
}
/**
* 根据指定的sql查询对应的信息,返回对应的JavaBean规范的数据对
*
* @param sql 指定的sql查询信息
* @param cls JavaBean规范的对象
* @param parameters 指定查询参数
* @param <T>
* @return 返回对应的JavaBean规范的数据对象
* @throws SQLException
*/
public <T> T queryBean(String sql, Class<T> cls, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
T t = null;
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
Constructor<T> constructor = cls.getConstructor();
int columnCount = resultSet.getMetaData().getColumnCount();
if (resultSet.next()) {
t = constructor.newInstance();
for (int i = 1; i <= columnCount; i++) {
BeanUtils.setProperty(t, resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
}
}
} catch (SQLException e) {
throw e;
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return t;
}
/**
* 校验输入的Sql语句是否合法
*
* @param sql 输入的Sql语句
*/
private void check(String sql) {
if (null == sql || sql.isEmpty()) {
throw new IllegalArgumentException("非法sql语句异常");
}
}
/**
* 校验传入的参数和Sql语句所需的参数是否符合,不符合抛出非法参数异常
* 符合将输入的参数列表提交到对那个的sql位置
*
* @param statement PreparedStatement类型的sql语句执行接口
* @param parameters 用户提供的参数列表
* @throws SQLException
*/
private void handlereStatement(PreparedStatement statement, Object[] parameters) throws SQLException {
ParameterMetaData parameterMetaData = statement.getParameterMetaData();
if (parameterMetaData.getParameterCount() != parameters.length) {
throw new IllegalArgumentException("Sql语句所需参数不符");
}
for (int i = 0; i < parameters.length; i++) {
statement.setObject(i + 1, parameters[i]);
}
}
}
从上面的代码可以看出代码非常的冗余,下面让我们采用另外一种方式将其改进。
分析:对上述代码的查询功能进行分析,可知,上面的建立数据库连接,执行sql语句,以及下面关闭资源的操作基本一样,不同点仅仅在于对数据的处理,这样我们可以设计一个接口,接口中只有一个数据处理方法,然后在各个实现类中完成数据的处理。
接口如下:
package util;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 自定义Java.sql.ResultSet数据库查询结果集对象
*
*/
public interface ResultSetHandler<T> {
/**
* 结果集处理器接口
*
* @param resultSet 结果集
* @return 由实现类决定
* @throws SQLException
*/
T handler(ResultSet resultSet) throws SQLException;
}
首先设计如下代码:
/**
* 通用查询方法
* 方法所需参数是执行目标的 SQL 语句,对应当前结果集处理方式 ResultSetHandler 接口实现类,
* 同时利用 ResultSetHandler 类型约束泛型对应具体数据类型,也是同时约束当前方法对应的返回
* 值类型。方法还需要给予 SQL 语句所需参数列表,返回值类型由 ResultSetHandler 处理器接口
* 约束。
*
* @param sql 目标查询执行的 SQL 语句
* @param rsh ResultSetHandler 结果集处理器接口实现类对象,同时约束泛型,也就是约束方法
* 返回值类型
* @param parameters 对应的 SQL 语句的参数列表,为 Object 类型不定长参数
* @param <T> 自定义泛型占位符,主要约束当前方法的返回值结果
* @return 根据当前使用的 ResultSetHandler 结果集处理器方式,返回值对应 ResultSet 最终数据
* 处理结果
*/
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... parameters) throws SQLException {
check(sql);
PreparedStatement statement = null;
ResultSet resultSet = null;
Connection connection = null;
FileUtils.addJdbcInformation("D:/JavaSE_Study/MysqlStudy/src/jdbcstudy/path.txt");
connection = JdbcUtils.getConnection();
T t = null;
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
t = rsh.handler(resultSet);
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return t;
}
在来设计实现类,以ListBean为例:
package util.impl;
import org.apache.commons.beanutils.BeanUtils;
import util.ResultSetHandler;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ListBeanHandler<T> implements ResultSetHandler<List<T>> {
private final Class<T> cls;
public ListBeanHandler(Class<T> cls) {
this.cls = cls;
}
@Override
public List<T> handler(ResultSet resultSet) throws SQLException {
T t = null;
ArrayList<T> list = null;
try {
Constructor<T> constructor = cls.getConstructor();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
list = new ArrayList<>(columnCount);
while (resultSet.next()) {
t = constructor.newInstance();
for (int i = 1; i <= columnCount; i++) {
BeanUtils.setProperty(t, metaData.getColumnName(i), resultSet.getObject(i));
}
list.add(t);
}
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return list.isEmpty() ? null : list;
}
}
后面对于不同的方法设计不同的类即可,这里面的BeanUtils.setProperty使用了第三方jar包
若不想使用,可以使用反射完成上诉操作
package com.test1;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 实现符合 JavaBean 规范实体类
*
*/
public class BeanUtils {
/**
* 用户指定符合 JavaBean 规范的类对象 bean,指定当前类对象中的对应成员变量名称,
* 给予当前成员变量赋值使用数据 String 类型参数 value,完成赋值操作
*
* @param bean 指定的JavaBean规范对象
* @param fieldName 属性
* @param value 值
*/
public static void setProperty(Object bean, String fieldName, String value) {
// 获取该JavaBean对象的Class对象
Class<?> cls = bean.getClass();
try {
Field field = cls.getDeclaredField(fieldName);
field.setAccessible(true);
Class<?> type = field.getType();
if (String.class.equals(type)) {
field.set(bean, value);
} else if (Integer.class.equals(type)) {
field.set(bean, Integer.parseInt(value));
} else if (Character.class.equals(type)) {
field.set(bean, value.charAt(0));
} else {
Method method = type.getMethod("parse" + type.getName().substring(type.getName().lastIndexOf(".") + 1), String.class);
field.set(bean, method.invoke(null, value));
}
} catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 获取用户指定符合 JavaBean 规范类对象 bean,
* 指定成员变量名称 fieldName 存储的数据,为保证数据的精确性,返回值类型是 String 类型
*
* @param bean 指定的JavaBean规范对象
* @param fieldName 指定的属性
* @return 返回该属性对应的值
*/
public static String getProperty(Object bean, String fieldName) {
Class<?> cls = bean.getClass();
Object o = null;
try {
Field field = cls.getDeclaredField(fieldName);
field.setAccessible(true);
o = field.get(bean);
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
return String.valueOf(o);
}
public static void populate(Object bean, Map<String, String> map) {
Class<?> cls = bean.getClass();
for (Map.Entry<String, String> entry : map.entrySet()) {
setProperty(bean, entry.getKey(), entry.getValue());
}
}
}
这里不再多说
改进完的代码如下:
package util;
import util.impl.*;
import java.sql.*;
import java.util.List;
import java.util.Map;
/**
* BaseDao
* 基础数据库持久化操作类
* 提供通用的
* 1.update更新方法
* 2.query查询套餐方法
* 2.a.JavaBean规范对象
* 2.b.键值对Map双边队列
* 2.c.仅数据模式的Object数组
*
*/
public class BaseDaoPlus {
/**
* 提供对应的增删改操作
*
* @param sql 指定对应功能的Sql语句
* @param parameters 指定对应的参数列表
* @return 返回影响的行数
* @throws SQLException
*/
public int update(String sql, Object... parameters) throws SQLException {
check(sql);
Connection connection = null;
PreparedStatement statement = null;
FileUtils.addJdbcInformation("D:/JavaSE_Study/MysqlStudy/src/jdbcstudy/path.txt");
connection = JdbcUtils.getConnection();
int affectedRows = 0;
try {
statement = connection.prepareStatement(sql);
/**
* 获取当前数据的元数据
*/
ParameterMetaData parameterMetaData = statement.getParameterMetaData();
/**
* 通过parameterMetaData调用getParameterCount()方法获取Sql语句中的参数个数
* 问号个数
*/
int parameterCount = parameterMetaData.getParameterCount();
if (parameterCount != parameters.length) {
throw new IllegalArgumentException("Sql语句所需参数不符");
}
for (int i = 0; i < parameters.length; i++) {
statement.setObject(i + 1, parameters[i]);
}
affectedRows = statement.executeUpdate();
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement);
}
return affectedRows;
}
/**
* 查询一条记录,返回Map<String, Object>类型双边队列
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的ListMap <String, Object>类型双边队列,查询不到返回NULL,不指定查询条件,返回第一条记录
* @throws SQLException
*/
public Map<String, Object> queryMap(String sql, Object... parameters) throws SQLException {
return query(sql, new MapHandler(), parameters);
}
/**
* 查询多条记录,返回List<Map<String, Object>>类型集合
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的List<Map < String, Object>>类型集合,查询不到返回NULL,不指定查询条件,返回所有记录
* @throws SQLException
*/
public List<Map<String, Object>> queryListMap(String sql, Object... parameters) throws SQLException {
return query(sql, new MapListHandler(), parameters);
}
/**
* 查询多条记录,返回List<Object[]>类型集合
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的List<Object [ ]>类型集合,查询不到返回NULL,不指定查询条件,返回所有记录
* @throws SQLException
*/
public List<Object[]> queryArrayList(String sql, Object... parameters) throws SQLException {
return query(sql, new ArrayListHandler(), parameters);
}
/**
* 查询单条记录,返回Object类型数组
*
* @param sql 指定查询Sql语句
* @param parameters 指定查询的参数列表
* @return 返回指定查询条件的Object类型数组,查询不到返回NULL,不指定查询条件,返回第一条记录
* @throws SQLException
*/
public Object[] queryArray(String sql, Object... parameters) throws SQLException {
return query(sql, new ArrayHandler(), parameters);
}
/**
* 根据指定的sql查询对应的信息,返回对应的JavaBean规范的数据对象集合
*
* @param sql 指定的sql查询信息
* @param cls JavaBean规范的对象
* @param parameters 指定查询参数
* @param <T>
* @return 返回对应的JavaBean规范的数据对象集合
* @throws SQLException
*/
public <T> List<T> queryListBean(String sql, Class<T> cls, Object... parameters) throws SQLException {
return query(sql, new ListBeanHandler<>(cls), parameters);
}
/**
* 根据指定的sql查询对应的信息,返回对应的JavaBean规范的数据对
*
* @param sql 指定的sql查询信息
* @param cls JavaBean规范的对象
* @param parameters 指定查询参数
* @param <T>
* @return 返回对应的JavaBean规范的数据对象
* @throws SQLException
*/
public <T> T queryBean(String sql, Class<T> cls, Object... parameters) throws SQLException {
return query(sql, new BeanHandler<>(cls), parameters);
}
/**
* 校验输入的Sql语句是否合法
*
* @param sql 输入的Sql语句
*/
private void check(String sql) {
if (null == sql || sql.isEmpty()) {
throw new IllegalArgumentException("非法sql语句异常");
}
}
/**
* 校验传入的参数和Sql语句所需的参数是否符合,不符合抛出非法参数异常
* 符合将输入的参数列表提交到对那个的sql位置
*
* @param statement PreparedStatement类型的sql语句执行接口
* @param parameters 用户提供的参数列表
* @throws SQLException
*/
private void handlereStatement(PreparedStatement statement, Object[] parameters) throws SQLException {
ParameterMetaData parameterMetaData = statement.getParameterMetaData();
if (parameterMetaData.getParameterCount() != parameters.length) {
throw new IllegalArgumentException("Sql语句所需参数不符");
}
for (int i = 0; i < parameters.length; i++) {
statement.setObject(i + 1, parameters[i]);
}
}
/**
* 通用查询方法
* 方法所需参数是执行目标的 SQL 语句,对应当前结果集处理方式 ResultSetHandler 接口实现类,
* 同时利用 ResultSetHandler 类型约束泛型对应具体数据类型,也是同时约束当前方法对应的返回
* 值类型。方法还需要给予 SQL 语句所需参数列表,返回值类型由 ResultSetHandler 处理器接口
* 约束。
*
* @param sql 目标查询执行的 SQL 语句
* @param rsh ResultSetHandler 结果集处理器接口实现类对象,同时约束泛型,也就是约束方法
* 返回值类型
* @param parameters 对应的 SQL 语句的参数列表,为 Object 类型不定长参数
* @param <T> 自定义泛型占位符,主要约束当前方法的返回值结果
* @return 根据当前使用的 ResultSetHandler 结果集处理器方式,返回值对应 ResultSet 最终数据
* 处理结果
*/
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... parameters) throws SQLException {
check(sql);
PreparedStatement statement = null;
ResultSet resultSet = null;
Connection connection = null;
connection = JdbcUtils.getConnection();
T t = null;
try {
statement = connection.prepareStatement(sql);
handlereStatement(statement, parameters);
resultSet = statement.executeQuery();
t = rsh.handler(resultSet);
} catch (SQLException e) {
throw e;
} finally {
JdbcUtils.close(connection, statement, resultSet);
}
return t;
}
}