JDBC簡單封裝框架

2020-08-08 20:36:14

在使用JDBC連線技術時我們反覆 反復建立連線,或者每次進行DML操作以及查詢時需要寫大量的程式碼,很是繁瑣,下面 下麪我們用一些常見的技術把這些操作封裝起來,實現一個簡單的框架,這個框架具有以下功能:

1.獲取數據庫連線(通過組態檔)
2.將傳入裝入屬性資訊的map集合轉化爲一個物件
3.將查詢到資訊轉化爲一個物件(返回一個物件)
4.將查詢多個資訊轉化爲多個物件(返回一個裝有物件的動態陣列集合)
5.將查詢到的資訊裝入map集合然後裝進list集合併返回查詢結果
6.執行DML操作
7.支援事務的DML操作
8.關閉連線、結果集、StateMent物件

用到技術:集合框架,jdbc連線技術,反射,泛型介面、方法	

我們定義一個類作爲我們的框架:
首先我們建立一個組態檔(設定數據庫資訊)
在这里插入图片描述
注意:先要匯入數據庫連線驅動,eclipsec通過構建路徑設定驅動jar包,Idea通過Alt+shift+ctrl+s進入Project Structure找到Dependencies新增驅動包應用即可,還有一種方式這裏不再贅述,讀者可以參閱網上的教學,下面 下麪我們看一下程式碼實現。

程式碼:

package com.softeem.jdbc;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;

/**
 * 實現一個簡單jdbc操作的簡單的框架
 *
 * @Author GQ 2020/8/7 14:59
 */
public class DBUtilsMyself {
    /**
     * 驅動類名
     */
    private static final String DRIVER_CLASS;
    /**
     * 數據庫密碼
     */
    private static final String PASSWORD;
    /**
     * 數據庫使用者名稱
     */
    private static final String USER;
    /**
     * 數據庫路徑
     */
    private static final String URL;
    /**
     * map集合轉化的物件
     */
    private static Object obj;

    static {
        //建立屬性類讀取設定
        Properties p = new Properties();
        try {
            //獲取流(放入組態檔路徑即可)
            InputStream is = new FileInputStream("C:\\Users\\14252\\Desktop\\組態檔\\數據庫組態檔.txt");
            //載入流
            p.load(is);
            System.out.println(is);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        DRIVER_CLASS = p.getProperty("driver");
        URL = p.getProperty("url");
        // 數據庫伺服器登錄使用者名稱
        USER = p.getProperty("user");
        // 數據庫伺服器登錄密碼
        PASSWORD = p.getProperty("password");
    }

    /***
     * 獲取連線
     */
    public static Connection getCon() {
        Connection conn = null;
        try {
            //載入驅動
            Class.forName(DRIVER_CLASS);
            //獲取連線
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 關閉資源
     *
     * @param conn
     * @param rs
     * @param ps
     */
    public static void close(Connection conn, ResultSet rs, Statement ps) {
        try {
            if (conn != null) {
                conn.close();
            }
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /***
     * 將map集合轉化爲物件
     * @param <T>
     * @return
     */
    private static <T> T mapToBean(Class<T> t, Map<String, Object> map) {
        try {
            //獲取範例
            obj = t.newInstance();
            //將map集閤中的鍵值對結構屬性轉化爲物件屬性,這裏一個k代表一個屬性,v代表值
            map.forEach((k, v) -> {
                //通過鍵獲取屬性
                try {
                    Field filed = t.getDeclaredField(k);
                    //設定屬性可見
                    filed.setAccessible(true);
                    //給屬性賦值
                    filed.set(obj, v);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return (T) obj;
    }

    /**
     * 通過sql語句以及相關參數查詢結果以鍵值對結構裝入到map集合
     * 並將map裝入到List集合返回
     *
     * @param sql
     * @param params
     * @return
     */
    public static List<Map<String, Object>> queryList(String sql, Object... params) {
        //建立集合接收值
        List<Map<String, Object>> list = new ArrayList<>();
        //獲取連線
        Connection conn = getCon();
        ResultSet rs = null;
        PreparedStatement ps = null;
        try {
            //得到執行sql語句的PreparedStateMent物件
            ps = conn.prepareStatement(sql);
            //通過回圈給預編譯的語句給值
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            //通過查詢獲得結果集
            rs = ps.executeQuery();
            //獲取查詢結果元數據
            ResultSetMetaData metaData = rs.getMetaData();
            //獲取元數據查詢結果列數
            int columnCount = metaData.getColumnCount();
            while (rs.next()) {
                //建立map集合放入查詢到的結果
                Map<String, Object> map = new HashMap<>();
                //取出每一列值加入到map集閤中
                for (int i = 0; i < columnCount; i++) {
                    //獲取標籤值
                    String label = metaData.getColumnName(i + 1);
                    //獲取查詢到的值
                    Object obj = rs.getObject(label);
                    //獲取列名
                    String key = metaData.getColumnName(i + 1);
                    //將查詢到元素放入到集合
                    if (obj != null) {
                        map.put(key, obj);
                    }
                }
                //將map放入到List集合
                list.add(map);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //關閉資源
            close(conn, rs, ps);
        }

        return list;
    }

    /**
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    public static <T> T queryOne(Class<T> t, String sql, Object... params) {
        //查詢一個,掉用queryList得到結果
        List<Map<String, Object>> list = queryList(sql, params);
        //獲取查詢到的一個結果
        Map<String, Object> map = list.get(0);
        //將map集合轉化爲物件並且返回
        return mapToBean(t, map);
    }

    /**
     * 執行DML語句
     * @param sql
     * @param params
     * @return
     */
    public static boolean executeUpdate(String sql, Object... params) {
        //獲取連線
        Connection conn = getCon();
        return executeUpdate(conn,sql,params);
    }
    /**
     * 支援事務的DML操作方法
     * 因爲事務需要保證同一連線
     * @param conn
     * @param sql
     * @param params
     * @return
     */
public static boolean executeUpdate(Connection conn,String sql,Object...params){
    PreparedStatement ps = null;
    try {
        //得到執行sql語句的PreparedStateMent物件
        ps = conn.prepareStatement(sql);
        //通過回圈給預編譯的語句給值
        for (int i = 0; i < 1; i++) {
           ps.setObject(i + 1, params[i]);
        }
        //執行,如果結果大於0執行成功返回true
        return ps.executeUpdate() > 0;
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        //關閉資源
        close(conn,null,ps);
    }
    return false;
}
public static <T> List<T> queryBeanList(Class<T> t,String sql,Object...params){
    //建立集合儲存物件
    List<T>list=new ArrayList<>();
    //接收查詢到的結果
    List<Map<String, Object>> maps = queryList(sql, params);
    maps.forEach(map->{
        //將查詢到的集合轉化爲對應物件
        T tt=mapToBean(t,map);
         //將查詢到結果放入到list集閤中
        list.add(tt);
    });

    return list;
}

}

上面程式可以滿足大部分查詢,更新操作,簡化了程式碼,無需每次存取數據庫都重寫一樣的程式碼,通過封裝操作,在進行dao層操作時非常方便。上面程式碼由於作者寫的比較快,也只做了一些簡單的測試,如果有那裏不對的地方請聯繫作者以及時更改!