JavaWeb-Servlet-News(CURD)

本文介绍了使用Servlet优化JavaWeb中的新闻CURD操作,通过封装CUD方法减少重复代码,并利用JSTL改进JSP页面展示,提高了开发效率。

话说:

因为前面JavaWebJDBC一系列有超大的优化空间,这里先用Servlet改造一下。目的还是实现新闻News的CURD.
不过,这次变化点是
1)全程用Servlet来写,替代了原来JSP来负责页面跳转那部分(几个do.*的页面);
2)代码优化。笔者将通过前后代码对比,来体现一点点优化思想(设计思想)

今天整体介绍思路:


一、前后工程结构对比图
二、最终要实现的结果图
三、如何用Servlet实现的?
四、重点优化代码
五、整体总结


这次IDE也是有原来的MyEclipse、Eclipse替换为IntelliJ IDEA

一、前后工程结构对比图
现工程名称:JavaWeb_Servlet

这里写图片描述

原工程名称:SmileTestJDBC

这里写图片描述

二、最终要实现的结果图

这里写图片描述

三、如何用Servlet实现的?
所有Servlet中的业务逻辑代码都基于BaseDao和NewsDao。BaseDao里面的代码高度概括,NewsDao则根据业务需求精细化处理。

BaseDao代码
这里面实现了这样几个功能:
1)连接了MySQL数据库
2)把修改、查询、删除通通抽象化为了CUD()方法。这里面有很好的面向对象的思想。
3)对查做了个输出处理,验证连接MySQL是否成功。整体代码和前面JavaWebJDBC大同小异。

package com.hmc.jdbc.news.dao;
import com.hmc.jdbc.news.model.News;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

//哎呀,默认导全部的包,如果包到错了怎么办?
public class BaseDao {
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    //1、加载驱动,把加载类定义为静态语句块
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //说实话感觉卡顿的问题也没怎么解决。可能搜狗输入法还没有和捷克公司做好沟通吧。
    }
    //2、连接MySQL数据库 定义方法getConn()
    public Connection getConn() {
        String url = "jdbc:mysql://localhost:3306/news_db";
        String user = "root";
        String password = "119913";
        try {
            conn = DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.print("恭喜你,连接上了....");
        return conn;
    }

    //3、关闭资源
    public void closeJDBC(ResultSet rs, PreparedStatement ps,Connection conn) {
        try {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static  void main(String[] args) {
        //编写查  把数据库的News输出到控制台

            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            BaseDao bd = new BaseDao();
            //这里如果赋值,就会报NullPoint错误。
           conn = bd.getConn();
        try {
            //预编译SQL语句
            String sql = "select * from t_news";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            //遍历结果集
            while(rs.next()){
                //这里我们可以分明感受到Idea和Eclipse的差别
                int id = rs.getInt(1);
                String title = rs.getString("title");
                String author = rs.getString("author");
                System.out.println(id+"---"+title+"---"+author);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    /**
     * 我们会发现,我们发现,在NewsDao里面,尤其是CUD有大量重复代码,他们结构都差不多,不同的只是Sql语句和SQL带的参数。所以我们可以做如下封装。
     *另外,NewsShow中的查询和改(U)代码也几乎完全相同,无非一个是
     * select * from t_news  ;一个是select * from t_news where id = ? 是否也可以类似CUD那样封装起来?
     *
     */
    public int CUD(String sql,Object[] params){
        int result = 0;
        getConn();
        try {
            ps = conn.prepareStatement(sql);
            //问题关键是参数怎么赋值?在参数个数不确定?类型不确定的情况下?
            for (int i=0;i<params.length;i++) {
            ps.setObject((i+1),params[i]);
            }
           result = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
        return  result;
    }

    //下面们把查在优化一下
    public List<News> listShow(String sql, Object[] params) {
        List<News> list = new ArrayList<>();
        getConn();
        try {
            ps = conn.prepareStatement(sql);
            for(int i = 0;i<params.length;i++) {
                ps.setObject((i+1),params[i]);
            }
           rs =  ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String title = rs.getString(2);
                String author = rs.getString("author");
                News news = new News(id,title,author);
                list.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  list;
    }

}

NewsDao代码:
这里面开始用了最笨最土的方法写了大量重复代码,以便烘托简化后的代码之简洁。优化后的方法都以类似newsDel2()、newsUpdate2()这样命名,虽然不规范,适合自己理解。
分别实现了CURD功能,基础吧。据说,用框架来做,7min可以搞定的。这里之所以这么麻烦,是这个过程很有意义,可以很深刻体会到优化的重要性和代码的设计模式的升级。读者如果觉得小儿科,请自动忽略,就不耽搁您宝贵时间了。

package com.hmc.jdbc.news.dao;

import com.hmc.jdbc.news.model.News;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * User:Meice
 * 2017/10/1
 */
public class NewsDao extends  BaseDao{
    //这个类里面我们要写CURD啦。
    //1 查 R
    /**
     * 我们要把数据从刚才的控制台输出变为输出到页面,所以需要一个类似容器的东西存放我们的数据
     * 这里我们用List集合来存放新闻信息,作为运输工具。把我们的代码运输到JSP页面。
     */
    public List<News> list() {
        List<News> list = new ArrayList<>();
        getConn();
        String sql = "select * from t_news";
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt(1);
                String title = rs.getString("title");
                String author = rs.getString("author");
                //每次遍历一次,我们就把一行新闻作为一个对象,这就是JavaBean
                News news = new News(id,title,author);
                list.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //输出做验证,看以上代码是否正确
      //  System.out.println(list);
        closeJDBC(rs,ps,conn);

        return list;
    }

    public static void main(String[] args) {
        NewsDao nd = new NewsDao();
        //验证list()方法
       // nd.list();
    }

    //2 增 C
    //法1:封装发布新闻的方法
    public void newsAdd(News news) {
        getConn();
        String sql = "insert into t_news (title,author) values (?,?)";
        try {
            //预编译,步骤类似查 R
            ps = conn.prepareStatement(sql);
            //这里我们使用?来传递,专业名称忘了
            ps.setString(1,news.getTitle());
            ps.setString(2,news.getAuthor());
            //这里执行和查就不一样了,用的是Update方法
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }

    //法2:封装发布新闻的方法(前后对比明显吧!)
    public int newsAdd2(News news){
        String sql = "insert into t_news (title,author) values (?,?)";
        Object[] params = {news.getTitle(),news.getAuthor()};
       return CUD(sql,params);
    }





    //3 删 D 法一
    public void newsDel(int id) {
        getConn();
        String sql = "delete from t_news where id = ? ";
        System.out.println("进来了");
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }

    //删除法二
    public int newsDel2(int id) {
        String sql = "delete from t_news where id = ?";
        Object[] params = {id};
      return   CUD(sql,params);
    }

    //4 改 U
    //法1:第一步,点击修改链接,我们要能把对应的内容放到对应的位置。
    public News newsPut(int id) {
        getConn();
        News news = null;
        String sql = "select * from t_news where id = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            rs = ps.executeQuery();
            while (rs.next()) {
                id = rs.getInt(1);
                String title = rs.getString(2);
                String author = rs.getString(3);
                news = new News(id,title,author);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(rs,ps,conn);
        return  news;
    }
    //法2:封装根据对应ID把新闻放到页面的方法(两方法对比结果鲜明!)
    public  List<News> newsPut2(int id) {
        String sql = "select * from t_news where id = ?";
        Object[] params = {id};
       return listShow(sql,params);
    }



    //执行修改操作 法1:

    public  void newsUpdate(News news) {
        getConn();
        String sql = "update t_news set title = ? , author = ? where id = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1,news.getTitle());
            ps.setString(2,news.getAuthor());
            ps.setInt(3,news.getId());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }

    //执行修改操作 法2:(没有对比就没有伤害)
    public int newsUpdate2(News news) {
        String sql = "update t_news set title = ?, author = ? where id = ?";
        Object[] params = {news.getTitle(),news.getAuthor(),news.getId()};
        return   CUD(sql,params);
    }

}

重点是这里:Servlet的设计。
这里还是采用上古时代多个Servlet来实现各自响应和页面跳转的功能,目的也是为后期继续优化做铺垫。

NewsShowServlet
在页面显示新闻

package com.hmc.jdbc.news.servlet;

import com.hmc.jdbc.news.dao.NewsDao;
import com.hmc.jdbc.news.model.News;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * User:Meice
 * 2017/10/3
 */
public class NewsShowServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //1 处理编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        //2 处理业务逻辑,调用方法
        NewsDao nd = new NewsDao();
        List<News> list = nd.list();
        //3 存储到req中
        req.setAttribute("list",list);
        req.getRequestDispatcher("newsShow.jsp").forward(req,resp);
    }
}

NewsAddServlet
发布新闻Servlet

package com.hmc.jdbc.news.servlet;
import com.hmc.jdbc.news.dao.NewsDao;
import com.hmc.jdbc.news.model.News;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * User:Meice
 * 2017/10/3
 */
public class NewsAddServlet extends HttpServlet {
    /**
     * 重写Servlet的方法,service()方法什么请求都可以处理,不利于精细化操作。
     * 比如,我在修改新闻的时候,开始点击修改链接,这是get请求,修改过后提交表单又是post请求,业务逻辑处理不一样
     * 如果都写在service里面,怎么区别开呢?所以这里我们重写doGet()  doPost()方法。
     *
     */

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        /**
         *
         *如果同时重写doGet()、doPost()两个方法,页面是什么请求就调用什么方法。
         *但是这样麻烦,我们需要在两个方法里面写业务逻辑代码。
         *所以处理方式是让一个请求调用另外一个请求。(当然不可以双方互相调用),
         *这样,我就就只用在一个方法里面写业务逻辑代码,不论什么请求,都这个来处理。
         */
        doPost(req,resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这里是为了验证页面请求方式.
        //System.out.println("表单提交,post请求....");

        //1 处理编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        //2 接受参数
       String title = req.getParameter("title");
       String author = req.getParameter("author");

        News news = new News(title,author);

       //3 调用方法,即业务逻辑处理
        NewsDao nd = new NewsDao();
      int result =  nd.newsAdd2(news);

        //4 页面跳转
        /**
         * 1)为什么要用request转发来跳转?而不用重定向或者session?因为重定向无法携带参数;session可以
         * 但是session耗资源,因为request请求后就释放了,但是session还一直保存一个会话周期里,直到会话结束。
         * 2)为什么要判断?编程的严谨,如果都没有增加成功,还跳转什么?就要给出提示。比如发布空新闻之类的。
         *
         */
        if (result > 0) {
            req.getRequestDispatcher("newsShow.do").forward(req,resp);
        }else {
            req.getRequestDispatcher("newsAdd.jsp").forward(req,resp);
        }

    }


}

NewsUpdateServlet
NewsUpdateDoServlet

他们分别处理修改新闻的时候,在页面显示要修改的内容,和修改后返回到NewsShow.jsp页面。
NewsUpdateServlet

package com.hmc.jdbc.news.servlet;
import com.hmc.jdbc.news.dao.NewsDao;
import com.hmc.jdbc.news.model.News;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * User:Meice
 * 2017/10/3
 */
public class NewsUpdateServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //1 接收参数
        int id = 0;
        String strId = req.getParameter("id");
        if(strId != null && !"".equals(strId)) {
            id = Integer.valueOf(strId);
        }
        //2 业务逻辑处理(调用根据id查询单个新闻的方法newsPUt2())
        NewsDao nd = new NewsDao();
       List<News> list = nd.newsPut2(id);

        //3 页面传值
        //把这个集合传过去,类似newsShow
        req.setAttribute("list",list);

        //4 页面跳转
        req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);

    }
}

NewsUpdateDoServlet

package com.hmc.jdbc.news.servlet;
import com.hmc.jdbc.news.dao.NewsDao;
import com.hmc.jdbc.news.model.News;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * User:Meice
 * 2017/10/3
 */
public class NewsUpdateDoServlet extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //1 处理编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //2 接受参数
        int id = 0;
        String strId = req.getParameter("id");
        if(strId != null && !"".equals(strId)) {
            id = Integer.valueOf(strId);
        }
        String title = req.getParameter("title");
        String author = req.getParameter("author");

        // 3业务逻辑处理(提交修改后的新闻)
        News news = new News(id,title,author);
        NewsDao nd = new NewsDao();
        int result = nd.newsUpdate2(news);


        //3 页面跳转
        if (result>0) {
            req.getRequestDispatcher("newsShow.do").forward(req,resp);
        }else {
            req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);
        }

    }
}

NewsDelServlet

package com.hmc.jdbc.news.servlet;
import com.hmc.jdbc.news.dao.NewsDao;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * User:Meice
 * 2017/10/3
 */
public class NewsDelServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 接受参数
            int id = 0;
            String strId = req.getParameter("id");
            if(strId != null && !"".equals(strId)) {
                id = Integer.valueOf(strId);
            }
        //2 业务逻辑处理(按照id删除对应新闻)
        NewsDao nd = new NewsDao();
          int result =  nd.newsDel2(id);
        //3 页面跳转
        if(result >0 ) {
            req.getRequestDispatcher("newsShow.do").forward(req,resp);
        }else {
            req.getRequestDispatcher("newsShow.do").forward(req,resp);
        }


    }
}

奥,还有非常重要的web.xml配置,没有这个,所有的Servlet有什么意义呢?

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

   <!--news Add Servlet-->

    <servlet>
        <servlet-name>newsAdd</servlet-name>
        <servlet-class>com.hmc.jdbc.news.servlet.NewsAddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>newsAdd</servlet-name>
        <url-pattern>/newsAdd.do</url-pattern>
    </servlet-mapping>


    <!--news Show Servlet-->

    <servlet>
        <servlet-name>newsShow</servlet-name>
        <servlet-class>com.hmc.jdbc.news.servlet.NewsShowServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>newsShow</servlet-name>
        <url-pattern>/newsShow.do</url-pattern>
    </servlet-mapping>

    <!-- news Update Servlet-->
    <servlet>
        <servlet-name>newsUpdate</servlet-name>
        <servlet-class>com.hmc.jdbc.news.servlet.NewsUpdateServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>newsUpdate</servlet-name>
        <url-pattern>/newsUpdate.do</url-pattern>
    </servlet-mapping>

    <!--news Update Do Servlet-->
    <servlet>
        <servlet-name>newsUpdateDo</servlet-name>
        <servlet-class>com.hmc.jdbc.news.servlet.NewsUpdateDoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>newsUpdateDo</servlet-name>
        <url-pattern>/newsUpdateDo.do</url-pattern>
    </servlet-mapping>

    <!--news Del Servlet-->
    <servlet>
        <servlet-name>newsDel</servlet-name>
        <servlet-class>com.hmc.jdbc.news.servlet.NewsDelServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>newsDel</servlet-name>
        <url-pattern>/newsDel.do</url-pattern>
    </servlet-mapping>
</web-app>


这篇博客有点长。不过都是一个整体,为了保持思绪连贯性,哈哈。

四、重点优化代码

1、优化CUD代码。

因为他们都执行PreparedStatement.executeUpdate()方法,但是查就不一样,执行的是PreparedStatement.executeQuery()方法,返回结果也不一样,所以这三个可以封装起来。

封装后是这么写的:
 public int CUD(String sql,Object[] params){
        int result = 0;
        getConn();
        try {
            ps = conn.prepareStatement(sql);
            //问题关键是参数怎么赋值?在参数个数不确定?类型不确定的情况下?
            for (int i=0;i<params.length;i++) {
            ps.setObject((i+1),params[i]);
            }
           result = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
        return  result;
    }

调用是这么调用的:

 //法2:封装发布新闻的方法(前后对比明显吧!)
    public int newsAdd2(News news){
        String sql = "insert into t_news (title,author) values (?,?)";
        Object[] params = {news.getTitle(),news.getAuthor()};
       return CUD(sql,params);
    }


 //删除法二
    public int newsDel2(int id) {
        String sql = "delete from t_news where id = ?";
        Object[] params = {id};
      return   CUD(sql,params);
    }

 //执行修改操作 法2:(没有对比就没有伤害)
    public int newsUpdate2(News news) {
        String sql = "update t_news set title = ?, author = ? where id = ?";
        Object[] params = {news.getTitle(),news.getAuthor(),news.getId()};
        return   CUD(sql,params);
    }

未封装前是这么写的:

 //2 增 C
    //法1:封装发布新闻的方法
    public void newsAdd(News news) {
        getConn();
        String sql = "insert into t_news (title,author) values (?,?)";
        try {
            //预编译,步骤类似查 R
            ps = conn.prepareStatement(sql);
            //这里我们使用?来传递,专业名称忘了
            ps.setString(1,news.getTitle());
            ps.setString(2,news.getAuthor());
            //这里执行和查就不一样了,用的是Update方法
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }

 //3 删 D 法一
    public void newsDel(int id) {
        getConn();
        String sql = "delete from t_news where id = ? ";
        System.out.println("进来了");
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }

 //执行修改操作 法1:

    public  void newsUpdate(News news) {
        getConn();
        String sql = "update t_news set title = ? , author = ? where id = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setString(1,news.getTitle());
            ps.setString(2,news.getAuthor());
            ps.setInt(3,news.getId());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(null,ps,conn);
    }
你会发现,有大量重复代码,正所谓,没有对比就没有伤害!


2、优化是查(R),因为它特殊点。

优化后代码如下:

//下面们把查在优化一下

    /**
     * 这里我们不把SQL写死,我们会在两个地方用到,1是newsShow.jsp用到,
     * 另外一个是修改新闻的时候要用到,代码区别仅仅只是SQL语句不同。
     */
    public List<News> listShow(String sql, Object[] params) {
        List<News> list = new ArrayList<>();
        getConn();
        try {
            ps = conn.prepareStatement(sql);
            /**
             * 以下方法解决了参数个数和参数类型不同的问题
             * 高度抽象,不论你给多少参数,什么类型,都可以处理。
             */
            for(int i = 0;i<params.length;i++) {
                ps.setObject((i+1),params[i]);
            }
           rs =  ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String title = rs.getString(2);
                String author = rs.getString("author");
                News news = new News(id,title,author);
                list.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  list;
    }

未优化之前是这样的:

 //1 查 R
    /**
     * 我们要把数据从刚才的控制台输出变为输出到页面,所以需要一个类似容器的东西存放我们的数据
     * 这里我们用List集合来存放新闻信息,作为运输工具。把我们的代码运输到JSP页面。
     */
    public List<News> list() {
        List<News> list = new ArrayList<>();
        getConn();
        String sql = "select * from t_news";
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                int id = rs.getInt(1);
                String title = rs.getString("title");
                String author = rs.getString("author");
                //每次遍历一次,我们就把一行新闻作为一个对象,这就是JavaBean
                News news = new News(id,title,author);
                list.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //输出做验证,看以上代码是否正确
      //  System.out.println(list);
        closeJDBC(rs,ps,conn);

        return list;
    }


//修改新闻的时候,我们首先要根据新闻id在页面显示对应要修改的新闻,这个时候也要用到查,未优化之前,也要这么写:
//4 改 U
    //法1:第一步,点击修改链接,我们要能把对应的内容放到对应的位置。
    public News newsPut(int id) {
        getConn();
        News news = null;
        String sql = "select * from t_news where id = ?";
        try {
            ps = conn.prepareStatement(sql);
            ps.setInt(1,id);
            rs = ps.executeQuery();
            while (rs.next()) {
                id = rs.getInt(1);
                String title = rs.getString(2);
                String author = rs.getString(3);
                news = new News(id,title,author);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        closeJDBC(rs,ps,conn);
        return  news;
    }

很鲜明的对比!仅仅只是SQL语句不同,其他代码都类似。这个封装难度小于CUD.

3、页面优化前后对比

用JSTL后页面显示新闻是这样的:
<tbody>
           <%--${news}--%>
           <%--这里传过来就是那幅图的场景;现在的问题是我不知道怎么接收这个传递过来的值,直接用EL取出来的是
           个List<News>的集合。这边又没法遍历。??
           如果不用JSTL,我们用普通的for each,问题是怎么取出这个值。
           --%>

           <c:forEach var="news" items="${list}">
                <tr>
                    <td align="center">${news.id}</td>
                    <td align="center">${news.title}</td>
                    <td align="center">${news.author}</td>
                    <td align="center">
                        <a href="newsUpdate.do?id=${news.id}">修改</a>
                        <a href="newsDel.do?id=${news.id}" onclick="return confirm('真的忍心删我?')">删除</a>
                    </td>
                </tr>
           </c:forEach>

        </tbody>

这里用JSTL替代了之前的JSP和页面代码之间的嵌套,那样比较混乱;另外取值也直接用了EL表达式。避免了<%=%>的取值方式。
未优化之前是这样的:

 <tbody>
            <%
                for(News news: list){
            %>
            <tr>
                <td align="center"><%=news.getId() %></td>
                <td><%=news.getTitle() %></td>
                <td><%=news.getAuthor()%></td>
                <td align="center">
                    <a href="newsUpdate.jsp?id=<%=news.getId()%>">修改</a>
                    <a href="doDel.jsp?id=<%=news.getId()%>" onclick="return confirm('真的忍心删我?')">删除</a>
                </td>
            </tr>
        <%
            }
        %>
        </tbody>

五、整体总结


技术层面:
1)在前一篇博客JavaWeb_Servlet基础上,运用Servlet到业务中;
2)面向对象思想的灵活运用(封装、继承);
3)JSTL、El表达式的运用。
非技术层面:
1)空杯心态,温故才能知新;
2)能不能把已知的东西有条理总结出来,是一种写作能力的锻炼;
3)实践必定会有很多坑,不要嫌麻烦。


午安!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值