package project02_Order_management.util;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
* 封裝對數據庫進行--連接/增/刪/改/查/
*
* @author MartinDong
*
* @param <T>
* 要操作的數據對象
*/
public class BaseDAOUtil<T> {
/**
* 聲明數據庫連接對象
*/
private static Connection connection;
/**
* 聲明預處理對象
*/
private static PreparedStatement preparedStatement;
/**
* 聲明sql語句返回結果集對象
*/
private static ResultSet resultSet;
/**
* 加載默認的configuration.properties資源文件
*
* @return
*/
public static Properties getProperties() {
return getProperties(null);
}
/**
* 加載資源文件
*
* @param propertyName
* 傳入要加載的資源文件名稱;
* @return properties 返回一個屬性配置對象
*/
public static Properties getProperties(String propertyName) {
/**
* 設置配置資源文件的默認文件名
*/
if (propertyName == null) {
propertyName = "configuration.properties";
}
/**
* 聲明屬性文件類,讀取配置使用
*/
Properties properties = new Properties();
try {
/**
* currentThread()是Thread的一個靜態方法,返回的是當前的進程對象
*/
properties.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream(propertyName));
} catch (IOException e) {
System.out.println(propertyName + "文件加載出現錯誤!");
e.printStackTrace();
}
return properties;
}
/**
* 獲取默認的數據庫連接對象
*
* @return
*/
public static Connection getConnection() {
return getConnection(getProperties());
}
/**
* 獲取數據庫連接對象
*
* @param properties
* 傳入已經配置好的屬性配置對象;
* @return <b>connection</b> 數據庫連接對象
*/
public static Connection getConnection(Properties properties) {
if (connection == null) {
/**
* 加載數據庫驅動文件
*/
try {
Class.forName(properties.getProperty("jdbc.driver"));
/**
* 創建數據庫連接對象
*/
try {
connection = DriverManager.getConnection(
properties.getProperty("jdbc.url"),
properties.getProperty("jdbc.user"),
properties.getProperty("jdbc.password"));
System.out.println("數據庫連接成功>>>>>>>>>>>");
} catch (SQLException e) {
System.out.println("數據庫連接參數錯誤!");
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
System.out.println("缺少數據庫驅動文件:"
+ properties.getProperty("jdbc.driver") + "!");
e.printStackTrace();
}
}
return connection;
}
/**
* 釋放資源的方法;<br>
*
* @param releaseSet
* @param preparedStatement
* @param connection
*/
public static void release(ResultSet releaseSet,
PreparedStatement preparedStatement, Connection connection) {
if (releaseSet != null) {
try {
releaseSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// /////////////////////////////////CRUD基礎業務/////////////////////////////
/**
* 採用默認的連接,並且數據庫表名與實體類名一致[不區分大小寫]
*
* @param entity
* @throws SQLException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void save(T entity) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SQLException {
save(entity, getConnection());
}
/**
* 採用數據庫表名與實體類名一致[不區分大小寫]外部傳入數據庫連接;
*
* @param entity
* @param connection
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public void save(T entity, Connection connection)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
save(entity, connection, null);
}
/**
* 將實體存入數據庫
*
* @param entity
* 要操作的數據對象
* @param connection
* 傳數據庫連接
* @param tableName
* 要操作的表的名稱,如果傳入null,則對傳入的對象名稱一致的表進行操作
* @throws SQLException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void save(T entity, Connection connection, String tableName)
throws SQLException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
/**
* 獲取操作實體的類型
*/
Class<? extends Object> clazz = entity.getClass();
/**
* 獲取傳入實體的所有公開的方法;
*/
Method[] methods = clazz.getDeclaredMethods();
/**
* 獲取傳入實體中的所有公開的的屬性
*/
Field[] fields = clazz.getDeclaredFields();
/**
* 如果沒有輸入指定的數據表名酒採用類名進行操作
*/
if (tableName == null) {
tableName = clazz.getSimpleName().toLowerCase();
}
/**
* 拼接類中的屬性字段,即數據表中的字段名
*/
String fieldsName = "";
/**
* 佔位符的設置
*/
String placeholder = "";
for (int i = 0; i < fields.length; i++) {
fieldsName = fieldsName + fields[i].getName() + ",";
placeholder = placeholder + "?" + ",";
}
/**
* 去除多餘的標點
*/
fieldsName = fieldsName.substring(0, fieldsName.length() - 1);
placeholder = placeholder.substring(0, placeholder.length() - 1);
/**
* 拼接sql語句
*/
String sql = "insert into " + tableName + "(" + fieldsName + ")"
+ " values " + "(" + placeholder + ")";
System.out.println(sql);
/**
* 預編譯sql語句
*/
PreparedStatement pst = connection.prepareStatement(sql);
/**
* 給預編譯語句賦值
*/
int index = 1;
for (int j = 0; j < fields.length; j++) {
String str = "get" + fields[j].getName();
/**
* 循環方法名比對
*/
for (int k = 0; k < methods.length; k++) {
/**
* 如果當前的屬性拼出的get方法名,與方法明集合中的有一樣的執行
*/
if (str.equalsIgnoreCase(methods[k].getName())) {
/**
* 接收指定的方法執行後的數據
*/
Object propertyObj = methods[k].invoke(entity);
/**
* 爲指定的佔位符進行賦值
*/
pst.setObject(index++, propertyObj);
}
}
}
/**
* 執行已經加載的sql語句
*/
pst.executeUpdate();
}
/**
* 使用默認的數據庫連接進行刪除,傳入的對象
*
* @param entity
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public void delete(T entity) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SQLException {
deleteById(entity, getConnection());
}
/**
* 使用傳入的數據庫連接,刪除指定的對象.
*
* @param entity
* @param connection
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public void deleteById(T entity, Connection connection)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
delete(entity, connection, null);
}
/**
*
* @param entity
* 傳入操作的對象實體
* @param connection
* 傳入數據庫連接對象
* @param id
* 要刪除數據的id
* @param tableName
* 要操作的表的名稱,如果傳入null,則對傳入的對象名稱一致的表進行操作
* @throws SQLException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*
*/
public void delete(T entity, Connection connection, String tableName)
throws SQLException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Class<? extends Object> clazz = entity.getClass();
Method[] methods = clazz.getDeclaredMethods();
Field[] fields = clazz.getDeclaredFields();
if (tableName == null) {
tableName = clazz.getSimpleName().toLowerCase();
}
String sql = "delete from " + tableName + " where id=?";
System.out.println(sql);
PreparedStatement pst = connection.prepareStatement(sql);
Object id = null;
for (int i = 0; i < fields.length; i++) {
for (int j = 0; j < methods.length; j++) {
if ("getId".equalsIgnoreCase(methods[j].getName())) {
id = methods[j].invoke(entity);
}
}
}
pst.setObject(1, id);
pst.executeUpdate();
}
/**
* 使用默認的數據庫連接修改傳入的對象.
*
* @param entity
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public void update(T entity) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SQLException {
update(entity, getConnection());
}
/**
* 使用傳入的數據庫連接進行數據庫修改;
*
* @param entity
* @param connection
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public void update(T entity, Connection connection)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
update(entity, connection, null);
}
/**
*
* @param entity
* 傳入操作的對象實體
* @param connection
* 傳入數據庫連接對象
* @param tableName
* 要操作的表的名稱,如果傳入null,則對傳入的對象名稱一致的表進行操作
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws SQLException
*/
public void update(T entity, Connection connection, String tableName)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
Class<? extends Object> clazz = entity.getClass();
Method[] methods = clazz.getDeclaredMethods();
Field[] fields = clazz.getDeclaredFields();
if (tableName == null) {
tableName = clazz.getSimpleName().toLowerCase();
}
String fieldsName = "";
// 創建id字段的默認數據
Object id = 1;
// 循環遍歷以獲取的公開的屬性
for (int i = 0; i < fields.length; i++) {
// 嵌套循環,比較公開屬性名經過拼接後和公開的方法名進行匹配
for (int j = 0; j < methods.length; j++) {
// 使用屬性名+get進行拼接
String getFieldName = "get" + fields[i].getName();
if (getFieldName.equalsIgnoreCase(methods[j].getName())) {
// 拼接更行sql語句中的set字段,並用佔位符
fieldsName = fieldsName + fields[i].getName() + "=?,";
}
// 獲取id字段的值
if ("getId".equalsIgnoreCase(methods[j].getName())) {
id = methods[j].invoke(entity);
}
}
}
fieldsName = fieldsName.substring(0, fieldsName.length() - 1);
String sql = "update " + tableName + " set " + fieldsName
+ " where id=?";
System.out.println(sql);
PreparedStatement pst = connection.prepareStatement(sql);
int index = 1;
for (int j = 0; j < fields.length; j++) {
String str = "get" + fields[j].getName();
// 循環方法名比對
for (int k = 0; k < methods.length; k++) {
// 如果當前的屬性拼出的get方法名,與方法明集合中的有一樣的執行
if (str.equalsIgnoreCase(methods[k].getName())) {
// 接收指定的方法執行後的數據
Object propertyObj = methods[k].invoke(entity);
// 爲指定的佔位符進行賦值
pst.setObject(index++, propertyObj);
}
}
}
pst.setObject(index++, id);
pst.execute();
}
/**
* 使用默認的數據庫連接查詢指定的id數據
*
* @param entity
* @param id
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public T findById(T entity, Integer id) throws InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
return findById(entity, null, id);
}
/**
*
* 使用傳入的數據庫連接以及傳入的id查詢數據;
*
* @param entity
* @param connection
* @param id
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public T findById(T entity, Connection connection, Integer id)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SQLException {
return findById(entity, connection, id, null);
}
/**
*
* 根據id查詢數據
*
* @param entity
* 查詢的實體對象
* @param connection
* 數據庫連接對象
* @param id
* 查詢的id
* @param tableName
* 操作的數據庫表名
* @return 返回一個查詢結果對象
* @throws SQLException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public T findById(T entity, Connection connection, Integer id,
String tableName) throws SQLException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Class<? extends Object> clazz = entity.getClass();
Method[] methods = clazz.getDeclaredMethods();
Field[] fields = clazz.getDeclaredFields();
// 聲明查詢的結果對象
T resultObject = null;
if (tableName == null) {
tableName = clazz.getSimpleName().toLowerCase();
}
String sql = "select * from " + tableName + " where id=?";
System.out.println(sql);
PreparedStatement pst = connection.prepareStatement(sql);
pst.setObject(1, id);
ResultSet resultSet = pst.executeQuery();
if (resultSet.next()) {
resultObject = (T) clazz.newInstance();
for (int i = 0; i < fields.length; i++) {
String fieldName = fields[i].getName();
Object fieldObject = resultSet.getObject(i + 1);
if (fieldObject == null) {
fieldObject = "null";// 防止數據爲null時引發空指針異常
}
for (int j = 0; j < methods.length; j++) {
if (("set" + fieldName).equalsIgnoreCase(methods[j]
.getName())) {
methods[j].invoke(resultObject,
resultSet.getObject(fieldName));
}
}
}
}
return resultObject;
}
/**
* 使用默認的數據庫連接進行數據查詢
*
* @param entity
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public List<T> findAll(T entity) throws InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, SQLException {
return findAll(entity, getConnection());
}
/**
* 使用傳入的數據庫連接進行數據查詢
*
* @param entity
* @param connection
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws SQLException
*/
public List<T> findAll(T entity, Connection connection)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SQLException {
return findAll(entity, connection, null);
}
/**
* 查詢數據表所有的數據
*
* @param entity
* 查詢的實體對象
* @param connection
* 數據庫連接對象
* @param tableName
* 操作的數據庫表名
* @return
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public List<T> findAll(T entity, Connection connection, String tableName)
throws SQLException, InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Class<? extends Object> clazz = entity.getClass();
Method[] methods = clazz.getDeclaredMethods();
Field[] fields = clazz.getDeclaredFields();
// 聲明查詢的結果對象
List<T> resultObjects = new ArrayList<T>();
if (tableName == null) {
tableName = clazz.getSimpleName().toLowerCase();
}
String sql = "select * from " + tableName;
System.out.println(sql);
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet resultSet = pst.executeQuery();
while (resultSet.next()) {
T resultObject = (T) clazz.newInstance();
for (int i = 0; i < fields.length; i++) {
String fieldName = fields[i].getName();
Object fieldObject = resultSet.getObject(i + 1);
if (fieldObject == null) {
fieldObject = "null";
}
for (int j = 0; j < methods.length; j++) {
if (("set" + fieldName).equalsIgnoreCase(methods[j]
.getName())) {
methods[j].invoke(resultObject,
resultSet.getObject(fieldName));
}
}
}
resultObjects.add(resultObject);
}
return resultObjects;
}
public List<T> query(T entity, Connection connection, String tableName,
String sql) {
return null;
}
/**
* 一個需要用戶手動輸入sql和參數語句的:增/刪/改/的操作
*
* @param sql
* @param args
* @return
*/
public static int upDate(String sql, Object[] args) {
try {
preparedStatement = getConnection().prepareStatement(sql);
for (int i = 1; i <= args.length; i++) {
preparedStatement.setObject(i, args[i - 1]);
}
return preparedStatement.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
/**
* 傳入自定義的sql語句和參數進行查詢;
*
* @param sql
* sql語句
* @param args
* 傳入的參數條件
* @return 返回一個set集合
*/
public static ResultSet getObject(String sql, Object[] args) {
System.out.println(sql);
try {
preparedStatement = JDBCUtil.getConnection().prepareStatement(sql);
if (args != null) {
for (int i = 1; i <= args.length; i++) {
preparedStatement.setObject(i, args[i - 1]);
}
}
resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultSet;
}
}
configuration.properties配置文件
jdbc.url=jdbc\:mysql\://localhost\:3306/order_manager
jdbc.user=root
jdbc.password=admin
jdbc.driver=com.mysql.jdbc.Driver