/**
*
*/
package cn.web.jdbc;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.sql.rowset.CachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
/**
* @author Administrator
* 单例模式: 保证一个项目里面 只有一个类的实例<br>
* 4要素:<br>
* 1、1个私有的构造方法 <br>
* 2、1个私有的静态的类的实例 <br>
* 3、1个公有的 静态的 同步的 方法<br>
* 4、重载一个clone方法 <br>
*/
public class JdbcTool {
private static JdbcTool INSTANCE = null;
private JdbcTool() {
}
public static synchronized JdbcTool getInstance() {
// return new JdbcTool();
if(null == INSTANCE) {
INSTANCE = new JdbcTool();
}
return INSTANCE;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return getInstance();
}
/**
* 连接对象
*/
public Connection getConnection() {
String driverName = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String username = "scott";
String password = "tiger";
Connection connection = null;
try {
// 1、加载驱动
Class.forName(driverName);
// 2、创建连接
connection = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
/**
* 执行查询
* @param querySql
* @return
* @throws Exception
*/
public ResultSet executeQuery(Connection connection, String querySql) throws Exception {
Statement statement = connection.createStatement();
// ResultSet resultSet = statement.executeQuery(querySql);
// return resultSet;
return statement.executeQuery(querySql);
}
/**
* 执行预处理查询
* @param connection
* @param querySql
* @throws Exception
*/
public <T> List<T> executeQueryList(Connection connection, String querySql,
Object [] params, Class<T> t) throws Exception {
PreparedStatement preparedStatement = connection.prepareStatement(querySql);
if (null != params && params.length>=1) {
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1, params[i]);
}
}
return parseResultSet(preparedStatement.executeQuery(), t);
}
/**
* 执行预处理查询
* @param connection
* @param querySql
* @throws Exception
*/
public ResultSet executePreparedQuery(Connection connection,
String querySql, Object [] params) throws Exception {
PreparedStatement preparedStatement = connection.prepareStatement(querySql);
if (null != params && params.length>=1) {
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1, params[i]);
}
}
return preparedStatement.executeQuery();
}
public int getCount(Connection connection, String countSql) {
int count = 0;
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(countSql);
if(resultSet.next()) {
count = resultSet.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return count;
}
/**
* 执行更新
* @param updateSql
* @return
*/
public int executeUpdate(Connection connection, String updateSql) {
// TODO Auto-generated method stub
return 0;
}
// 封装公共代码
public static void executePreparedUpdate(Connection connection,
String sql, Object[] params) throws Exception {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if (null != params && params.length>=1) {
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i+1, params[i]);
}
}
}
/**
* 关闭连接对象
* @param connection
*/
public void closeConnection(Connection connection) {
// 6、关闭连接
try {
connection.close(); // 关闭连接对象之后,ResultSet无法使用
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 用于测试:输出结果集的内容
* @param resultSet
*/
public void dumpResultSet(ResultSet resultSet) {
if ( null == resultSet) {
return;
}
try {
// 结果集的游标不在第一行
if(!resultSet.isBeforeFirst()){
resultSet.beforeFirst();
}
// System.out.println(resultSet.last()); // 移到最后一行
// System.out.println(resultSet.getRow()); // 获取结果集行数
ResultSetMetaData metaData = resultSet.getMetaData();
int num = metaData.getColumnCount();
while(resultSet.next()) {
for (int i = 0; i < num; i++) {
System.out.print(resultSet.getObject(i+1) + "\t");
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通用的查询方法: 结合 泛型,反射,JDBC 元数据
* @param resultSet
* @param clazz
* @return
*/
public <T> List<T> parseResultSet(ResultSet resultSet, Class<T> clazz) {
List<T> list = new ArrayList<T>();
// 1.判断是否为空
if(null == resultSet) {
return list;
}
try {
//2、结果集的指针有没有位于第一个记录的前面,如果不是,将结果集的指针指向第一条记录
CachedRowSet cachedRowSet = new CachedRowSetImpl();
cachedRowSet.populate(resultSet);
if (!cachedRowSet.isBeforeFirst()) {
cachedRowSet.beforeFirst();
}
// 3.1、 获取元数据
ResultSetMetaData metaData = cachedRowSet.getMetaData();
// 3.2获取结果集有几列
int num = metaData.getColumnCount();
String[] columnNames = new String[num];
for (int i = 0; i < num; i++) {
columnNames[i] = metaData.getColumnName(i+1);
}
Method[] methods = clazz.getMethods();
//3.3 处理结果集, 遍历每一行
while(cachedRowSet.next()) {
T t = clazz.newInstance(); // 实例化对象
// 3.4遍历每一行记录 的所有列,最终把每一列的值 设置到对象的属性中
for (int i = 0; i < num; i++) {
// 把列名转换成方法名
String columnName = columnNames[i];
// String methodName = "set" + columnName.substring(0, 1).toUpperCase()
// + columnName.substring(1).toLowerCase();
String methodName = "set" + columnName;
// 反射 找到 该列 对应的方法Method
for (Method setMethod : methods) {
if (methodName.equalsIgnoreCase(setMethod.getName())) {
// 反射判断方法的参数类型是否相同
String fieldTypeName = setMethod.getParameterTypes()[0].getName();
// 数据库中的类型
String columnTypeName = cachedRowSet.getObject(columnName).getClass().getName();
// 如果类型不相同,则继续下一个方法
if(!fieldTypeName.equals(columnTypeName)){
continue;
}
// 使用反射调用方法
setMethod.invoke(t, new Object[]{cachedRowSet.getObject(columnName)});
}
}
}
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}