JavaWeb03thymeleaf快速入门

thymeleaf是干什么用的?

帮助我们进行视图渲染的

通过代码实现页面展现数据库里的所有数据

我们需要用到之前JDBC学的知识完成服务器与数据库的交互

 

 

 IndexServlet

import java.sql.Connection;
import java.util.List;
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        FruitDAOImpl fruitDAO = new FruitDAOImpl();
        Connection connection = null;
        try {
            connection = JDBCutil.getConnection();
            List<Fruit> fruitList = fruitDAO.getAll(connection);
            System.out.println(fruitList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        JDBCutil.closeResource(connection,null);


    }
}

测试连接现在有个问题。数据现在能获取到,我的doGet会自己执行两次

现在还没有解决

前端页面:
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
    <tr >
        <th>名称</th>
        <th>单价</th>
        <th>数量</th>
        <th>操作</th>
    </tr>
    <tr>
        <th>苹果</th>
        <th>5</th>
        <th>20</th>
        <th>删除</th>
    </tr>
</table>

</body>
</html>

配置Thymeleaf

 配置网站:代码重工 (gitee.io)

1.导入jar包

 还需要添加到库,构建模块操作

2.新建一个servlet类

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {

        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);

        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);

    }

    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

写这串代码有什么用?

 里面有两个方法,init初始化,processTemplate需要三个参数(模板名,请求,响应)

processTemplate可以帮我们完成资源的转发和数据的渲染

3.在web.xml添加配置(也就是配置上下文参数)

 

这个前缀和后缀会在init里初始化的时候使用

 4.用我们的servlet继承ViewBaseServlet

 servlet继承ViewBaseServlet和之前的效果是一样的,因为ViewBaseServlet继承了HttpServlet

进行跳转:

 

观察是否跳转:

 

 成功跳转了,而且域名最后是index而不是index.html

把我们动态查询到的数据整合到前端页面上

先把获取的数据存到session作用域里

try {
            //获取数据库连接
            connection = JDBCutil.getConnection();
            //获取表中的全部记录
            List<Fruit> fruitList = fruitDAO.getAll(connection);
            //输出表中所有的数据
            System.out.println(fruitList);
            HttpServletRequest request = (HttpServletRequest) req;
            HttpSession session = request.getSession();
            session.setAttribute("fruitList",fruitList);
            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭数据库连接
        JDBCutil.closeResource(connection,null);


    }

这里我们需要用到thymeleaf语句写在前端页面上

1.判断我们获取的存在session的数据是否为空,就要用if, else

如果库存为空就合并四行,显示库存为空

如果session数据不为空,就用each循环的把值赋给fruit 

再在下面的每一次循环中,给每个td的文本赋相对应的值

测试成功

保存作用域(4种)

1.page(页面级别,现在几乎不用)

2.request(一次请求响应范围,客户端重定向就失效,服务器内部转发不失效)

此时demo02获取不到数据

 

此时demo02可以i获取数据

3.session(一次会话范围)

 此时下面的客户端获取不到数据

4.application(只要tomcat不关,就不失效)

 此时每个客户端都可以获取数据

路径问题

相对路径与绝对路径,用绝对路径会更好一点

对于现在这个项目的优化

对于一个项目来说,这是这样子简单的展示肯定不行,我们想在index.html页面的名称上加超链接,用户点击超链接可以展示水果详情,并且可以对信息进行修改

1.在index.html页面的名称上加超链接

 但是这个时候,老师的页面没有加超链接,因为这个时候,td里的th:text把整个a标签都当成了文本,所以我们直接在a标签里写thymeleaf就可以了

 页面效果:

 但是现在域名是直接在后面是edit.do,如果我们的edit页面很深,每次这样子写就很麻烦,所以我们用thymeleaf的绝对路径形式

2.写edit.do展示修改页面

第一个问题,跳转到edit.do后,用的是什么请求方法?

现在的记法是,只要不是表单里特别备注了methdo,就默认是get

第二个问题,我怎么知道跳转过来,我要查询的是哪个水果呢?

 我们需要在超链接后面加?id=fruit.id才可以,关键是怎么加,现在,我们的/deit.do?fid=应该是字符串,后面的fruit.id应该是thymeleaf表达式才合理

(1)字符串拼接

 

 (2)thymeleaf表达式键值对形式(一般使用这种)

 

3.edit获取index传来的id,并且把查询到的数据渲染到edit.html页面上

首先判断传来的字符串是不是空,可以写一个工具方法方便以后用

package com.LALALA.util;

public class StringUtil {
    public static boolean isEmpty(String str ) {
    return str==null || "".equals(str);
    }

    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }
}

判断类型并且转换类型为int

public class EditServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        if(StringUtil.isNotEmpty(idStr)){
            int id = Integer.parseInt(idStr);
        }
    }
}

在DAO里写根据ID查询方法

接口:

实现类:

 

 在edit中实现查询:

public class EditServlet extends ViewBaseServlet {
    private FruitDAO fruitDAO = new FruitDAOImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        if(StringUtil.isNotEmpty(idStr)){
            int id = Integer.parseInt(idStr);

            Connection connection = null;
            try {
                connection = JDBCutil.getConnection();
                Fruit fruit = fruitDAO.getFruitByID(connection,id);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                JDBCutil.closeResource(connection,null,null);
            }
        }
    }
}

把获取的数据保存在请求作用域里,并且用thymeleaf把fruit和edit.html进行渲染

4.写edit.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
    <tr >
        <th>名称:</th>
        <td><inpu type="text" name="name"></inpu></td>
    </tr>
    <tr >
        <th>单价:</th>
        <td><inpu type="text" name="price"></inpu></td>
    </tr>
    <tr >
         <th>库存:</th>
         <td><inpu type="text" name="count"></inpu></td>
    </tr>
    <tr >
         <th>备注:</th>
         <td><inpu type="text" name="remark"></inpu></td>
    </tr>
    <tr >
         <th colspan="2">
             <input type="submit" value="修改"/>
         </th>
    </tr>
</table>

</body>
</html>

5.把数据放在edit.html页面上展示

之前用的是展示session作用域,怎么展示request作用域?

获取成功

 

 但是现在我们每次都要写fruit.会非常麻烦,我们使用th:object来解决,这样子以后在写了th:object下面的子标签想用对象直接*{name},*{count}就可以了

成功

 

 6.解决用户点击修改后,修改数据库里的内容的功能

首先,要把edit.html里要提交的数据用表单post形式提交,在table外面加<from></from>

 actioin是要提交的路径,method是提交的方法,数据可以用req.getParameter获得,但是现在我们id没有传到update那边去,需要设置一个隐藏域用来传id(用户不看id),所以我们把th:object等级设置的高一点在form上

写update.do页面,获取参数

@WebServlet("/update.do")
public class UpdateServlet extends ViewBaseServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        Integer id = Integer.parseInt(idStr);
        String name = req.getParameter("name");
        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(idStr);
        String countStr = req.getParameter("count");
        Integer count = Integer.parseInt(idStr);
        String remark = req.getParameter("remark");
    }
}

写修改数据库代码

接口:

实现类:

 

在update中实现修改:

@WebServlet("/update.do")
public class UpdateServlet extends ViewBaseServlet {
    private FruitDAO fruitDAO = new FruitDAOImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String idStr = req.getParameter("id");
        Integer id = Integer.parseInt(idStr);
        String name = req.getParameter("name");
        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(idStr);
        String countStr = req.getParameter("count");
        Integer count = Integer.parseInt(idStr);
        String remark = req.getParameter("remark");


        Connection connection = null;
        try {
            connection = JDBCutil.getConnection();
            Fruit fruit = new Fruit(id,name,price,count,remark);
            fruitDAO.update(connection,fruit);
            System.out.println("update success");
            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutil.closeResource(connection,null);
        }
    }
}

测试:

 

 出现错误:无论如何修改,价格和库存都是和id一样的数值

 获取参数代码写错了

修改:

        req.setCharacterEncoding("UTF-8");
        String idStr = req.getParameter("id");
        Integer id = Integer.parseInt(idStr);

        String name = req.getParameter("name");

        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(priceStr);

        String countStr = req.getParameter("count");
        Integer count = Integer.parseInt(countStr);

        String remark = req.getParameter("remark");

再次测试:

 查看西瓜:

 修改西瓜:

 修改后:

 此时我们发现没有变化,但是数据表里

 为什么会这样子?

再我们第一次查询时,数据保存在了session作用域里

 之后我们对数据表进行修改,最后进行了资源跳转

//资源跳转

//渲染页面跳转
super.processTemplate("index",req,resp);
//服务器转发跳转
req.getRequestDispatcher("index.html").forward(req,resp);

但是上面这两种目前都不行,现在只需要让客户端重定向到index就会再查询一次数据表,这样子就相当于完成了一次更新

//客户端重定向(此时index,是去IndexServlet,完成重新查询后最后用thymeleaf渲染数据和页面)
resp.sendRedirect("index");

最终测试:

查看apple详情:

 

 修改apple:

 修改后:

 

 完成!!!!!!

删除和添加功能

1.删除功能

现在我们的页面上的删除操作只是摆着看的,实现该功能,鼠标点击删除

首先一定要用到JS

但是传统的字符串拼接形式组合thymeleaf表达式,太麻烦,我们现在可以这样子 

加完双竖线,会自动识别 thymeleaf表达式

 此时我们点击删除,右边的fruit.id会自动识别要删除的id

下面我们写JS文件,让用户一旦点击就删除该数据,命名为DeleteServlet

 

 此时用户一旦点击删除,就会在当前页面域名的后面加上del.do?id=****跳转到DeleteServlet上面去执行删除操作

写DeleteServlet

写路径的注解

因为此时不是表单提交,默认为get方式请求,并且获取id,判断当前id是否为空,为空就不执行任何操作,不为空操作数据库删除

@WebServlet("/del.do")
public class DeleteServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        if(StringUtil.isNotEmpty(idStr)){
            int id = Integer.parseInt(idStr);
            
        }
    }
}

接口:

实现类:

 

 对数据库操作,并且删除后客户端重定向到index:

@WebServlet("/del.do")
public class DeleteServlet extends ViewBaseServlet {
    private FruitDAO fruitDAO = new FruitDAOImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        if(StringUtil.isNotEmpty(idStr)){
            int id = Integer.parseInt(idStr);
            Connection connection = null;
            try {
                connection = JDBCutil.getConnection();
                fruitDAO.delFruitByID(connection,id);
                resp.sendRedirect("index");
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                JDBCutil.closeResource(connection,null);
            }
        }
    }
}

测试:

问题1:写前端页面时,我用的是td,无法点击删除,也就无法触发js文件到deleteServlet那边,所以我这边用了原来的链接形式来处理

问题2: 点击删除后虽然进入了deleteServlet,但是没法删除,一开始的sql语句表名写错了

真正测试:

 点击删除:

 数据表:

 成功!!!!!!!!

2.添加功能

添加一个首页链接命名为添加一条数据

写出我们的添加页面,点击添加后带着数据到addServlet操作数据库(应该和edit.html类似,我们直接拿来修改)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/add.do}" method="post" >
    <table >
        <tr >
            <th>名称:</th>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr >
            <th>单价:</th>
            <td><input type="text" name="price" /></td>
        </tr>
        <tr >
            <th>库存:</th>
            <td><input type="text" name="count" /></td>
        </tr>
        <tr >
            <th>备注:</th>
            <td><input type="text" name="remark" /></td>
        </tr>
        <tr >
            <th colspan="2">
                <input type="submit" value="添加"/>
            </th>
        </tr>
    </table>
</form>


</body>
</html>

 测试:

 

 页面正常

AddServlet操作数据库

获取前端的数值

接口:

 

实现类:

 

  对数据库操作,并且删除后客户端重定向到index:

@WebServlet("/add.do")
public class AddServlet extends ViewBaseServlet {
    FruitDAO fruitDAO = new FruitDAOImpl();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //String idStr = req.getParameter("id");
        //Integer id = Integer.parseInt(idStr);

        String name = req.getParameter("name");

        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(priceStr);

        String countStr = req.getParameter("count");
        Integer count = Integer.parseInt(countStr);

        String remark = req.getParameter("remark");

        Fruit fruit = new Fruit(0,name,price,count,remark);

        Connection connection = null;
        try {
            connection = JDBCutil.getConnection();
            fruitDAO.insert(connection,fruit);
            resp.sendRedirect("index");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutil.closeResource(connection,null);
        }



    }
}

问题:点击添加后,页面不自动跳转到index上

(后面会说解决方法) 

修改:

测试:

 

 点击添加:

 点击提交:

 

 !!!!!!成功!!!!!!!

实现分页功能

现在我们的数据一次展示的太多了,能不能一次只显示5条数据?

 每页显示五条,肯定要分页,我们可以从前端获取当前想要查询的页数,再从数据库里查询返回

修改接口:

 修改实现类:

sql语句该如何写,已经知道

是查询第0开始显示前5条数据

 是查询第0开始显示前5条数据

现在我们已知查多少页,应该怎么写?

 

  对数据库操作,并且查询好后用thymeleaf渲染数据与页面(测试默认pageNo为1):

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //req.setCharacterEncoding("UTF-8");
        FruitDAOImpl fruitDAO = new FruitDAOImpl();
        Connection connection = null;
        int pageNo = 1;
        try {
            //获取数据库连接
            connection = JDBCutil.getConnection();
            //获取表中的全部记录
            List<Fruit> fruitList = fruitDAO.getByPage(connection,pageNo);
            //输出表中所有的数据
            //System.out.println(fruitList);
            HttpServletRequest request = (HttpServletRequest) req;
            HttpSession session = request.getSession();
            session.setAttribute("fruitList",fruitList);
            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭数据库连接
        JDBCutil.closeResource(connection,null);
    }
}

测试成功:

下面需要解决的问题就是,如何从前端页面获取用户想要查询哪一页,或者用户点击上一页下一页操作的时候当前页面是第几页

我们先在首页底部加上首页上一页下一页尾页的按钮

 

首先,我们第一次启动时,默认服务器查询前5条数据,我们可以把pageNo设置为1,先把这个pageNo放到session作用域里,如果前端需要更改,就从session里改变pageNo的值,跳转到后端后,后端先再次把pageNo设置为1,再获取session里pageNo的值,判断session的pageNo是否为空,如果为空,就是第一次启动服务器,默认展示前五条,如果不为空,就把session的pageNo强制转换为int类型再赋给我们一开始设置的pageNo,后面再次执行查询

后端:

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int pageNo = 1;
        String pageNoStr = req.getParameter("pageNo");
        if(StringUtil.isNotEmpty(pageNoStr)){
            pageNo = Integer.parseInt(pageNoStr);
        }
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession();
        session.setAttribute("pageNo",pageNo);

        
        
        FruitDAOImpl fruitDAO = new FruitDAOImpl();
        Connection connection = null;
        try {
            //获取数据库连接
            connection = JDBCutil.getConnection();
            //获取表中的全部记录
            List<Fruit> fruitList = fruitDAO.getByPage(connection,pageNo);
            //输出表中所有的数据
            //System.out.println(fruitList);
            session.setAttribute("fruitList",fruitList);
            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭数据库连接
        JDBCutil.closeResource(connection,null);
    }
}

前端(设置一个点击事件函数,当用户点击对应的操作,改变session里pageNo的值,并且跳转到indexServlet):

 JS文件(跳转):

 测试:

 点击下一页:

 暂时没有问题,但是我们点尾页没法确定到底是第几条数据到第几条数据,如果我们知道当前表中一共有几条数据就好办了

接口:

 实现类;

 在indexServlet里算出尾页是第几页,启动服务器的时候算好,存到session作用域里,如果前端用户想直接查看尾页,直接让session的pageNo等于我们算出来的尾页数值,再传给后端进行查找就可以了

后端:

因为我们需要int类型的返回值,所以进行修改

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int pageNo = 1;
        String pageNoStr = req.getParameter("pageNo");
        if(StringUtil.isNotEmpty(pageNoStr)){
            pageNo = Integer.parseInt(pageNoStr);
        }
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession();
        session.setAttribute("pageNo",pageNo);



        FruitDAOImpl fruitDAO = new FruitDAOImpl();
        Connection connection = null;
        try {
            //获取数据库连接
            connection = JDBCutil.getConnection();
            //获取表中的全部记录
            List<Fruit> fruitList = fruitDAO.getByPage(connection,pageNo);
            //输出表中所有的数据
            //System.out.println(fruitList);
            session.setAttribute("fruitList",fruitList);


            //记录条数
            int fruitCount = fruitDAO.getCount(connection);
            System.out.println("count::"+fruitCount);
            //页数
            int pageCount = (fruitCount+5-1)/5;
            session.setAttribute("pageCount",pageCount);

            
            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭数据库连接
        JDBCutil.closeResource(connection,null);
    }
}

前端:

测试:

 

 都可以正常操作

最后一个问题,如果我在第一页点击上一页,或者在首页点击首页,尾页点击下一页,尾页点击尾页肯定不合适,需要进行disabled禁用

 如果当前就在首页,首页和上一页就禁用

如果当前总页数和当前页数相同(在最后一页),尾页和下一页禁用

 

 

 !!!!!!!!分页完成!!!!!!!!!!!

根据关键字搜素

我们需要把我们查询的关键字用from表单提交到服务器查询

 

 我们现在想在文本框中输入关键字,查找名称或者备注含有该关键字的数据,并且要求分页,我们from表单提交后,会跳转到searchServlet进行处理,但是,我们这边的功能实际上和indexServlet很像,我们可不可以在indexServlet上就实现这个功能?

如果我们想在indexServlet实现查询,首先,表单提交的是post方法,如何让这个post方法进行get执行代码呢?

 这样子就可以解决,但是记得在get里设置post的编码

现在的问题:

1.需要判断这次需要渲染的数据是分页展示查询关键字还是分页展示查询表中所有数据

可以在前端的from表单里设置一个隐藏域并且给定一个初始值,如果传到后端,初始值没有变,就是通过搜素进入indexServlet,如果初始值变了或者为空,则是正常分页查询或者是关键字查询用户点击了下一页

总之还是要看数据的情况:

pageNo:一定是不可能为空的,它完成了无论哪种情况,一定要有查询的是哪几条数据的功能

oper:可能不为空,用户点击查询按钮

            可能为空,用户点击查询按钮后,点击了下一页操作

keyword:可能为空,这只是一次简单的分页展示操作

                 可能不为空,用户需要分页查询,所以在第一次点击查询之后,一定要设置到session                      里,方便点击下一页的时候完成对关键字的操作

前端:

后端:

@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码
        req.setCharacterEncoding("UTF-8");
        //获取session
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession();

        //此时数据库默认为第一次启动,默认查询第一页
        int pageNo = 1;


        //此时数据库默认为第一次启动,关键字默认为空
        String keyword = null;
        //只有每一次点击提交查询按钮才会给oper设置默认值
        //获取oper并且判断oper是否为默认值并且不能为空,如果满足,那么这次一定就是查询关键字操作
        String oper = req.getParameter("oper");

        if(StringUtil.isNotEmpty(oper) && "search".equalsIgnoreCase(oper)){
            //点击表单进行第一次查询
            //此时设置pageNo为1是为了查询后默认从id低到高进行分页展示
            pageNo = 1;
            //获取当前session里关键字的值
            keyword = req.getParameter("keyword");
            //如果关键字为空说明此时用户只是点击了搜素,没加任何关键字,就手动把关键字设置为空字符串
            if (StringUtil.isEmpty(keyword)){
                keyword = "";
            }
            //如果关键字不是空,就把它记录到session,让下面的DAO执行查询操作,或者让查询后点击下一页时,也能获取到当前的关键字
            session.setAttribute("keyword",keyword);
        }else {
            //正常查询(也有可能是用户输入了搜素后,点击了下一页上一页操作)
            //获取当前session里pageNo的值
            String pageNoStr = req.getParameter("pageNo");
            //此处是为了计算当前无论哪种情况,都要进行分页查询,判断当前在第几页
            //如果前端点击了上一页,就会改变或者新建session里的pageNo的值,判断用户是不是点击了上一页
            if(StringUtil.isNotEmpty(pageNoStr)){
                //把pageNo转化为int,方便下面DAO使用
                pageNo = Integer.parseInt(pageNoStr);
            }
            //保存当前session里pageNo,方便下一次计算要展示第几条数据
            session.setAttribute("pageNo",pageNo);

            //获取当前session里关键字的值,看看是不是进行关键字分页查询
            Object keywordObj = session.getAttribute("keyword");

            if (keywordObj!=null){
                //如果关键字不为空,说明此时需要进行关键字分页查询,赋值给keyword,方便下面DAO进行使用
                keyword = (String) keywordObj;
            }else {
                //关键字为空,这是正常的普通查询,但是用户点了下一页,把keyword设置为空,不影响下面DAO的sql语句就可以了
                keyword = "";
            }
        }




        FruitDAOImpl fruitDAO = new FruitDAOImpl();
        Connection connection = null;
        try {
            //获取数据库连接
            connection = JDBCutil.getConnection();
            //获取表中的全部记录
            List<Fruit> fruitList = fruitDAO.getByPage(connection,pageNo);
            //输出表中所有的数据
            //System.out.println(fruitList);
            session.setAttribute("fruitList",fruitList);


            //记录条数
            int fruitCount = fruitDAO.getCount(connection);
            //System.out.println("count::"+fruitCount);
            //一共有几页
            int pageCount = (fruitCount+5-1)/5;
            session.setAttribute("pageCount",pageCount);


            super.processTemplate("index",req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭数据库连接
        JDBCutil.closeResource(connection,null);
    }
}

2.如何对于数据库进行操作呢?

此时我们需要用的语句为

如果前两个占位符为空(keyword),那么这就是一次简单的分页展示,如果不为空,就是分页查询,所以我们要传入keyword和pageNo两个参数 

接口:

实现类:

 

 

数据处理:

 

测试:

错误1:basedao里getValue填充字符串一开始有问题,对应不上

修改:

错误2:数据库模糊查询语法有问题(一开始进行模糊查询结果总是为空)

修改:

 

错误3:查询跳转时,找不到页面

修改:

最后我们想让我们在搜素时,搜索框里一直显示我们的关键字,应该怎么做?

如果此时session里有关键字,我们默认让文本框里的值为关键字就可以了

最终测试:

 

 

 !!!!!!!!人生中第一个小项目成功啦!!!!!!!!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值