一.准备工作

1.maven环境搭建

使用模板maven的javaweb模板创建。
更改web.xml的配置文件为新版。(解决EL表达式不能正确识别)

<?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_4_0.xsd"
         version="4.0"
         metadata-complete="true">


<display-name>Archetype Created Web Application</display-name>
</web-app>

2.Tomcat配置

3.导入jar包

在pom.xml中配置需要使用的jar包。
jsp, servlet, mysql, jstl, taglib(标签库)。

例如:

<dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
    </dependency>

4.创建项目包结构

超市架构图怎么做 超市框架结构_maven

项目整体结构:

dao层存放数据库的操作类

filter存放过滤器

pojo存放数据库中表的类的映射(表->java类)

service存放(事务层)

servlet存放servlet层(操作事务层)

util存放constant常量

5.实体类

ORM映射 数据库的表–>类的映射,写在pojo包下。

例如smbms数据库中的user表的对应如下(其他表同理,要包含get,set方法),将表的每个属性映射为类中的属性,并设置相应的get,set方法。

对toString方法进行重写:当直接使用System.out.println(类名),会输出tostring方法的内容,默认是hashcode值。

超市架构图怎么做 超市框架结构_超市架构图怎么做_02

package com.han.pojo;

import java.util.Date;

public class User {
    private Integer id; //id
    private String userCode; //用户编码
    private String userName; //用户名称
    private String userPassword; //用户密码
    private Integer gender;  //性别
    private Date birthday;  //出生日期
    private String phone;   //电话
    private String address; //地址
    private Integer userRole;    //用户角色
    private Integer createdBy;   //创建者
    private Date creationDate; //创建时间
    private Integer modifyBy;     //更新者
    private Date modifyDate;   //更新时间

    private Integer age;//年龄,通过获取当前时间与出生时间计算得出。

    private String userRoleName;    //用户角色名称


    public String getUserRoleName() {
        return userRoleName;
    }

    public void setUserRoleName(String userRoleName) {
        this.userRoleName = userRoleName;
    }

    //计算年龄
    public Integer getAge() {
		/*long time = System.currentTimeMillis()-birthday.getTime();
		Integer age = Long.valueOf(time/365/24/60/60/1000).IntegerValue();*/
        Date date = new Date();
        Integer age = date.getYear() - birthday.getYear();
        return age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userCode='" + userCode + '\'' +
                ", userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", gender=" + gender +
                ", birthday=" + birthday +
                ", phone='" + phone + '\'' +
                ", address='" + address + '\'' +
                ", userRole=" + userRole +
                ", createdBy=" + createdBy +
                ", creationDate=" + creationDate +
                ", modifyBy=" + modifyBy +
                ", modifyDate=" + modifyDate +
                ", age=" + age +
                ", userRoleName='" + userRoleName + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserCode() {
        return userCode;
    }

    public void setUserCode(String userCode) {
        this.userCode = userCode;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getUserRole() {
        return userRole;
    }

    public void setUserRole(Integer userRole) {
        this.userRole = userRole;
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public Integer getModifyBy() {
        return modifyBy;
    }

    public void setModifyBy(Integer modifyBy) {
        this.modifyBy = modifyBy;
    }

    public Date getModifyDate() {
        return modifyDate;
    }

    public void setModifyDate(Date modifyDate) {
        this.modifyDate = modifyDate;
    }
}

6.基础公共类

6.1数据库配置文件

resources文件夹下,建立db.properties文件
存放数据库的配置信息

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username=root
password=123456
6.2编写数据库的公共类(Dao层)

建立basedao层,作为模板,并建立多种针对每个表的
dao层。
首先通过类加载器读取数据库配置文件db.properties中的属性。

private static String driver;
    private static String username;
    private static String password;
    private static String url;

    static {
        Properties properties = new Properties();
        //通过类加载器实现,获取资源的流,读取db文件中的属性
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver = properties.getProperty("driver");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
        url = properties.getProperty("url");
    }

获取数据库的连接
PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句“准备好”。包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN参数的值在 SQL 语句创建时未被指定。相反的,该语句为每个 IN 参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX 方法来提供。

//获取数据库的连接
    public static Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

方法executeQuery
用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句.

//编写查询的公共方法
    public static ResultSet execute(Connection connection, String sql, PreparedStatement preparedStatement,ResultSet resultSet,Object[] params) throws SQLException {
        preparedStatement=connection.prepareStatement(sql);
        //填充参数列表,paramater从1开始
        for(int i=0;i<params.length;i++){
            preparedStatement.setObject(i+1,params[i]);
        }
        resultSet=preparedStatement.executeQuery();
        return resultSet;
    }

编写数据库修改的公共方法(executeUpdate)
方法executeUpdate
用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。

//编写增删改公共方法
    public static int execute(Connection connection, String sql, PreparedStatement preparedStatement,Object[] params) throws SQLException {
        preparedStatement=connection.prepareStatement(sql);
        for(int i=0;i<params.length;i++){
            preparedStatement.setObject(i+1,params[i]);
        }
        int updateRows=preparedStatement.executeUpdate();
        return updateRows;
    }

编写数据库关闭资源

public static boolean closeResource(Connection connection,PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException
    {
        boolean flag=true;
        if(resultSet!=null){
            resultSet.close();
            //垃圾回收机制
            resultSet=null;
        }
        else{
            flag=false;
        }

        if(connection!=null){
            connection.close();
            connection=null;
        }
        else{
            flag=false;
        }

        if(preparedStatement!=null){
            preparedStatement.close();
            preparedStatement=null;
        }
        else {
            flag=false;
        }
        return flag;
    }

6.3编写字符编码过滤器

package com.han.filter;

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

public class CharacterEncodingFilter implements Filter {
    public void destroy() {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }
}

将该过滤器对所有路径,在web.xml中进行配置。

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.han.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

7.导入静态资源

超市架构图怎么做 超市框架结构_java_03

二.登录流程

超市架构图怎么做 超市框架结构_超市架构图怎么做_04

1编写前端页面

login.jsp(登陆页面)

2设置默认欢迎页

在web.xml中配置,将login.jsp设置为默认的页面。

<display-name>Archetype Created Web Application</display-name>
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

3编写业务层,通过DAO层获取数据库信息

service从dao层中获取需要的用户信息。

package com.han.service.user;

import com.han.dao.BaseDao;
import com.han.dao.user.UserDao;
import com.han.dao.user.UserDaoImpl;
import com.han.pojo.User;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;

public class UserServiceImpl implements UserService{
    //业务层需要调用Dao层,所以先引入
    private UserDao userDao;
    public UserServiceImpl(){
        userDao=new UserDaoImpl();
    }

    @Override
    public User login(String userCode, String password) throws SQLException {
        Connection connection=null;
        User user=null;

        //业务层调用dao层
        connection= BaseDao.getConnection();
        user= userDao.getLoginUser(connection,userCode);
        return user;
    }
    @Test
    public void test() throws SQLException {
        UserServiceImpl userService=new UserServiceImpl();
        User admin=userService.login("admin","123456");
        System.out.println(admin.getUserPassword());
    }
}

4.编写servlet,调用sevice层

package com.han.servlet;

import com.han.pojo.User;
import com.han.service.user.UserService;
import com.han.service.user.UserServiceImpl;
import com.han.util.Constant;

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.sql.SQLException;

public class LoginServlet extends HttpServlet {
    //控制层调用事务层
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        System.out.println("Login--Servlet--start");
        //获取用户名和密码
        String userCode= req.getParameter("userCode");
        String userPassword= req.getParameter("userPassword");
        //和业务层中的数据作比较
        UserService userService=new UserServiceImpl();//这里把已经登录的人查出来
        User user= null;
        try {
            user = userService.login(userCode,userPassword);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

        if(user!=null&&user.getUserPassword().equals(userPassword)){
            req.getSession().setAttribute(Constant.USER_SESSION,user);
            resp.sendRedirect("jsp/frame.jsp");
        }
        else{//没这个人无法登录,返回登录页面,并提示错误信息
            req.setAttribute("error","用户名或密码不正确");
            req.getRequestDispatcher("login.jsp").forward(req,resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req,resp);
    //前端的login用的是post提交方式,操作的代码都写在了doGet方法中,所以要进行调用。
    }

}
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>

<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>系统登录 - 超市订单管理系统</title>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"/>
</head>
<body class="login_bg">
<section class="loginBox">
    <header class="loginHeader">
        <h1>超市订单管理系统</h1>
    </header>
    <section class="loginCont">
        <form class="loginForm" action="${pageContext.request.contextPath}/login.do" method="post" name="actionForm"
              id="actionForm">

            <!--error来自loginservlet发送的错误信息-->

            <div class="info">${error}</div>


            <div class="inputbox">
                <label for="userCode">用户名:</label>
                <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
            </div>
            <div class="inputbox">
                <label for="userPassword">密码:</label>
                <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
            </div>
            <div class="subBtn">
                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </div>
        </form>
    </section>
</section>
</body>
</html>