写个小网站(也就增删改查)

发布于:2023-01-04 ⋅ 阅读:(189) ⋅ 点赞:(0)

注:刚学完springboot,试着自己写了个网站,记录一下对比以后,如果文中有更好的实现方法欢迎大佬指出。(静态资源前端资源和数据库采用的狂神视频中的)

目录

一、准备工作

1.导入项目依赖

2.建立项目结构,导入静态资源

3.配置yaml

4.数据库

5.连接数据库

6.建实体类

二、主要功能

1.添加订单

2.修改订单

3.删除

4.显示供应商信息

5.展示,分页,升降序,查询

三、其他功能

1.添加视图解析器

2.首页实现

3. 拦截器

4.权限控制

5.登录功能实现

6.注册功能实现

7.注销

8.404,500


一、准备工作

所用到的技术,springboot(2.6.10),maven,mybatis,thymeleaf,mysql

1.导入项目依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2.建立项目结构,导入静态资源

注解:
@Controller(标注一个业务逻辑组件类)
@Mapper (将mapper注册到spring里)
@Repository (标注一个DAO组件类)
@service(标注一个业务逻辑组件类)
@Autowired:可用于为类的属性、构造器、方法进行注值

3.配置yaml

注意空格

#数据源
spring:
  datasource:
    username: root
    password:
    url: jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
#关闭thymeleaf缓存
  thymeleaf:
    cache: false
#设置时间格式,和数据库不一致存不进去
  mvc:
    format:
      date: yyyy-MM-dd
#mybatis别名,扫描包位置,日志
mybatis:
  type-aliases-package: com.zhu.myspringboot.pojo
  mapper-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4.数据库

一些字段没有用到

库名:smbms 表:

smbms_bill

​smbms_provider

smbms_user

5.连接数据库

6.建实体类

二、主要功能

1.添加订单 2.修改订单 3.删除订单 4.点击商品名称显示所有供应商信息,点击一个具体商品显示对应商品供应商信息 5.显示全部订单 6.查询 7.分页 8.点击商品数量,会按商品数量升降序

1.添加订单

前端

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <h2>添加订单</h2>
            <form th:action="@{/addBill}" method="post">
                <div class="form-group">
                    <label>账单编码</label>
                    <input type="text" name="billCode" class="form-control" placeholder="账单编码">
                </div>
                <div class="form-group">
                    <label>商品名称</label>
                    <input type="text" name="productName" class="form-control" placeholder="商品名称">
                </div>
                <div class="form-group">
                    <label>商品单位</label>
                    <input type="text" name="productUnit" class="form-control" placeholder="商品单位">
                </div>
                <div class="form-group">
                    <label>商品数量</label>
                    <input type="text" name="productCount" class="form-control" placeholder="商品数量">
                </div>
                <div class="form-group">
                    <label>总金额</label>
                    <input type="text" name="totalPrice" class="form-control" placeholder="总金额">
                </div>
                <div class="form-group">
                    <label>供应商</label>
                    <input type="text" name="providerId" class="form-control" placeholder="供应商">
                </div>
                <div class="form-group">
                    <label>是否支付</label><br>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="isPayment" value="1">
                        <label class="form-check-label">是</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input  class="form-check-input" type="radio" name="isPayment" value="2">
                        <label class="form-check-label">否</label>
                    </div>
                </div>
                <div class="form-group">
                    <button class="btn btn-primary">添加</button>
                </div>
            </form>
        </main>

mapper

    //添加订单
    int addBill(Bill bill);

mapper.xml(建在resources和mapper同名包下)

<insert>标签

    <insert id="addBill" parameterType="bill">
        insert into smbms.smbms_bill (billCode, productName, productUnit, productCount, totalPrice, isPayment,providerId)
        values (#{billCode},#{productName},#{productUnit},#{productCount},#{totalPrice},#{isPayment},#{providerId})
    </insert>

在service层注入mapper: @Autowired MyMapper myMapper

在controller层注入service @Autowired MyServiceImpl myService;

cotroller

    @RequestMapping("/toAddBill")
    public String toAddBill(Model model){

        return "/add/addBill";
    }

    //form表单会把name里的同名属性封装到对象里
    @RequestMapping("/addBill")
    public String addBill(Bill bill){

        myService.addBill(bill);
        return "redirect:/billList/1";
    }

2.修改订单

前端

//index.html
<a class="btn btn-sm btn-primary" th:href="@{'/updateBill/'+${billList.getId()}}">修改</a>
//updateBill.html
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <h2>修改订单</h2>
            <form th:action="@{/updateBill}" method="post">
                <input type="hidden" name="id" th:value="${upBillList.getId()}">
                <div class="form-group">
                    <label>账单编码</label>
                    <input th:value="${upBillList.getBillCode()}" type="text" name="billCode" class="form-control">
                </div>
                <div class="form-group">
                    <label>商品名称</label>
                    <input th:value="${upBillList.getProductName()}" type="text" name="productName" class="form-control">
                </div>
                <div class="form-group">
                    <label>商品单位</label>
                    <select class="form-control" name="productUnit">
                        <!--/*@thymesVar id="departments" type=""*/-->
                        <option th:each="billList:${billLists}" th:text="${billList.getProductUnit()}" th:value="${billList.getProductUnit()}"></option>
                    </select>
                </div>
                <div class="form-group">
                    <label>商品数量</label>
                    <input th:value="${upBillList.getProductCount()}" type="text" name="productCount" class="form-control">
                </div>
                <div class="form-group">
                    <label>总金额</label>
                    <input th:value="${upBillList.getTotalPrice()}" type="text" name="totalPrice" class="form-control">
                </div>
                <div class="form-group">
                    <label>是否支付</label><br>
                    <div class="form-check form-check-inline">
                        <input th:checked="${upBillList.getIsPayment()==1}" class="form-check-input" type="radio" name="isPayment" value="1">
                        <label class="form-check-label">是</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input th:checked="${upBillList.getIsPayment()==2}" class="form-check-input" type="radio" name="isPayment" value="2">
                        <label class="form-check-label">否</label>
                    </div>
                </div>
                <div class="form-group">
                    <button class="btn btn-primary">修改</button>
                </div>
            </form>
        </main>

mapper

    //修改订单
    int updateBill(Bill bill);

mapper.xml

<update>标签 

    <update id="updateBill" parameterType="bill" >
        update smbms.smbms_bill set billCode=#{billCode},productName=#{productName},productUnit=#{productUnit},
                                    productCount=#{productCount},totalPrice=#{totalPrice},isPayment=#{isPayment}
        where id=#{id}
    </update>

controller

    @RequestMapping("/updateBill/{id}")
    public String toUpdateBill(@PathVariable("id") int id,Model model){

        Bill billById = myService.getBillById(id);
        model.addAttribute("upBillList",billById);

        Map<String,Object> map = new HashMap<>();
        List<Bill> allBill = myService.getAllBill(map);
      //用于前端展示原来的信息,方便修改
        model.addAttribute("billLists",allBill);

        return "/update/updateBill";
    }

    @PostMapping("/updateBill")
    public String updateBill(Bill bill){

        myService.updateBill(bill);

        return "redirect:/billList/1";
    }

3.删除

前端

//index.html
<a class="btn btn-sm btn-danger" th:href="@{'/deleteBill/'+${billList.getId()}}">删除</a>

mapper

    int deleteBill(int id);

mapper.xml

    <delete id="deleteBill" parameterType="int">
        delete from smbms.smbms_bill where id=#{id}
    </delete>

controller

    @RequestMapping("/deleteBill/{id}")
    public String delete(@PathVariable("id") int id){
        myService.deleteBill(id);

        return "redirect:/billList/1";
    }

4.显示供应商信息

前端

//index.html
//显示所有供应商
<th><a class="form-inline" href="/providerList">商品名称</a></th>
//显示对应供应商
<td><a style="color: blue" class="nav-link" th:href="@{'/providerList/'+${billList.getProviderId()}}" th:text="${billList.getProductName()}"></a></td>
//providerList.html
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
            <h2>供应商信息</h2>
            <div class="table-responsive">
                <table class="table table-striped table-sm">
                    <thead>
                    <tr>
                        <th><p>供应商编码</p></th>
                        <th><p>供应商名称</p></th>
                        <th><p>供应商描述</p></th>
                        <th><p>供应商联系人</p></th>
                        <th><p>供应商电话</p></th>
                        <th><p>供应商地址</p></th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr th:each="provider:${providers}">
                        <!--/*@thymesVar id="getBillCode" type="com.zhu.myspringboot.pojo"*/-->
                        <td><p th:text="${provider.getProCode()}"></p></td>
                        <td><p th:text="${provider.getProName()}"></p></td>
                        <td><p th:text="${provider.getProDesc()}"></p></td>
                        <td><p th:text="${provider.getProContact()}"></p></td>
                        <td><p th:text="${provider.getProPhone()}"></p></td>
                        <td><p th:text="${provider.getProAddress()}"></p></td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </main>

mapper

    //获取供应商信息
    List<Provider> getProvider();
    //获取对应的供应商信息
    List<Provider> getBillProvider(int providerId);

mapper.xml

    <select id="getProvider" resultType="provider">
        select * from smbms.smbms_provider
    </select>
    <select id="getBillProvider" parameterType="int" resultType="provider">
        select * from smbms.smbms_provider where id=#{providerId}
    </select>

controller

    //显示所有
    @RequestMapping("/providerList")
    public String toProviderList(Model model){

        List<Provider> providers = myService.getProvider();
        model.addAttribute("providers",providers);

        return "list/providerList";

    }
    //显示对应
    @RequestMapping("/providerList/{providerId}")
    public String getBillProvider(@PathVariable("providerId") int providerId,Model model){

        List<Provider> billProvider = myService.getBillProvider(providerId);
        model.addAttribute("providers",billProvider);

        return "/list/providerList";
    }

5.展示,分页,升降序,查询

前端

<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2>订单信息</h2>
					<div class="row">
						<div>
							<a class="btn btn-sm btn-primary" href="/toAddBill">添加订单</a>
						</div>
						<div>
							<a class="btn btn-sm btn-primary" href="/billList/1">全部订单</a>
						</div>
						<div class="col-md-4 column">
							<form class="form-inline" th:action="@{/jumpBill}" method="post" style="float: right">
								<input type="hidden" name="num" value="1">
								<input type="hidden" name="orderColumn" th:value="${orderColumn}">
								<input type="hidden" name="orderType" th:value="${orderType}">
								<input type="text" placeholder="搜索一下" name="queryParam" class="form-control" required>
								<input type="submit" value="查询" class="btn btn-sm btn-primary">
								<p style="color: red" th:text="${error}" th:if="${not #strings.isEmpty(error)}"></p>
							</form>

						</div>
					</div><br>
					<div class="table-responsive">
						<table class="table table-striped table-sm">
							<thead>
								<tr>
									<th>账单编码</th>
									<th><a class="form-inline" href="/providerList">商品名称</a></th>
									<th>商品单位</th>
									<th>
										<a class="form-inline" th:href="@{'/billList/'+${queryParam}+'/productCount/'+${!orderType}+'/1'}">商品数量</a>
									</th>
									<th>
										<a class="form-inline" th:href="@{'/billList/'+${queryParam}+'/totalPrice/'+${!orderType}+'/1'}">商品数量</a>
									</th>
									<th>是否支付</th>
								</tr>
							</thead>
						<tbody>
							<tr th:each="billList:${billLists}">
								<!--/*@thymesVar id="getBillCode" type="com.zhu.myspringboot.pojo"*/-->
								<td th:text="${billList.getBillCode()}"></td>
								<td><a style="color: blue" class="nav-link" th:href="@{'/providerList/'+${billList.getProviderId()}}" th:text="${billList.getProductName()}"></a></td>
								<td th:text="${billList.getProductUnit()}"></td>
								<td th:text="${billList.getProductCount()}"></td>
								<td th:text="${billList.getTotalPrice()}"></td>
								<td th:text="${billList.getIsPayment()==1?'已支付':'未支付'}"></td>
								<td>
									<a class="btn btn-sm btn-primary" th:href="@{'/updateBill/'+${billList.getId()}}">修改</a>
									<a class="btn btn-sm btn-danger" th:href="@{'/deleteBill/'+${billList.getId()}}">删除</a>
								</td>
							</tr>
						</tbody>
						</table>
					</div>
					<div class="row">
						<div>
							<a class="btn btn-sm btn-primary" th:href="@{'/billList/'+${queryParam}+'/'+${orderColumn}+'/'+${orderType}+'/1'}">首页</a>
						</div>
						<div>
							<a class="btn btn-sm btn-primary" th:href="@{'/billList/'+${queryParam}+'/'+${orderColumn}+'/'+${orderType}+'/'+${currentPage - 1}}">上一页</a>
						</div>
						<a style="font-size: 20px" class="text-uppercase">[[${currentPage}]]/[[${totalPage}]]</a>
						<div>
							<a class="btn btn-sm btn-primary" th:href="@{'/billList/'+${queryParam}+'/'+${orderColumn}+'/'+${orderType}+'/'+${currentPage + 1}}">下一页</a>
						</div>
						<div>
							<a class="btn btn-sm btn-primary" th:href="@{'/billList/'+${queryParam}+'/'+${orderColumn}+'/'+${orderType}+'/'+${totalPage}}">尾页</a>
						</div>
						<form class="form-inline" th:action="@{/jumpBill}" method="post" style="float: end">
							<input type="hidden" name="orderColumn" th:value="${orderColumn}">
							<input type="hidden" name="orderType" th:value="${orderType}">
							<input type="hidden" name="queryParam" th:value="${queryParam}">
							<input type="text" placeholder="请输入要跳转的页面" name="num" class="form-control" required>
							<input type="submit" value="跳转" class="btn btn-sm btn-primary">
							<p class="hideSlow" style="color: red" th:text="${errorJump}" th:if="${not #strings.isEmpty(errorJump)}"></p>
						</form>
					</div>
				</main>

mapper

    //所有要显示的订单信息
    List<Bill> getAllBill(Map<String,Object> map);

mapper.xml

//可以不用查provider表,没用到,一开始写上没改
<select id="getAllBill" parameterType="map" resultMap="AllBill">

        SELECT DISTINCT b.id bid,billcode,productName,proDesc,productUnit,productCount,totalPrice,isPayment,providerId,proName,proContact
        from smbms.smbms_bill b,smbms.smbms_provider p
        where b.providerId = p.id
//注意第一个是and,查询所有字段
        <if test="queryParam != null">
            and (billCode like "%"#{queryParam}"%" or productName like "%"#{queryParam}"%" or productUnit like "%"#{queryParam}"%"
            or productCount like "%"#{queryParam}"%" or totalPrice like "%"#{queryParam}"%" or isPayment like "%"#{queryParam}"%")
        </if>
//orderType直接写asc或desc会报错,注意中间有一个空格
        <if test="orderType !=null and orderColumn != null">
            order by b.${orderColumn} ${orderType}
        </if>

        <if test="num != null">
            limit ${num * 5},5
        </if>

    </select>
    <resultMap id="AllBill" type="Bill">
        <result property="id" column="bid"/>
        <result property="billCode" column="billCode"/>
        <result property="productName" column="productName"/>
        <result property="proDesc" column="proDesc"/>
        <result property="productUnit" column="productUnit"/>
        <result property="productCount" column="productCount"/>
        <result property="totalPrice" column="totalPrice"/>
        <result property="isPayment" column="isPayment"/>
        <result property="providerId" column="providerId"/>
        <association property="provider" javaType="provider">
            <result property="proName" column="proName"/>
            <result property="proContact" column="proContact"/>
        </association>
    </resultMap>

controller

//1.展示 2.分页 3.查询 4.按字段升降序
     /**
     * @param queryParam   查询
     * @param orderColumn  要排序的字段
     * @param orderType    升序为false,降序true
     * @param num          页数
     */
    //restful可能为空的字段,加上required = false,写多个路径
    @RequestMapping(value = {"/billList/{queryParam}/{orderColumn}/{orderType}/{num}","/billList/{queryParam}/{num}",
            "/billList/{orderColumn}/{orderType}/{num}","/billList/{num}"})
    public String toBillList(@PathVariable(value = "queryParam",required = false) String queryParam,
                             @PathVariable(value = "orderColumn",required = false) String orderColumn,
                             @PathVariable(value = "orderType",required = false) boolean orderType,
                             @PathVariable("num") int num,Model model){


        int currentPage;//当前页
        int totalPage;//总页数
        List<Bill> billList;//条件查询出的
        List<Bill> allBill;//所有的

        //所有订单
        Map<String,Object> map = new HashMap<>();

        //判空的时候先判断是否为null,否则会有空指针异常,restful风格传进来的null是字符串(不知道是不是我传的有问题)
        if(queryParam != null && !queryParam.isEmpty() && !queryParam.equals("null")){
            map.put("queryParam", queryParam);//queryParam为空则展示全部,不为空展示查询所有字段为queryParam的结果
        }

        //map为空也就是所有订单
        allBill = myService.getAllBill(map);

        //总页数(一页展示五个)
        if((allBill.size() % 5) == 0){
            totalPage = (allBill.size() / 5);
        }else{
            totalPage = (allBill.size() / 5) + 1;
        }

        //判断边界
        if(num < 1){
            num = 1;
        }

        if(num > totalPage ){
            num = totalPage ;
        }
        //当前页
        currentPage = num ;

        //分页之后
        map.put("num",num - 1);

        //排序默认按创建时间升序
        if(orderColumn != null && !orderColumn.isEmpty() && !orderColumn.equals("null")){
            map.put("orderColumn",orderColumn);
        }else {
            map.put("orderColumn", "creationDate");
        }

        if(orderType==true){
            map.put("orderType","desc");
        }else {
            map.put("orderType","asc");
        }

        billList = myService.getAllBill(map);

        //返回前端
        if(billList != null &&!billList.isEmpty()){
            model.addAttribute("billLists", billList);
        }else {
            model.addAttribute("error","未找到");
        }
        model.addAttribute("currentPage", currentPage);
        model.addAttribute("totalPage", totalPage);
        model.addAttribute("queryParam",queryParam);

        if(orderColumn != null &&!orderColumn.isEmpty()){
            model.addAttribute("orderColumn",orderColumn);
        }else {
            model.addAttribute("orderColumn", "creationDate");
        }
        model.addAttribute("orderType",orderType);


        return "list/billList";
    }

    private String str2 = "^[0-9]*$";
    //跳转页面
    @RequestMapping("/jumpBill")
    public String jumpBill(String queryParam,String orderColumn,boolean orderType,String num,Model model){


        if(num.matches(str2)){
            return toBillList(queryParam,orderColumn,orderType,Integer.parseInt(num),model);
        }else {
            model.addAttribute("errorJump","错误页面");
            return toBillList(queryParam,orderColumn,orderType,1,model);
        }

    }

三、其他功能

1.添加视图解析器

方便管理,在config包下建立一个类继承WebMvcConfigurer,重写addViewControllers方法

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    }
}

2.首页实现

springboot会自动扫描templates下的index

3. 拦截器

拦截一些请求,登录之后可访问 在config包下,建一个类继承HandlerInterceptor,重写preHandle方法

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //登录之后在session中存入"afterLogin",看"afterLogin"是否为空,来判断是否登录
        Object afterLogin = request.getSession().getAttribute("afterLogin");

        if(afterLogin == null){

            request.setAttribute("msg","请先登录");
            request.getRequestDispatcher("/tologin").forward(request,response);
            return false;
        }
        return true;
    }

}
//将Interceptor加到config
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/","/index.html","/tologin","/login","/toEnroll","enroll","/css/**","/js/**","/img/**");
        registry.addInterceptor(new RoleInterceptor()).addPathPatterns("/other");
    }

}

4.权限控制

//查询数据库中用户的权限等级,显示对应的页面,和访问拦截
public class RoleInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Integer userRole = (Integer) request.getSession().getAttribute("userRole");
        if(userRole < 20){
            request.setAttribute("msg","请充值来获得更多服务");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }
        return true;
    }

}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/","/index.html","/tologin","/login","/toEnroll","enroll","/css/**","/js/**","/img/**");
        registry.addInterceptor(new RoleInterceptor()).addPathPatterns("/other");
    }

}

5.登录功能实现

前端

index.html            
            <!--用session来判断用户是否登录-->
            <!--未登录显示登录,已登录显示用户昵称-->
            <div th:if="${#strings.isEmpty(session.afterLogin)}">
                <a class="nav-link" href="/tologin">登录</a>
            </div>

            <div th:if="${not #strings.isEmpty(session.afterLogin)}">
                <a class="nav-link" href="/tohome">[[${session.afterLogin}]]</a>
            </div>

login.html
	<body class="text-center">
		<form class="form-signin" action="/login">
			<img class="mb-4" src="/img/bootstrap-solid.svg" alt="" width="72" height="72">
			<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
			<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
			
			<input type="text" name="userCode" class="form-control" placeholder="Username" required="" autofocus="">
			
			<input type="password" name="password" class="form-control" placeholder="Password" required="">

			<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
			<a class="btn btn-lg btn-primary btn-block nav-link" href="/toEnroll">注册</a>
		</form>

	</body>

mapper

    //所有用户名列表
    List<String> getCodeList();
    //根据姓名查密码
    String getPwdByCode(String userCode);
    //查询用户的全部信息
    User getUser(String userCode);

mapper.xml

    <select id="getCodeList" resultType="String">
        select userCode
        from smbms.smbms_user
    </select>
    <select id="getPwdByCode" parameterType="String" resultType="String">
        select userPassword
        from smbms.smbms_user
        where userCode = #{userCode}
    </select>
    <select id="getUser" parameterType="String" resultType="user">
        select * from smbms.smbms_user where userCode=#{userCode}
    </select>

controller

    @RequestMapping("/tologin")
    public String tologin(){
        return "login";
    }


    @RequestMapping("/login")
    public String login(@RequestParam("userCode") String userCode,
                        @RequestParam("password") String password,
                        Model model, HttpSession session){
        List<String> codeList = myService.getCodeList();
        User currentUser = myService.getUser(userCode);

        String pwd = currentUser.getUserPassword();
        Integer userRole = currentUser.getUserRole();
//在数据库中查询所有用户名,看有没有用户输入的
        if(codeList.contains(userCode)){
//有该用户在判断密码
            if(pwd.equals(password)){
//验证成功在session存值
                String userName = currentUser.getUserName();
                session.setAttribute("afterLogin",userName);
                session.setAttribute("uid",userCode);
                session.setAttribute("userRole",userRole);
                return "redirect:/index.html";
            }else{
                model.addAttribute("msg","密码错误");//真实情况应该不显示密码错误
                return "login";
            }
        }else{
            model.addAttribute("msg","用户名错误");
            return "login";
        }
    }

6.注册功能实现

前端

enroll.html
<form class="form-signin" action="/enroll">
    <img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal">注册用户</h1>

    <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

    <input type="text" name="userCode" class="form-control" placeholder="用户名" required="" autofocus="">

    <input type="password" name="fPassword" class="form-control" placeholder="密码" required="">

    <input type="password" name="sPassword" class="form-control" placeholder="确认密码" required="">

    <button class="btn btn-lg btn-primary btn-block" type="submit">注册</button>

</form>

mapper

     int addUser(Map<String,String> map);

mapper.xml

    <insert id="addUser" parameterType="map">
        insert into smbms.smbms_user (userCode,userPassword) values (#{userCode},#{userPassword})
    </insert>

controller

    @RequestMapping("/toEnroll")
    public String toEnroll(){

        return "enroll";
    }

    //正则表达式,必须有字母和数字
    private String str1 = "^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]{1,})$";
    @RequestMapping("/enroll")
    public String enroll(@RequestParam("userCode") String userCode,
                         @RequestParam("fPassword") String fPassword,
                         @RequestParam("sPassword") String sPassword,
                         Model model){

        List<String> codeList = myService.getCodeList();

        //设置用户名为唯一标识
        if(codeList.contains(userCode)){
            model.addAttribute("msg","用户名已被注册");
            return "enroll";
        }else {
            if(fPassword.matches(str1)){

                if(fPassword.length() >= 8){

                    if(fPassword.equals(sPassword)){

                        Map<String, String> map = new HashMap<>();
                        map.put("userCode",userCode);
                        map.put("userPassword",fPassword);
                        myService.addUser(map);

                        model.addAttribute("msg","注册成功");
                        return "login";
                    }else{
                        model.addAttribute("msg","两次密码不一致");
                        return "enroll";
                    }
                }else{
                    model.addAttribute("msg","密码不能少于八位");
                    return "enroll";
                }
            }else{
                model.addAttribute("msg","密码必须由字母和数字组成,不能包含特殊字符");
                return "enroll";
            }
        }

    }

7.注销

   //清空session即注销
    @RequestMapping("/logout")
    public String logout(HttpSession session){

        session.invalidate();
        return "redirect:/index.html";
    }

8.404,500

在templates下建error包,写404.html