關於Java怎樣封裝executeQuery()的問題


Java封裝BaseDao時經常困擾的一個問題,就是封裝executeQuery()方法的問題

 1. 如果封裝該方法返回一個ResultSet對象的話,會出現資源無法釋放的尷尬情況

 2. 如果提前關閉Connection對象和PreparedStatement對象的話返回出去的ResultSet對象將會無法使用

 3. 不釋放資源的話雖然可以使用,但是總覺得不舒服

為了解決這個問題,試了好久終於發現一個還算不錯的方法,雖然不能完美的解決這個問題,最起碼是可以任意使用的

廢話不多說,貼代碼:

首先,我們編寫BaseDao類時,聲明一個額外的抽象方法(所以BaseDao也要被定義為抽象類),該方法如下:

  /**
     * 獲取所有信息的方法返回一個List泛型集合
     * 由實現該方法的類來確定返回的集合的類型
* 補充,在聲明該方法時,需要將BaseDao聲明一個<T>泛型 *
@param rs * @return */ public abstract List<T> getAllInfo(ResultSet rs);

聲明這個方法之后,我們就可以開始封裝executeQuery()方法了,具體封裝如下:

這里我們仍然返回的是一個泛型集合List<T>

  /**
     * 查詢對象,返回一個泛型集合
     */
    public List<T> executeQuery(String sql,Object...params){
        //連接對象
        Connection conn = getConnection();
        //執行SQL對象
        PreparedStatement pstmt = null;
        //結果集對象
        ResultSet rs = null;
        //處理SQL語句
        try {
            pstmt = conn.prepareStatement(sql);
            //判斷傳入的參數是否為空
            if(params != null){
                //循環賦值
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i+1,params[i]);
                }
            }
            //創建結果集對象
            rs = pstmt.executeQuery();
            //調用抽象方法來返回一個泛型集合
            List<T> list = getAllInfo(rs);
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        } finally {
            //關閉連接
            closeAll(conn,pstmt,rs);
        }
    }

接着我們就可以創建BaseDao的子類了,我們都知道子類繼承父類時需要實現父類所有的抽象方法。

所以,我們在創建了子類后,利用子類來實現 List<T> getAllInfo(ResultSet rs); 方法,具體實現如下:

PS:同時有必要給大家看一下 NewsDao 接口中的東西

NewsDao 接口:

 

 1 package dao;
 2 
 3 import entity.News;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * @user: Mr.Wang
 9  * @date: 2019/5/21
10  * @time: 20:02
11  */
12 public interface NewsDao {
13 
14     List<News> getAllnews();
15 
16 }

 

NewsImpl 實現類:

 

 1 package dao.impl;
 2 import dao.BaseDao;
 3 import dao.NewsDao;
 4 import entity.News;
 5 import java.sql.ResultSet;
 6 import java.util.ArrayList;
 7 import java.util.List;
 8 
 9 /**
10  * @user: Mr.Wang
11  * @date: 2019/5/21
12  * @time: 20:04
13  */
14 public class NewsImpl extends BaseDao implements NewsDao {
15 
16     /**
17      * 查詢獲得所有用戶的方法
18      * @return
19      */
20     @Override
21     public List<News> getAllnews() {
22         //SQL語句
23         String sql = "SELECT * FROM news";
24         //調用查詢方法返回List集合
25         return executeQuery(sql,null);
26     }
27 
28     /**
29      * 實現父類的方法
30      * @param rs 結果集
31      * @return
32      */
33     @Override
34     public List<News> getAllInfo(ResultSet rs) {
35         List<News> list = null;
36         try{
37             //判斷rs是否為空
38             if(null != rs){
39                 //創建List
40                 list = new ArrayList<News>();
41                 //遍歷結果集
42                 while(rs.next()){
43                     //創建News對象
44                     News news = new News();
45                     //取出結果集中的值
46                     news.setNid(rs.getInt("nid"));
47                     news.setNtitle(rs.getString("ntitle"));
48                     news.setNauthor(rs.getString("nauthor"));
49                     news.setNcontent(rs.getString("ncontent"));
50                     //將該對象添加進集合
51                     list.add(news);
52                 }
53             }
54             //返回list
55             return list;
56         } catch (Exception e){
57             e.printStackTrace();
58             return null;
59         }
60     }
61 }

釋:大概意思就是,實現時,確定了泛型的返回類型為<News>,這時我們就可以創建一個List<News>集合

  正常的利用參數 Resultset rs 去遍歷結果集,將結果集存入 List<News> 中

  因為我們在調用封裝的executeQuery()方法時調用過了getAllInfo(ResultSet rs)方法

  所以當我們重寫后,將會調用我們重寫后得方法,這樣就可以順利取出值。

缺點問題:大概就是這個流程,但是有個問題就是,有時我們繼承BaseDao的類可能不需要用到查詢出所有結果的要求,可能只是根據要求找出一個對象

這時我們繼承BaseDao又得必須實現getAllInfo(ResultSet rs)方法顯得有些雞肋。。。這個問題本小白暫時沒找出好的解決方法

我是用了一種比較投機取巧的方法去完成的,比如登錄驗證,只用返回單個結果,我是這樣完成的,代碼如下:

PS:BaseDao的代碼和實現類的代碼和上述基本一致,所以就不貼了,貼出來業務邏輯層的代碼是怎么處理的!

因為同樣返回了集合,所以在寫SQL語句時將條件寫在了WHERE條件中,這樣就可以確保找到我們想要的數據

然后我們接收到返回的集合,通過判斷集合的長度來確定我們是否找到符合條件的數據,詳細代碼如下:

 

package service;
import dao.impl.NewsUsersImpl;
import entity.NewsUsers;
import java.util.List;

/**
 * @user: Mr.Wang
 * @date: 2019/5/21
 * @time: 16:44
 * 業務邏輯類,負責進行邏輯判斷
 */
public class NewsUserService {

    // new一個NewsUserImpl對象,調用其登錄驗證的方法
    private NewsUsersImpl newsUsers = new NewsUsersImpl();

    /**
     * 登錄驗證
     * @param name 登錄名
     * @param pwd   登錄密碼
     * @return 返回一個boolean類型
     */
    public boolean loginVerify(String name,String pwd){
        boolean flag = true;
        //調用驗證方法返回一個集合
        List<NewsUsers> list = newsUsers.loginVerify(name,pwd);
        //判斷該集合的長度是否大於0
        if(list.size() <= 0){
            flag = false;
        }
        return flag;
    }

}

希望看到本貼的大佬們,能留言提出一個最完美的解決對策!!!感謝!!!!

希望看到本貼的大佬們,能留言提出一個最完美的解決對策!!!感謝!!!!

希望看到本貼的大佬們,能留言提出一個最完美的解決對策!!!感謝!!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM