javaweb工程之生鲜管理系统简易版详细过程

注:这是视频学习笔记

尝试做一个运行示意图:

简单的生鲜管理系统

一、考察的知识点

(1)servlet知识

(2)cookie和session的使用

(3)jsp的三大指令,四大作用域,以及jstl标签

(4)过滤器filter的简单使用

(5)管理类的使用

(6)请求转发与重定向

(7)数据库的CRUD操作

(8)用户注册与登录,账号保存

完整的目录文件(左是src目录,右是web目录)

二、详细过程

1.准备工作:

(1)安装JDK-8u71版

(2)下载安装apache-tomcat-8.5.60

(3)下载安装idea,本次实验使用的是IntelliJ IDEA 2018.1.6

(4)下载mysql-connector-java-8.0.14.jar(数据库连接jar包)

(5)下载安装jakarta-taglibs-standard-1.1.2(标签库)

(6)下载安装MySQL8.0版

(7)下载安装数据库的操作工具:Navicat

所有所需文件

 

2.创建项目和配置项目

(1)创建项目和配置项目

aa.已经打开之前的项目的情况下:file ------> new ------>  project

bb.未打开项目的情况下直接点击:create new Project

进入到如下界面:

注意:如果在安装intellij idea 时已经配置了jdk,就不用再配置(要配置也可以,我这里的图片就是重新又配置了一遍,所以有(1)这样的显示),Tomcat也一样,java EE的版本应该与idea以及jdk和Tomcat相匹配

cc.项目以及model的名称和保存位置设置

dd.点击finish进入到项目界面(左图),然后创建对应的项目结构,同时把素材文件复制到对应的文件目录之下,(将c3p0-config.xml)配置文件复制粘贴到src目录下(与com.study同级目录)

ee.配置项目以及配置文件的修改

说明:图1,项目结构图;图2,标签库配置;图3,数据库连接配置;图4-13,Tomcat server服务器配置过程(首次配置过程)

 

 

(2)创建数据库

aa.打开Navicat,连接mysql8.0

bb.新建数据库:fresh10,新建两张表:user和category

cc.给category添加数据

 

 

 

3.后端代码编写

(1)bean部分代码编写:

          <1> User类:私有数据域:private int id/String name/String password/String email,创建其getter和setter方法即可

          <2> User类:私有数据域:private int id/String name/String password/String email,创建其getter和setter方法即可

          <3> User类:私有数据域:private int id/String name/String password/String email,创建其getter和setter方法即可

(2)管理类代码编写

package com.study.web;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 管理代码工具类
 */
@WebServlet(name = "BaseServlet")
public class BaseServlet extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

        try {
            //统一设置请求页面的编码格式,防止乱码
            req.setCharacterEncoding("utf-8");
            
            //1.获取前端页面名为method的值
            String method = req.getParameter("method");
            //2.获取字节码
            Class clazz=this.getClass();
            //3.获取对象字节码的方法
            Method method1 = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
            //4.执行方法
            method1.invoke(this,req,res);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

 

(3)用户注册与登录代码编写(执行顺序依次为:UserServlet---> UserService---> UserDao)

          <1> UserServlet类

package com.study.web;

import com.study.bean.User;
import com.study.service.UserService;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Map;

/**
 * 用户登陆注册类
 * /user表示表单提交到后端的Servlet类
 * 该类继承管理类BaseServlet,通过父类调用其方法
 */
@WebServlet(name = "UserServlet",urlPatterns = "/user")
public class UserServlet extends BaseServlet {
    public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        try {
            //获取前端相关参数map集合
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user=new User();
            //封装user
            BeanUtils.populate(user,parameterMap);

            //调用userService的查找用户登陆方法,并返回结果user
            UserService userService=new UserService();
            user=userService.queryLoginUser(user);
            
            if(user !=null){//用户不为空,说明用户查找到了,可以进行登陆操作
                //获取记住密码的参数值
                String remember = request.getParameter("remember");
                if(remember !=null && "yes".equals(remember)){//勾选表示记住账号,保存用户名和密码
                    //使用cookie保存账号信息
                    Cookie nameCookie =new Cookie("name",user.getName());
                    Cookie passwordCookie = new Cookie("password",user.getPassword());
                    //设置cookie保存时间
                    nameCookie.setMaxAge(60*20);
                    passwordCookie.setMaxAge(60*20);
                    //发送给客户端浏览器
                    response.addCookie(nameCookie);
                    response.addCookie(passwordCookie);
                }
                //将user封装信息设置到session中,用于过滤检查品类操作页面是否是用户在登陆的情况下操作
                request.getSession().setAttribute("user",user);
                //重定向到品类列表页面(category是表示提交到CategoryServlet,method=getCategoryList表示执行CategoryServlet下的getCategoryList方法
                response.sendRedirect(request.getContextPath()+"/category?method=getCategoryList");
            }else{
                
                //设置响应客户端浏览器显示内容的编码格式
                response.setContentType("text/html;charset=utf-8");
                //登陆失败显示提示信息
                response.getWriter().write("登录失败!");
            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //获取封装信息
            Map<String, String[]> parameterMap = request.getParameterMap();
            User user=new User();
            BeanUtils.populate(user,parameterMap);

            //调用实现方法
            UserService userService=new UserService();
            boolean register=userService.registerUser(user);
            if(register){//注册成功
                //重定向到登陆页面
                response.sendRedirect(request.getContextPath()+"/login.jsp");
            }else{
                //设置响应客户端浏览器显示内容的编码格式
                response.setContentType("text/html;charset=utf-8");
                //注册失败显示登陆信息
                response.getWriter().write("注册失败!");
            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

          <2> UserService类

package com.study.service;

import com.study.bean.User;
import com.study.dao.UserDao;

import java.sql.SQLException;

public class UserService {
    /**
     * 查找登陆用户是否存在,存在返回登陆用户封装信息
     * @param user 封装登陆用户信息
     * @return 返回查找结果user
     * @throws SQLException
     */
    public User queryLoginUser(User user) throws SQLException {
        UserDao userDao=new UserDao();
        return userDao.queryLoginUser(user);
    }
    /**
     * 注册用户
     * @param user 封装登陆用户信息
     * @return 返回注册结果:布尔值
     * @throws SQLException
     */

    public boolean registerUser(User user) throws SQLException {
        UserDao userDao=new UserDao();
        //获取注册用户信息是否已经注册过
        boolean checkUser=userDao.checkUser(user);
        if(checkUser){
            //没有注册过,调用注册用户方法并返回注册结果,布尔值
            return userDao.registerUser(user);
        }
        //用户已经注册返回布尔值false
        return false;
    }
}

          <3> UserDao类

package com.study.dao;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.study.bean.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class UserDao {
    /**
     * 查找登陆用户,并返回结果
     * @param user
     * @return 返回查找结果
     * @throws SQLException
     */
    public User queryLoginUser(User user) throws SQLException {
        //连接数据库
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        //创建数据库操作类对象
        QueryRunner queryRunner = new QueryRunner(dataSource);
        //数据查找语句
        String sql="select * from user where name=? and password=?";
        //调用数据库操作类查找单个类信息的方法并返回查找结果,user或null
        return queryRunner.query(sql,new BeanHandler<User>(User.class),user.getName(),user.getPassword());

    }

    /**
     * 检查注册用户名是否已经注册过并返回结果布尔值
     * @param user
     * @return
     * @throws SQLException
     */
    public boolean checkUser(User user) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="select * from user where name=?";
        User query = queryRunner.query(sql, new BeanHandler<User>(User.class), user.getName());
        //三元表达式:如果用户为空则没有注册过,返回true,否则返回false
        return query == null ? true : false;
    }

    /**
     * 注册用户并返回注册结果布尔值
     * @param user
     * @return
     * @throws SQLException
     */
    public boolean registerUser(User user) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="insert into user values(null,?,?,?)";
        //调用数据库操作类的更新方法并得到一个int值的结果,大于0表示数据添加成功,否则失败
        int register = queryRunner.update(sql, user.getName(), user.getPassword(), user.getEmail());
        return register > 0 ? true : false;
    }
}

(4)生鲜类代码编写

     <1> CategoryServlet类:

package com.study.web;

import com.study.bean.Category;
import com.study.bean.Page;
import com.study.service.CategoryService;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;

@WebServlet(name = "CategoryServlet",urlPatterns = "/category")
public class CategoryServlet extends BaseServlet {
    /**
     * 获取显示列表信息并转发到显示列表
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void getCategoryList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        try {
           int currentPage=1;//设置当前页初始值是1
           int currentCount=10;//设置当前页总数目初始值是10
            //分别获取前端当前页和当前页总数目的String值
           String s1=request.getParameter("currentPage");
           String s2=request.getParameter("currentCount");

           if(s1 !=null) {//表示获取得到
               currentPage = Integer.parseInt(s1);//转为int值
               if (currentPage == 0) {
                   currentPage = 1;//设置当前页初始值是1
               }
           }
           if(s2 !=null) {//表示获取得到
               currentCount = Integer.parseInt(s2);//转为int值
               if (currentCount == 0) {
                   currentCount = 10;//设置当前页总数目初始值是10
               }
           }
           //创建CategoryService对象调用获取页面品类列表封装对象信息
           CategoryService categoryService=new CategoryService();
           Page page=categoryService.getPageCategory(currentPage,currentCount);
           if(page !=null) {//页面信息不为空
               request.setAttribute("page", page);//设置到request域中,这样在对应的请求转发页面就可以获取该信息
           }
           //将获取的页面信息转发到category-list.jsp页面(jsp实质上是Servelet类)
            request.getRequestDispatcher(request.getContextPath()+"/category-list.jsp").forward(request,response);

        }catch (SQLException e) {
            e.printStackTrace();
        }

    }

    /**
     * 添加生鲜品类
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void addCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Map<String, String[]> parameterMap = request.getParameterMap();
            Category category=new Category();
            BeanUtils.populate(category,parameterMap);
            category.setCreatetime(new Date());

            CategoryService categoryService=new CategoryService();
            boolean add=categoryService.addCategory(category);
            if(add){
                response.setStatus(201);//表示添加成功,重定向到生鲜列表页面
                response.sendRedirect(request.getContextPath()+"/category?method=getCategoryList");
            }else{
                response.setStatus(600);//表示添加失败,重定向到本页
                response.sendRedirect(request.getContextPath()+"/category-add.jsp");
            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改生鲜品类
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void updateCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Map<String, String[]> parameterMap = request.getParameterMap();
            Category category=new Category();
            BeanUtils.populate(category,parameterMap);
            category.setCreatetime(new Date());

            CategoryService categoryService=new CategoryService();
            boolean update=categoryService.updateCategory(category);
            if(update){
                response.setStatus(201);//表示更新成功,重定向到生鲜列表页面
                response.sendRedirect(request.getContextPath()+"/category?method=getCategoryList");
            }else{
                response.setStatus(600);//表示更新失败,重定向到本页
                response.sendRedirect(request.getContextPath()+"/category-update.jsp");
            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除生鲜品类
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void deleteCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Map<String, String[]> parameterMap = request.getParameterMap();
            Category category=new Category();
            BeanUtils.populate(category,parameterMap);

            CategoryService categoryService=new CategoryService();
            boolean delete=categoryService.deleteCategory(category);
            if(delete){//表示删除成功,重定向到生鲜列表页面
                response.sendRedirect(request.getContextPath()+"/category?method=getCategoryList");
            }else{//表示删除失败,显示提示信息
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("删除失败!");
            }


        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

     <2> CategoryService类:

package com.study.service;

import com.study.bean.Category;
import com.study.bean.Page;
import com.study.dao.CategoryDao;

import java.sql.SQLException;
import java.util.List;

public class CategoryService {
    public Page getPageCategory(int currentPage, int currentCount) throws SQLException {
        CategoryDao categoryDao=new CategoryDao();
        int totalCount=categoryDao.queryCount();//获取生鲜品类总数目
        int totalPage=(int)Math.ceil(1.0*totalCount/currentCount);//获取生鲜品类总页数
        int startPosition=(currentPage-1)*currentCount;//获取每一页生鲜品类的起始位置(不包括该数)
        List<Category> categories=categoryDao.queryPageCategoryList(startPosition,currentCount);//获取指定范围的生鲜品类的集合

        //封装到page对象中
        Page page=new Page();
        page.setCurrentPage(currentPage);
        page.setTotalPage(totalPage);
        page.setCurrentCount(currentCount);
        page.setTotalCount(totalCount);
        page.setList(categories);

        return page;
    }

    
    public boolean addCategory(Category category) throws SQLException {
        //添加生鲜品类
        CategoryDao categoryDao=new CategoryDao();
        return categoryDao.addCategory(category);

    }


    public boolean updateCategory(Category category) throws SQLException {
        //修改生鲜品类
        CategoryDao categoryDao=new CategoryDao();
        return categoryDao.updateCategory(category);

    }

    public boolean deleteCategory(Category category) throws SQLException {
        //删除生鲜品类
        CategoryDao categoryDao=new CategoryDao();
        return categoryDao.deleteCategory(category);

    }


}

     <3> CategoryDao类:

package com.study.dao;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.study.bean.Category;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

public class CategoryDao {
    /**
     * 查找生鲜品类总数目
     * @return 返回一个int值
     * @throws SQLException
     */
    public int queryCount() throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="select count(*) from category";
        Long query = queryRunner.query(sql, new ScalarHandler<>());
        return query.intValue();
    }

    /**
     * 查找指定范围生鲜品类集合
     * @return 返回一个生鲜品类对象集合
     * @throws SQLException
     */
    public List<Category> queryPageCategoryList(int startPosition, int currentCount) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="select * from category limit ?,?";
        return queryRunner.query(sql, new BeanListHandler<Category>(Category.class),startPosition,currentCount);
    }
    
    /**
     * 根添加生鲜品类
     * @return 返回一个布尔值,表示是否添加成功
     * @throws SQLException
     */
    public boolean addCategory(Category category) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="insert into category values(null,?,?,?,?)";
        int add = queryRunner.update(sql, category.getC_name(), category.getPlace(), category.getCreatetime(), category.getType());
        return add > 0 ? true : false;

    }

    /**
     * 根据c_id修改对应的生鲜品类
     * @return 返回一个布尔值,表示是否修改成功
     * @throws SQLException
     */
    public boolean updateCategory(Category category) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="update category set c_name=?,place=?,createtime=?,type=? where c_id=?";
        int update = queryRunner.update(sql,category.getC_name(), category.getPlace(), category.getCreatetime(), category.getType(),category.getC_id());
        return update > 0 ? true : false;

    }

    /**
     * 根据c_id删除对应的生鲜品类
     * @return 返回一个布尔值,表示是否删除成功
     * @throws SQLException
     */
    public boolean deleteCategory(Category category) throws SQLException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        String sql="delete from category where c_id=?";
        int delete = queryRunner.update(sql,category.getC_id());
        return delete > 0 ? true : false;
    }
}

(5)过滤器UserFilter类

package com.study.filter;

import com.study.bean.User;

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

/**
 * /category 表示对CategoryServlet类下的所有操作进行用户登陆过滤检查
 */
@WebFilter(filterName = "UserFilter",urlPatterns = "/category")
public class UserFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //转换类型
        HttpServletRequest request= (HttpServletRequest) req;
        HttpServletResponse response= (HttpServletResponse) resp;
        //获取session
        HttpSession session = request.getSession();
        //获取UserServlet类中login方法中设置的session属性值
        User user = (User) session.getAttribute("user");
        if(user==null){//表示用户没有登录,重定向到login.jsp页面,同时结束方法
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return;
        }

        //表示放行,用户已经登录,可以正常的提交页面信息
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

(6)素材前端页面的修改处如下:

(7)演示过程(点击之前配置的Tomcat server即可,就是Tomcat Server配置第一步点击处哪里寻找),这里是用做好的test10项目进行演示:

javaweb项目生鲜管理系统简易版演示.mp4

 

三、简单总结与拓展

1.简述添加生鲜品类的后端执行过程(其它类似)

(1)前端注册信息通过表单提交到UserServlet类,该类没有执行方法的入口,但是它的父类BaseServlet有,于是转到父类寻找执行方法入口,父类执行service()方法,该方法体通过反射获取其子类的方法并执行(因为前端表单在提交时同时提交了method的属性值,该值决定了执行子类的具体方法,这就要求前端的属性值和后端的方法名必须对应一致,否则无法使用BaseServletdi)
(2)首先通过UserServlet的register方法中request的getParameterMap()方法获取前端注册页面的注册信息,接着通过将信息封装到user对象中,调用UserService对象的registerUser()方法,在检测用户没有注册的情况下提交用户注册信息到数据库中,并且返回注册结果,注册成功则重新定向到登陆界面,否则给出提示信息,注册失败

(3)前端提交登陆界面信息后,后端调用UserServlet中login方法,同样先获取前端数据封装到对象user中,然后去数据库中查找有没有该用户,如有则获取前端记住密码的属性值,如果是“yes”则通过Cookie保存账号信息,否则不保存,同时将user对象设置到session对象的属性值中,这样UserFilter过滤器才能获取到user对象用于对生鲜品类界面操作判断用户是否已经登录;如果数据库中没有该用户,则提示登录失败。登录成功后,将挈带method参数值页面重定向到生鲜列表界面

(4)进入生鲜列表界面之前,首先判断用户是否已经登录,如果没有登录,则重定向到登陆界面login.jsp,如果已经登录,则先进入到BaseServlet中进行方法的调用,根据获取挈带的method值决定CategoryServlet的getCategoryList方法。

(5)首先给显示页面设置初始值,默认显示第1页,每页数量10条。这个通过获取前端属性值可以进行初值判断并且设置(如果不进行null值判断可能会报错)。此时我们可以通过一个封装类Page,将页面所有信息进行封装。通过数据库可以获取所有品类的总数,然后可以计算出总页数,当前页和当前页的数目通过前端设置获取;通过数据库还可以获取指定范围数目的生鲜品类信息的集合。所有这些都封装到page对象中,如果返回的page对象不是空值,则将其设置到request域中,通过request的请求转发将结果返回到前端页面前端页面再根据其结果将数据显示出来

(6)当我们进行添加生鲜品类时,前端提交表单会先进入UserFilter判断是否有用户登陆,如果没有,则重定向到登陆界面,否则就会进入正常提交表单数据操作:先是通过request的getParameterMap()方法获取表单数据,并且通过工具类封装到category对象中,然后调用对应的service和dao方法讲数据添加到数据库中,并且返回结果,如果成功,则向客户端发送一个成功的状态码,同时重新定向到生鲜列表显示界面(通过method挈带属性值重复(4)(5)步)

 

2.自己改写的简单工具类:

(1)db.properties替换c3p0-config.xml

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/fresh10?serverTimezone=GMT&useSSL=false
name=root
password=YCF500095

(2)数据库连接

package com.study.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
//import java.net.URL;

//连接数据库
public class DataSources {
	private static String driver;
	private static String URL;
	private static String USER;
	private static String PASSWORD;

	static {	
		try {
			ClassLoader classLoader=DataSources.class.getClassLoader();
			//URL resources=classLoader.getResource ("db.properties");
			InputStream resources=classLoader.getResourceAsStream("db.properties");
			Properties properties=new Properties();
			properties.load(resources);
			//properties.load (new FileReader (resources.getPath ()));
			driver=properties.getProperty("driver");
			URL=properties.getProperty("url");
			USER=properties.getProperty("name");
			PASSWORD=properties.getProperty("password");
		//System.out.println(driver+"\t"+URL+"\t"+USER+"\t"+PASSWORD);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public Connection getConnection(){
		Connection con=null;
		try {
			//注册驱动
			Class.forName(driver);
			//连接数据库
			con=DriverManager.getConnection(URL,USER,PASSWORD);
		} catch (ClassNotFoundException e) {
			System.out.println("数据库连接失败!");
			e.printStackTrace();
		} catch (SQLException e) {
			System.out.println("数据库连接失败!");
			e.printStackTrace();
		}
		return con;	
	}
	
}

(3)数据库操作

package com.study.utils;

import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

//数据库处理
@SuppressWarnings("unused")
public class QueryRunner {
    DataSources dataSources;

    public QueryRunner(DataSources dataSources) {
        this.dataSources = dataSources;
    }

    /**
     * 查找对象的集合
     * @param sql
     * @param beanListHandler
     * @param params
     * @return 返回一个对象集合
     * @throws SQLException
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public List query(String sql, BeanListHandler beanListHandler, Object... params) throws SQLException {
        List list = new ArrayList();
        try {
            //连接数据库
            Connection con = dataSources.getConnection();
            //调用查询方法
            PreparedStatement preparedStatement = con.prepareStatement(sql);
            //使用不确定参数,解决参数类型和参数个数未定的问题
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject((i + 1), params[i]);
            }
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                //需要set方法,属性类型,属性名称
                list.add(beanListHandler.reflectMethod(resultSet));
            }
            //关闭资源
            resultSet.close();
            preparedStatement.close();
            con.close();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 查找一个对象
     * @param sql
     * @param beanHandler
     * @param params
     * @return  返回一个对象
     * @throws SQLException
     */
    public Object query(String sql, BeanHandler beanHandler, Object... params) throws SQLException{
        Object obj=null;
        try {
            //连接数据库
            Connection con = dataSources.getConnection();
            //调用查询方法
            PreparedStatement preparedStatement = con.prepareStatement(sql);
            //使用不确定参数,解决参数类型和参数个数未定的问题
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject((i + 1), params[i]);
            }
            ResultSet resultSet = preparedStatement.executeQuery();

            while(resultSet.next()){
                obj=beanHandler.reflectMethod(resultSet);
            }
            //关闭资源
            resultSet.close();
            preparedStatement.close();
            con.close();

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 查找表的统计数据
     * @param sql
     * @param scalarHandler
     * @param params
     * @return 返回一个long值
     * @throws SQLException
     */
    public Long query(String sql, ScalarHandler scalarHandler, Object...params) throws SQLException {

            //连接数据库
            Connection con=dataSources.getConnection();
            //调用查询方法
            PreparedStatement preparedStatement=con.prepareStatement(sql);
            //使用不确定参数,解决参数类型和参数个数未定的问题
            for(int i=0;i<params.length;i++) {
                preparedStatement.setObject((i+1), params[i]);
            }
        ResultSet resultSet=preparedStatement.executeQuery();
        Long num=scalarHandler.getObjectRows(resultSet);
            //关闭资源

           resultSet.close();
            preparedStatement.close();
            con.close();
            return num;


    }
	
	//添加、修改、删除数据
	public int update(String sql,Object...params) {
		int row=0;
		try {
			Connection con=dataSources.getConnection();
			//使用preparedStatement防止SQL注入
			PreparedStatement preparedStatement=con.prepareStatement(sql);
			//使用不确定参数,解决参数类型和参数个数未定的问题
			for(int i=0;i<params.length;i++) {
				preparedStatement.setObject((i+1), params[i]);
			}
			//返回添加结果,结果是一个整数
			row =preparedStatement.executeUpdate();
			//关闭资源
			preparedStatement.close();
			//con.close();
		}catch (SQLException e) {
			e.printStackTrace();
		}
		return row;	
	}
}




 

(4)工具类BeanUtils:将前端相应参数值封装到对应对象中

package com.study.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 将前端相应参数封装到对象中
 */
public class BeanUtils{


    public static void populate(Object obj,Map<String,String[]> parameterMap) throws InvocationTargetException, IllegalAccessException{

            //得到字节码文件
            Class cls = obj.getClass();
            //获取对象字节码对象的所有方法
            Method[] mt = cls.getDeclaredMethods();
            //获取前端得到的键的集合
            Set<String> keySet = parameterMap.keySet();
            //使用迭代器读取

            for (Method e : mt) {
                //用下面这个方法,前提如下:对象封装类的void方法只有set方法
                if (e.getReturnType().equals(Void.TYPE)) {//获取封装对象的所有void方法
                    //获取void setter()方法名字名称部分:如public void setSum(int sum){this.sum=sum;}得到“setSum”中的“Sum”
                    String str = getMethodParameterName(e.getName());
                    if (str != null) {
                        Iterator<String> it = keySet.iterator();
                        while (it.hasNext()) {//读取前端得到的键名,即属性名称
                            String key = it.next();//得到属性名
                            String[] value = parameterMap.get(key);//获取对应键名(即属性名)的键值
                             System.out.println(str+";;;"+key+";;;"+value[0]);
                            if (key.equals(str)) {//如果方法名和键名对应,则执行对应方法
                                if(e.getParameterTypes()[0].getTypeName().equals("java.lang.String")) {//参数类型判断
                                    //指定方法赋值,即调用setter方法,(即如调用了public void setSum(int sum){this.sum=sum;})
                                    e.invoke(obj, value[0]);
                                }else{//数值类型转换为int型,当然可以把所有的数据类型列出来
                                    e.invoke(obj, Integer.parseInt(value[0]));
                                }
                                break;
                            }
                        }
                    }

                }
            }
    }


    public static String getMethodParameterName(String ss) {
        /**
         * 例:public void setSum(int sum){this.sum=sum;}
         * ss就是对应void型方法,只对set方法进行操作;
         * ss.substring(3,ss.length()).substring(0,1).toLowerCase(): 得到s
         * ss.substring(4,ss.length()):得到um
         * 拼起来就是sum(即得到了私有数据域private int sum的变量名称,和前端的属性名称是对应)
         */
        if(ss.substring(0,3).equals("set")) {
            return ss.substring(3, ss.length()).substring(0, 1).toLowerCase() + ss.substring(4, ss.length());
        }
        return null;
    }

}

(5)具体执行方法

package com.study.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 集合操作
 * @param <T>
 */
public class BeanListHandler<T>{
	@SuppressWarnings("rawtype")
	Class obj;
	//带字节码对象参数的构造方法
	public BeanListHandler(Class obj){
		this.obj=obj;//获得类名

	}

	public T reflectMethod(ResultSet resultSet) throws NoSuchMethodException, IllegalAccessException, InstantiationException, SQLException, InvocationTargetException {
		T t=(T) obj.newInstance();//实例化对象
		Method[] mt=obj.getDeclaredMethods();//获取本类所有的方法
		for(Method e:mt) {
			//找对象封装类的void类型的set方法
			if(e.getReturnType().equals(Void.TYPE)) {
				Method met=obj.getDeclaredMethod(e.getName(), e.getParameterTypes()[0]);//获取指定类的方法
                //通过void类型的set方法获取封装对象私有域变量名称
				String str=this.getMethodParameterName(e.getName());
				if(str !=null) {
				    if(e.getParameterTypes()[0].getTypeName().equals("java.util.Date")){
                       //执行该setter方法,不支持Date方法
                      met.invoke(t, resultSet.getDate(str));
                    }else{
                        //执行该setter方法,不支持Date方法
                        met.invoke(t, resultSet.getObject(str, e.getParameterTypes()[0]));

                    }

                }
			}
		}
		return t;
	}
	public String getMethodParameterName(String ss) {
	    if(ss.substring(0,3).equals("set")) {
	        //得到私有域变量名称
            return ss.substring(3, ss.length()).substring(0, 1).toLowerCase() + ss.substring(4, ss.length());
        }
		return null;
	}
}



package com.study.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 单类操作
 * @param <T>
 */
public class BeanHandler<T> {
    @SuppressWarnings("rawtypes")
    Class clazz;

    //带字节码对象参数的构造方法
    public BeanHandler(Class obj){
        this.clazz=obj;//获得类名

    }

    public T reflectMethod(ResultSet resultSet) throws SQLException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        T t = (T) clazz.newInstance();//实例化对象
            Method[] mts = clazz.getDeclaredMethods();//获取本类所有的方法
            for (Method e : mts) {
                //找对象封装类的void类型的set方法
                if (e.getReturnType().equals(Void.TYPE)) {
                    //获取指定类的方法
                    Method met = clazz.getMethod(e.getName(), e.getParameterTypes()[0]);
                    //通过void类型的set方法获取封装对象私有域变量名称
                    String str = this.getMethodParameterName(e.getName());
                    if (str != null) {
                        //执行该setter方法
                        met.invoke(t, resultSet.getObject(str, e.getParameterTypes()[0]));
                    }
                }
            }


        System.out.println(t.getClass());
        return t;
    }
        public String getMethodParameterName(String ss) {
        if(ss.substring(0,3).equals("set")) {
            //得到私有域变量名称
            return ss.substring(3, ss.length()).substring(0, 1).toLowerCase() + ss.substring(4, ss.length());
        }
        return null;
    }
}


package com.study.utils;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 统计数据操作
 * @param <T>
 */
public class ScalarHandler<T> {
    Object obj;
    public ScalarHandler(){
    }

    public ScalarHandler(Object obj){
        this.obj=obj;
    }



    public Long getObjectRows(ResultSet resultSet) throws SQLException {
        long num=0;
        while (resultSet.next()){
            num=resultSet.getInt(1);
        }
        return num;
    }

}

 

 

四、学习过程遇到的问题

1.配置文件连接数据库的问题

(1)driver驱动:根据不同版本的数据库连接包,其配置也不相同。例如在该例子中:我使用的是:mysql-connector-java-8.0.14.jar,所以其driver配置就为:

com.mysql.cj.jdbc.Driver(如果你是用db.properties文件,则为:driver=com.mysql.cj.jdbc.Driver),版本低就不要加“cj."

(1)url:根据不同版本的数据库连接包,其配置也不相同。例如在该例子中,我的配置就为:

jdbc:mysql://localhost:3306/fresh10?serverTimezone=GMT%2B8&amp;useSSL=false
(如果你是用db.properties文件,则为:jdbc:mysql://localhost:3306/fresh10?serverTimezone=GMT%2B8&useSSL=false)
 

2.数据库操作的问题

注意不要写错sql语句和参数

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你好,2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值