• 关于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;
        }
    
    }

    希望看到本贴的大佬们,能留言提出一个最完美的解决对策!!!感谢!!!!

    希望看到本贴的大佬们,能留言提出一个最完美的解决对策!!!感谢!!!!

    希望看到本贴的大佬们,能留言提出一个最完美的解决对策!!!感谢!!!!

  • 相关阅读:
    BZOJ_1196_[HNOI2006]公路修建问题_kruskal+二分答案
    BZOJ_1179_[Apio2009]Atm_tarjan+spfa
    BZOJ_1026_[SCOI2009]windy数_数位DP
    BZOJ_1003_[ZJOI2006]物流运输_最短路+dp
    吴裕雄--天生自然HADOOP操作实验学习笔记:tf-idf算法
    吴裕雄--天生自然HADOOP操作实验学习笔记:hive安装
    吴裕雄--天生自然HADOOP操作实验学习笔记:hdfs分布式文件系统安装
    吴裕雄--天生自然HADOOP操作实验学习笔记:单节点伪分布式安装
    吴裕雄--天生自然HADOOP操作实验学习笔记:安装zookeeper集群
    吴裕雄--天生自然HADOOP操作实验学习笔记:hadoop框架认识以及基本操作
  • 原文地址:https://www.cnblogs.com/wanguncle/p/10903299.html
Copyright © 2020-2023  润新知