来更新下本文的JDBCTemplate类的内容,新增如下内容:
1. 字段驼峰映射功能,在数据库中是table_name,而在java中就可以写tableName
2. 扩展查询结果提取,增加考虑查询结果为一个单数据的返回情况(如查询结果就是一个long值)。备注:因为前一个版本适用的是查询结果为一个对象的多个属性,可以封装数为对象返回,但是如果查询结果就是一个long值,由于反射获取字段,而long没有属性,所以就无能为力了。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class JDBCTemplate {
private Logger logger = LoggerFactory.getLogger(JDBCTemplate.class);
public List queryObjectList(Connection connection, String sql, Class requiredClass) throws Exception {
return queryObjectList(connection, sql, requiredClass, false);
}
public List queryObjectListWithCameCase(Connection connection, String sql, Class requiredClass) throws Exception {
return queryObjectList(connection, sql, requiredClass, true);
}
private List queryObjectList(Connection connection, String sql, Class requiredClass, boolean camelCase) throws Exception {
List resutls = new ArrayList<>();
business(connection, sql, requiredClass, resutls, false, camelCase);
return resutls;
}
public <T> T queryObject(Connection connection, String sql, Class<T> requiredClass) throws Exception {
return queryObject(connection, sql, requiredClass, false);
}
public <T> T queryObjectWithCameCase(Connection connection, String sql, Class<T> requiredClass) throws Exception {
return queryObject(connection, sql, requiredClass, true);
}
private <T> T queryObject(Connection connection, String sql, Class<T> requiredClass, boolean camelCase) throws Exception {
T instance = requiredClass.getDeclaredConstructor().newInstance();
business(connection, sql, requiredClass, instance, true, camelCase);
return instance;
}
private <T> T business(Connection connection, String selectSqlTmp, Class<T> requiredClass, Object object, boolean isSingle, boolean camelCase) throws Exception {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement(selectSqlTmp);
resultSet = preparedStatement.executeQuery();
if (isSingle) {
while (resultSet.next()) {
T instance = generateObject(resultSet, requiredClass, camelCase);
object = (T) instance;
}
// else {
// logger.info("没有查询结果!");
// }
// generateObjects(resultSet, requiredClass, null);
} else {
List<T> results = (List<T>) object;
while (resultSet.next()) {
T instance = generateObject(resultSet, requiredClass, camelCase);
results.add(instance);
}
// else {
// logger.info("没有查询结果!");
// }
}
} catch (Exception e) {
logger.error("查询数据库出错!", e);
throw e;
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException throwables) {
logger.error("preparedStatement error:", throwables);
}
}
return null;
}
private <T> T generateObject(ResultSet resultSet, Class<T> requiredClass, boolean camelCase) throws Exception {
T instance = requiredClass.getDeclaredConstructor().newInstance();
Field[] declaredFields = requiredClass.getDeclaredFields();
if (declaredFields == null || declaredFields.length == 0) {
//也许查询的结果就是对象本身,比如就是查询一个long值出来
instance = getFieldValue(resultSet, requiredClass);
} else {
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
String fieldName = declaredField.getName();
Class<?> type = declaredField.getType();
declaredField.set(instance, getFieldValue(resultSet, fieldName, type, camelCase));
}
}
return instance;
}
private <A> A getFieldValue(ResultSet resultSet, Class<A> fieldclazz) throws Exception {
A object = null;
try {
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
while (resultSet.next()) {
for (int i = 0; i < columnCount; i++) {
object = resultSet.getObject(i, fieldclazz);
break;
}
break;
}
} catch (Exception e) {
logger.error("", e);
}
return object;
}
private <A> A getFieldValue(ResultSet resultSet, String fieldName, Class<A> fieldclazz, boolean camelCase) throws Exception {
A object = null;
try {
if (camelCase) {
//驼峰转下划线
fieldName = CamelCaseUtil.toUnderlineCase(fieldName);
}
if (isExitColumn(resultSet, fieldName)) {
object = (A) resultSet.getObject(fieldName, fieldclazz);
}
} catch (Exception e) {
logger.error("", e);
}
return object;
}
private boolean isExitColumn(ResultSet resultSet, String fieldName) {
try {
resultSet.findColumn(fieldName);
return true;
} catch (SQLException throwables) {
return false;
}
}
}
备注: CamelCaseUtil见:
https://blog.csdn.net/jfqqqqq/article/details/119408238
----------------------------------------------------------- 分割线 -----------------------------------------------------------------
最近想回顾jdbc编程和反射机制,于是产生了下面的代码,其中返回集合的接口绝对测试通过,返回对象的没有测试,应该也没有问题,如果有发现问题的小伙伴,帮忙指出下,谢谢!
package com.jfqqqq.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JDBCTemplate {
private Logger logger = LoggerFactory.getLogger(JDBCTemplate.class);
public List queryObjectList(Connection connection, String sql, Class requiredClass) throws Exception {
List resutls = new ArrayList<>();
business(connection, sql, requiredClass, resutls, false);
return resutls;
}
public <T> T queryObject(Connection connection, String sql, Class<T> requiredClass) throws Exception {
T instance = requiredClass.getDeclaredConstructor().newInstance();
business(connection, sql, requiredClass, instance, true);
return instance;
}
private <T> T business(Connection connection, String selectSqlTmp, Class<T> requiredClass, Object object, boolean isSingle) {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement(selectSqlTmp);
resultSet = preparedStatement.executeQuery();
if (isSingle) {
while (resultSet.next()) {
T instance = generateObjects(resultSet, requiredClass);
object = (T) instance;
}
// else {
// logger.info("没有查询结果!");
// }
// generateObjects(resultSet, requiredClass, null);
} else {
List<T> results = (List<T>) object;
while (resultSet.next()) {
T instance = generateObjects(resultSet, requiredClass);
results.add(instance);
}
// else {
// logger.info("没有查询结果!");
// }
}
} catch (Exception e) {
logger.error("查询数据库出错!", e);
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException throwables) {
logger.error("preparedStatement error:", throwables);
}
}
return null;
}
private <T> T generateObjects(ResultSet resultSet, Class<T> requiredClass) throws Exception {
T instance = requiredClass.getDeclaredConstructor().newInstance();
Field[] declaredFields = requiredClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
String fieldName = declaredField.getName();
Class<?> type = declaredField.getType();
declaredField.set(instance, getFieldValue(resultSet, fieldName, type));
}
return instance;
}
private <A> A getFieldValue(ResultSet resultSet, String fieldName, Class<A> fieldclazz) throws Exception {
A object = null;
try {
if (isExitColumn(resultSet, fieldName)) {
object = (A) resultSet.getObject(fieldName, fieldclazz);
}
} catch (Exception e) {
logger.error("{}", e);
}
return object;
}
private boolean isExitColumn(ResultSet resultSet, String fieldName) {
try {
resultSet.findColumn(fieldName);
return true;
} catch (SQLException throwables) {
return false;
}
}
}