JDBC 通用工具类
resources中的jdbc.properties文件
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/java?serverTimezone=GMT&characterEncoding=UTF8
user = root
password = root
DBUtil类
- 有个缺点就是不能获取一个指定类型的实体类,只能获取Object实体类,如果要解决这个问题需要添加DBUtilEntity附在的类
package util;
/**
* HashMap<String, Object> getjdbcResources(sql)
* 获取连接数据库资源包括Connection和PreparedStatement对象放在Map<String,Object>中返回,
*
* ArrayList executeQuerEntitys(jdbcResources)
* 获取一个实体类集合 实体类全部是使用了Object对象,
* 如果要返回一个指定的实体类集合就请使用DBUtilEntity类中的查询
*
* ArrayList<HashMap<String, Object>> executeQuerMep(jdbcResoruces)
* 获取一个数据集合把查询出来的数据放入集合ArrayList集合中其中每个字段使用key:value存储
*
* PreparedStatement getPreparedStatement(jdbcResoruces)
* 获取数据库资源中的PreparedStatement对象
*
* close(jdbcResoruces)
* 关闭数据库资源
*
*/
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
public class DBUtil {
//连接池数量
static final int CONNECTION_POOl_AMOUNT = 10;
//1.加载驱动
/*
getClassLoader() 获取磁盘上对应的class文件加载到
getResourceAsStream() 获取文件所在包下的资源
*/
private static InputStream inputStream = DBUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
//实例化一个Properties对象,用来读取文件里面键值对
private static Properties properties = new Properties();
private static List<Connection> connectionPool = new ArrayList<>();
static {
try {
//properties文件加载inputStream
properties.load(inputStream);
//加载mysql的驱动
Class<?> driver = Class.forName(properties.getProperty("driver"));
//2.建立连接、由于考虑到每次使用都需要建立连接、所以直接一次创建多个,存储到连接池中
creatConnectionPool(CONNECTION_POOl_AMOUNT);
} catch (IOException e) {
System.out.println("properties文件加载失败");
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.out.println("驱动加载失败");
e.printStackTrace();
}
}
/**
* 获取数据库资源里面返回一个资源集合,集合中有Connection和PreparedStatement对象
* @param sql 需要传入一个预定的sql
* @return
*/
//3.创建一个statement对象,交给用户使用,用户对sql语句进行补全了在进行查询或者修改
public static HashMap<String, Object> getJdbcResources(String sql) {
//连接池为空则再次创建连接池
if (connectionPool.size() <= 0) {
//传入默认创建连接池为10个
creatConnectionPool(CONNECTION_POOl_AMOUNT);
}
//在连接池中最后面的一个数据
Connection connection = connectionPool.get(connectionPool.size() - 1);
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
} catch (SQLException throwables) {
System.out.println("创建statement对象失败");
throwables.printStackTrace();
}
//用一个map集合存放创建好的Connection和PreparedStatement
HashMap<String, Object> jdbcResources = new HashMap<>();
jdbcResources.put("connection", connection);
jdbcResources.put("preparedStatement", preparedStatement);
return jdbcResources;
}
/**
* 获取一个数据实体类
* 把每条数据使用一个实体类存放,将实体类放入ArrayList集合中 返回一个ArrayList<E>集合
* 查询完毕会关闭资源
* @param obj
* @param jdbcResources
* @return
*/
public static ArrayList executeQuerEntitys(Object obj, HashMap<String, Object> jdbcResources) {
PreparedStatement preparedStatement = (PreparedStatement) jdbcResources.get("preparedStatement");
ArrayList<Object> objects = new ArrayList<>();
try {
//执行sql语句
ResultSet resultSet = preparedStatement.executeQuery();
//获取表属性
ResultSetMetaData rsmd = resultSet.getMetaData();
//System.out.println(metaData);
Field[] declaredFields = obj.getClass().getDeclaredFields();
int columnCount = rsmd.getColumnCount();
while (resultSet.next()) {
//new一个obj对象
Object entityClass = obj.getClass().newInstance();
for (int i = 0; i < columnCount; i++) {
//获取数据的值
Object columnValue = resultSet.getObject(i + 1);
//私有属性强制访问
declaredFields[i].setAccessible(true);
//数据库查询出来的值放到obj实体类中
declaredFields[i].set(entityClass, columnValue);
}
//这个方法优点傻没删是因为留着看自己的不好经理
/*for (int i = 0; i < declaredFields.length; i++) {
//私有参数强制访问
declaredFields[i].setAccessible(true);
//获取表字段名,从1开始
String columnName = rsmd.getColumnLabel(i + 1);
//System.out.println(columnName);
//获取对象字段属性
String type = declaredFields[i].getType().getName();
System.out.println(type);
switch (type){
case "long":
//resultSet.getLong从查询出来的数据字段名为columnName中获取一个long类型的值
declaredFields[i].set(o,resultSet.getLong(columnName));
break;
case "java.lang.String":
declaredFields[i].set(o,resultSet.getString(columnName));
break;
case "java.sql.Date":
declaredFields[i].set(o,resultSet.getDate(columnName));
break;
case "double":
declaredFields[i].set(o,resultSet.getDouble(columnName));
break;
case "int":
declaredFields[i].set(o,resultSet.getInt(columnName));
break;
default:
System.out.println(type + "类型在工具类中没有");
}
}*/
//System.out.println((Employee) o);
objects.add(entityClass);
}
return objects;
} catch (SQLException | InstantiationException | IllegalAccessException throwables) {
throwables.printStackTrace();
} /*finally {
close(jdbcResources);
}*/
return null;
}
/**
* 获取一个数据集合
* 把查询出来的数据放入集合ArrayList集合中其中每个字段使用key:value存储
* 查询完毕会关闭资源
* @param jdbcResources 传入数据库资源
* @return
*/
public static ArrayList<HashMap<String, Object>> executeQuerMep(HashMap<String, Object> jdbcResources) {
PreparedStatement preparedStatement = (PreparedStatement) jdbcResources.get("preparedStatement");
//如果其中没有PreparedStatement对象 就没法进行查询了
if (preparedStatement == null){
return null;
}
ArrayList<HashMap<String, Object>> allRecord = new ArrayList<>();
allRecord = null;//初值为null
try {
//执行sql语句
ResultSet resultSet = preparedStatement.executeQuery();
//获取表属性
ResultSetMetaData rsmd = resultSet.getMetaData();
/*//如果没有查询到记录的话
if (resultSet.next() == false) {
return null;
}
//将光标移到最前面
resultSet.beforeFirst();*/
int columnCount = rsmd.getColumnCount();//获取列数
//遍历查询出来的数据存入集合中
while (resultSet.next()) {
//new一个hashMap
HashMap<String, Object> singleRecord = new HashMap<>();
for (int i = 0; i < columnCount; i++) {
//获取字段值 getColumnLabel()可以获取别名
String columnName = rsmd.getColumnLabel(i + 1);
//获取数据的值
Object columnValue = resultSet.getObject(i + 1);
//存放到hashMap集合中
singleRecord.put(columnName, columnValue);
}
//存入list集合中去
allRecord.add(singleRecord);
}
return allRecord;//返回存入的资源
} catch (SQLException throwables) {
throwables.printStackTrace();
} /*finally {
close(jdbcResources);
}*/
return null;
}
/**
* 关闭数据库资源
* @param jdbcResources 数据库资源
*/
public static void close(HashMap<String, Object> jdbcResources) {
//如果没有resultSet资源就其它两个资源如果有就关闭三个资源
if(jdbcResources == null){
return;
}
//关闭没有resultSet资源的情况下,并且集合长度为2防止用户在集合中添加了数据
if (jdbcResources.get("resultSet") == null || jdbcResources.size() == 2) {
try {
((Statement) jdbcResources.get("preparedStatement")).close();
((Connection) jdbcResources.get("connection")).close();
connectionPool.remove(connectionPool.size() - 1);
} catch (SQLException throwables) {
System.out.println("资源关闭失败");
throwables.printStackTrace();
}
} else if(jdbcResources.size() == 3){
try {
((Connection) jdbcResources.get("connection")).close();
((Statement) jdbcResources.get("preparedStatement")).close();
((ResultSet) jdbcResources.get("resultSet")).close();
connectionPool.remove(connectionPool.size() - 1);
} catch (SQLException throwables) {
System.out.println("资源关闭失败");
throwables.printStackTrace();
}
}
}
/**
* 创建连接池
*
* @param quantity 连接池的个数
*/
private static void creatConnectionPool(int quantity) {
Connection connection = null;
//创建quantity个连接
for (int i = 0; i < quantity; i++) {
try {
connection = DriverManager.getConnection(
properties.getProperty("url"),
properties.getProperty("user"),
properties.getProperty("password")
);
} catch (SQLException throwables) {
System.out.println("创建连接失败");
throwables.printStackTrace();
}
connectionPool.add(connection);
}
}
/**
* 获取该资源中的PreparedStatement
*
* @param jdbcResources 传入的jdbc资源,需要先获取资源了才能传入
* @return
*/
public static PreparedStatement getPreparedStatement(HashMap<String, Object> jdbcResources) {
if (jdbcResources != null) {
PreparedStatement preparedStatement = (PreparedStatement) jdbcResources.get("preparedStatement");
if (preparedStatement != null) {
return preparedStatement;
} else {
return null;
}
} else {
return null;
}
}
}
DBUtilEntity类
package util;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
public class DBUtilEntity<E> {
/**
* 获取一个实体类集合
* @param jdbcResources 需要传入的数据库资源
* @param e 需要存入的实体类
* @return ArrayList<E>集合
*/
public ArrayList<E> executeQuerEntity(HashMap<String,Object> jdbcResources,E e) {
PreparedStatement preparedStatement = (PreparedStatement) jdbcResources.get("preparedStatement");
ArrayList<E> es = new ArrayList<>();
try {
//执行sql语句
ResultSet resultSet = preparedStatement.executeQuery();
//获取表属性
ResultSetMetaData rsmd = resultSet.getMetaData();
//System.out.println(metaData);
Field[] declaredFields = e.getClass().getDeclaredFields();
int columnCount = rsmd.getColumnCount();
while (resultSet.next()) {
//new一个obj对象
E entityClass = (E)e.getClass().newInstance();
for (int i = 0; i < columnCount; i++) {
//获取数据的值
Object columnValue = resultSet.getObject(i + 1);
//私有属性强制访问
declaredFields[i].setAccessible(true);
//数据库查询出来的值放到obj实体类中
declaredFields[i].set(entityClass, columnValue);
}
es.add(entityClass);
}
return es;
} catch (SQLException | InstantiationException | IllegalAccessException throwables) {
throwables.printStackTrace();
} /*finally {
DBUtil.close(jdbcResources);
}*/
return null;
}
}