java web之图书查询总结

简单的查询项目的总结

我感觉这个项目用的基础知识和关键的知识多,就是用到了一些做项目的基本流程,让我知道了做项目的一些基本方法,里面也有一些点很值得我思考,就是向总结一下我作项目的一些错误。
第一,做一个简单的javaweb项目肯定定需要创建一个数据库:
这里我的数据库是给我了一个表格,然后自己创建就好了,这里使用的的是mysql数据库;
在写这里的时候有一些基本的数据库语言忘了
1.删除一个表格
不是delete 而是 drop table 加 表名

DROP TABLE IF EXISTS book_info;

2.直接在创建表格的时候创建一个外键:
首先要要创建一个与外面主键对应的一个字符 然后用 foreign key 自己表中的数据 references 外表加(表名)

book_type INT NOT NULL,
FOREIGN KEY(book_type) REFERENCES book_type(id)

这里的id 是book_type里面的主键
3.添加约束
我这里想添加一个不是主键但是是一个不能为空并且唯一的约束
关键字就是 unicode

user_code VARCHAR(50) UNICODE NOT NULL,

4.修改表
update 表名 set 数据 = 什么 然后就是 where 数据 = 什么

UPDATE  `users` SET `last_logintime` = NOW() WHERE `user_code` = '001';

还有就是 这里想说一些 一般使用select 语句 查询表中的所有数据的时候为什么不用 select * from 表名
而 用的是 select 表中的表头 加的表中的数据
这里使用 * 有3 个缺点:
1.会使我们查询的数据不明确
2.会让我们的多使用多余的io磁盘
3.会将我们一些隐私的数据展示给用户。
所以一般推荐使用的就是select 加 表头;
数据库建完之后,就得开始创建一个项目的结构,这里我使用的最简单的创建一个java web 项目的创建过程 ,使用mvc 进行项目的创建 ,但是这里我也遇到了一个问题,就是,我使用的是idea 2020.2.4 所以他没有那个java web 创建的直接的的选项,所以就是得县创建一个 一个普通的java 项目 然后给他添加一个web 的过程, 这里遇到的问题就是这样创建的web项目他没有tomcat的lib包,所以当下面你写servlet的时候,你就倒不到javax底下的 HttpServle 这个包,你就需要手动添加一下lib包:
在这里插入图片描述
在这里导入包就可以了
第一步先创建好一个javaweb项目 然后手动一定要创建多一点的文件夹
在这里插入图片描述
类似于像这样 然后先写 entity 把数据库端对应得的数据的列名写上去,然后就可以写dao层
一般都是先写接口:

package com.rongyu.dao;

import com.rongyu.entity.Users;

import java.util.Date;

/**
 * 用户登录接口
 */
public interface IUserDao {
    Users login(String username);
    int findUser(String username);
    boolean add(Users users);
    boolean update(String username,Date time);
}

然后dao层写完写service层:
直接倒入就好,最后servlet 层:
这里使用反射解决了每次需要创建多个servlet的麻烦:

package com.rongyu.utils;
/**
 * 使用反射封装对象
 */

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.lang.reflect.Method;

public class BaseServlet extends HttpServlet {
    //使用反射将方法自动调用service方法
    @Override
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        String action = req.getParameter("action");
        if (action!=null){
            try {
                Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
                method.invoke(this,req,res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

实现的思路就是:因为要实现一个servlet就需要继承 javax 底下的httpservlet包 他的底层就是 init方法 service方法 和 destory方法,基本上请求的servlet都是进入的是service方法,这里首先通过前段传进来的action的关键字获得你需要请求的方法的名字,然后通过反射拿到当前对象的这个名字所对应的这个方法,因为当时继承这个方法的时候,当前对象就是你目前写的这个servlet 这里我感觉最关键的就是这个this的关键字,因为这个this 才能使当前对象不断变化,才会使得当前对象不断变化,达到一个插件的目的。
其中servlet写基本的逻辑,就是先通过这个人输入的用户名返回一个User对象,然后通过User对象对应的密码对比和这个输入的密码是否一致,一致就为成功,这里用的是ajax+jquery,所以还得使用一个jar包,用来转换json数据。
在这里插入图片描述
使用的是这个 fastJson

int parse = (int)JSON.parse("0");

下来就是分页组件的编写:
一般使用mysql 数据库编写数据的进行分页的话,一般使用的就是limit ?,?第一个数据是开始的数据,第二个数据是你每页显示的条数,但是第一个数据是从0开始的;一般分页需要从5个数据下手,一般是:
1.总记录数
2.每页记录数
3.总页数
4.当前页数
5.返回的LIst集合

package com.rongyu.utils;

import java.util.List;

/**
 * 数据库分页查询组件
 */
public class PageBeanSQL<T> {
    private int curPage; //当前页号
    private int pageCount; //页面总数
    private int pageNumber = 3; //每页记录数
    private int pageTotals; //总记录数
    private List<T> books; // 返回的List集合
    private int startIndex;//数据库端返回的最开始的数字
    private int start;
    private int end;

    public PageBeanSQL(String curPa, int pageTotals) {
        this.setPageTotals(pageTotals);
        this.setCurPage(curPa);
        this.setStartIndex((this.getCurPage() - 1)*pageNumber);
        this.start = 1;
        this.end = 5;
        if (pageCount<=5){
            this.end = this.pageCount;
        }else {
            this.start = pageCount - 2;
            this.end = pageCount + 2;
            if (start<0){
                this.start = 1;
                this.end = 5;
            }
            if (end>this.pageCount){
                this.end = pageCount;
                this.start = end - 5;
            }
        }
    }

    public int getCurPage() {
        return curPage;
    }

    public void setCurPage(int curPa) {
        if (curPa<=0){
            curPage = 1;
        }else if (curPa>pageCount){
            curPage = pageCount;
        }else {
            curPage = curPa;
        }
    }

    public void setCurPage(String curPa){
        try{
            curPage = Integer.parseInt(curPa);
        }catch (Exception e){
            curPage = 1;
        }

        if (curPage<=0||pageCount==0){
            curPage = 1;
        }else if (curPage>this.pageCount&&curPage!=0){
            curPage = pageCount;
        }
    }

    public int getPageCount() {
        return pageCount;
    }

    public void setPageCount(int pageCount) {
        this.pageCount = pageCount;
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public int getPageTotals() {
        return pageTotals;
    }

    public void setPageTotals(int pageTotals) {
        this.pageTotals = pageTotals;
        if (this.pageTotals % pageNumber == 0){
            this.pageCount = this.pageTotals / pageNumber;
        }else {
            this.pageCount = (this.pageTotals / pageNumber) + 1;
        }
    }

    public List<T> getBooks() {
        return books;
    }

    public void setBooks(List<T> books) {
        this.books = books;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }
}

总结:
这里最关键的感觉就是理解这个的顺序结构,通过数据库端的查询,我们可以知道总记录数,通过总记录数,我们可以知道总的页数,通过当前页和每页记录数,我们可以计算出开始的数字。但是这个需要对当前页进行类型转换和进行判断,就需要用到总页数,所以需要在计算当前页数之前就算出来总的页数,还有就是要计算出来当前页和开始之间的关系,是一个当前页数-1*每页记录数的关系。
分页组件写好之后就是对于dao层的编写:
这里我们需要查询数据库端的一些数据,所以需要对数据库进行分页查询,每次用到都需要有一些技巧,就是把所有添加的数据都添加进集合在后面添加where 1=1 然后判断前段是否给后台传来数据,传来的话需要用and + sql语句进行实现,并且需要给集合里面添加查询到的数据,然后总记录数也需要进行改变,我们需要的是从from之后的数据库的sql语句,然后就可以实现分页;

package com.rongyu.dao.impl;

import com.rongyu.dao.IBookDao;
import com.rongyu.entity.Book;
import com.rongyu.entity.SearchBook;
import com.rongyu.utils.PageBeanSQL;
import com.rongyu.utils.StringEmpty;
import com.wdzl.dao.BaseDao;

import java.util.ArrayList;
import java.util.List;

public class BDaoImpl extends BaseDao implements IBookDao {
    @Override
    public PageBeanSQL<Book> query(String curPage,SearchBook book) {
        String book_name = book.getBook_name();
        String book_type = book.getBook_type();
        String is_borrow = book.getIs_borrow();
        String sql = "";
        List<Book> list = null;
        List<Object> params = new ArrayList<>();
        sql += "SELECT `book_id`,`book_code`,`book_name`,(SELECT `type_name` FROM `book_type` " +
                "WHERE `id` = `book_info`.`book_type`) `book_type`," +
                "`book_author`,`publish_press`,`publish_date`,`is_borrow`," +
                "`createdBy`,`creation_time`,`last_updatetime` from `book_info` where 1=1";
        if (!StringEmpty.isEmpty(book_name)){
            sql += " and book_name like ? ";
            params.add("%"+book_name+"%");
        }
        if (!StringEmpty.isEmpty(book_type)){
            sql += " and book_type = ? ";
            params.add(book_type);
        }
        if (!StringEmpty.isEmpty(is_borrow)){
            sql += " and is_borrow = ? ";
            params.add(is_borrow);
        }
        int count = count(sql,params.toArray());
        PageBeanSQL<Book> books = new PageBeanSQL<>(curPage,count);
        sql += " limit ?,? ";
        params.add(books.getStartIndex());
        params.add(books.getPageNumber());
        list = super.query(sql,Book.class,params.toArray());
        books.setBooks(list);
        return books;
    }

    @Override
    public int count(String sql,Object[] params) {
        String sql1 = " SELECT COUNT(*) " + sql.substring(sql.indexOf("from"));
        return super.queryCount(sql1,params).intValue();
    }
}

这里判断是否有数据需要注意不能加空格所以要使用strip方法

package com.rongyu.utils;

/**
 * 判断字符串是否为空
 */
public class StringEmpty {
    public static boolean isEmpty(String str){
        if (str == null || str.strip().equals("")){
            return true;
        }
        return false;
    }
}

然后编写前端:
前端选用的是jquery进行编写,所以需要引入js工具,这里还遇到了一个问题,就是js不发布的问题,然后只能在这个文件夹下面最后有编写了一个随意的文件idea才进行了发布,这里我认为前端比较难的地方就在于这个动态添加和动态选择这个问题,我动态添加了a标签但是动态选择之后想获取a标签里面的值怎么都获取不到最后还是使用了this这个关键字才解决了这个问题。

 for (var i = data.start; i <= data.end ; i++) {
        stri.append('<a name="page" href="#" yy="'+i+'">'+i+'</a>');
   }
$("#pages").on("click","[name='page']",function (){
  	let pa = $(this).text();
 	page = pa;
  	query();
});

最后是写的过滤器:
也不知道为啥每次这个过滤器会把js给禁止掉

package com.rongyu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter("/*")
public class AdminFilter implements Filter {
    //过滤非法用户
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpSession session = req.getSession(false);
        String url = req.getRequestURL().toString();
        //System.out.println(url);
        if (url != null && url.toUpperCase().contains("LOGIN")){
            filterChain.doFilter(request,response);
            return;
        }
        if (url != null && url.toUpperCase().contains("REGISTER")){
            filterChain.doFilter(request,response);
            return;
        }
        if (url != null && url.toUpperCase().contains("USER")){
            filterChain.doFilter(request,response);
            return;
        }
        if (session == null || session.getAttribute("login") == null){
            response.setContentType("text/html;charset = utf-8");
            response.getWriter().write("<h1>非法访问!<a href='login.jsp'>点击此处去登录!</a></h1>");
            return;
        }
        filterChain.doFilter(request,response);
    }
}

还写过滤字符编码的过滤器:

package com.rongyu.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class CherSetFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        filterChain.doFilter(request,response);
    }
}

到现在这个项目就编写完成了
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
项目总结:
我感觉这个项目用的知识和技术都是最基本的技术,还没用到验证码,监听器和自动登录cookie,但是我感觉写项目的最重要的就是一定要注意规范,尽量多写接口,使用同样的方法,命名一定要见名知意,注释不需要多,但是需要在重要的部分加上注释,和判断逻辑一定要清晰不能过于冗杂,这个项目写了大概2天时间,感觉写完一个项目很有成就感但是就是还是要注重基础知识的学习,毕竟一个大的项目就是凭借着基础造成的,写这个项目也遇到了很多问题,我感觉遇到问题不可怕,就是首先一定要知道是哪里出现了问题,定位的越准确越好了,然后就是要好好学习那方面的知识,好好学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值