首页 > 其他分享 >MVC项目实战-基于JSP的MVC设计模式实现投票系统

MVC项目实战-基于JSP的MVC设计模式实现投票系统

时间:2024-09-15 09:23:07浏览次数:3  
标签:投票系统 return MVC new vote import 设计模式 public conn

前言

  • 本博客将介绍基于JSP的MVC设计模式实现投票系统,实现两个功能:
    • 功能一:投票
    • 功能二:查看投票结果

 第一步:设计数据库,创建JavaWeb项目,配置pom.xml文件,创建实体类

数据库:

  •  数据库中的t_vote包含三个字段:id,v_name,v_num
    • id:主键,一行数据的唯一标识
    • v_name:参与投票的对象名

    • v_num:被投票数

表设计如下:

 实体类:

package entity;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class Vote implements Serializable {
    private Integer id;
    private String vName;
    private Integer vNum;

    public void setId(Integer id) {
       this. id = id;
    }
    public void setvName(String vName){
        this.vName=vName;
    }
    public void setvNum(Integer vNum){
        this.vNum=vNum;
    }
}

注意:这里的getter系列方法和有参/无参构造方法都可以由注解生成,但是setter方法一定需要手写出来,因为我使用了JDBCTemplate中的query查询方法中的

new BeanPropertyRowMapper() 进行查询操作

这个接口实现类,底层是通过反射和无参构造创建对象,并通过调用对应的setter方法给我们的Java对象的属性进行赋值的,而我们通过lombok注解生成的setter系列方法的方法名与数据库中的字段没有形成小驼峰映射关系,导致底层代码无法帮我们进行赋值,进而导致我们实体类创建的对象存储的数据都为null

简而言之:需要手写setter方法

创建JavaWeb项目,配置pom.xml:

项目结构:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>toupiao_9_12_zuoye</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>toupiao_9_12_zuoye Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!--MySQL数据库连接驱动jar包-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.28</version>
    </dependency>
    <!-- servlet依赖支持-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!--JDBCTemplate依赖支持,因为JDBCTemplate是Spring框架封装的一个工具类,因此需要导入Spring相关依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.3.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.8.RELEASE</version>
    </dependency>
  <!--lombok依赖-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.22</version> <!-- 请替换为实际想要使用的版本号 -->
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <!--配置项目名 -->
    <finalName>web</finalName>
    <plugins>
<!--      设置Maven项目的语言级别为jdk11版本-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>8</source>
          <target>8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <!--配置jetty服务器插件支持-->
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.3.14.v20161028</version>
      </plugin>
      <!--配置tomcat服务器插件支持-->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
          <server>tomcat7</server>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

第二步:导入JDBC工具类和数据库连接配置文件

JDBCUtils:

package utils;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtils {
    private static DataSource dataSource =null;

    static{
        try (
                InputStream is=JDBCUtils.class.getResourceAsStream("/jdbc.properties")
        ){
            Properties p = new Properties();
            p.load(is);
            dataSource = new DriverManagerDataSource(p.getProperty("url"), p.getProperty("username"), p.getProperty("password"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static JdbcTemplate getJDBCTemplate(){
        //创建JDBCTemplate对象并传入数据库连接池
        JdbcTemplate template = new JdbcTemplate(dataSource);
        return template;
    }

    /**
     * 获取数据库连接池
     * @return
     */
    public static DataSource getDataSource(){
        return dataSource;
    }

    /**
     * 开始线程绑定 +获取连接
     * @return
     */
    public static Connection startTransaction(){
        if (!TransactionSynchronizationManager.isSynchronizationActive()){
            TransactionSynchronizationManager.initSynchronization();
        }
        Connection connection =DataSourceUtils.getConnection(dataSource);
        try {
            connection.setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return connection;
    }

    /**
     * 提交事务
     * @param conn
     */
    public static void commit(Connection conn){
        try {
            conn.commit();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            clear(conn);
        }
    }

    /**
     * 回滚事务
     * @param conn
     */
    public static void rollback(Connection conn){
        try {
            conn.rollback();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            clear(conn);
        }
    }


    /**
     * 解除线程绑定+释放资源+归还连接到线程池
     * @param conn
     */
    public static void clear(Connection conn){
        //清除线程绑定的资源
        TransactionSynchronizationManager.clear();
        TransactionSynchronizationManager.unbindResourceIfPossible(dataSource);
        //归还数据库连接至连接池
        if (conn!=null){//非空判断,判断为空再归还
            DataSourceUtils.releaseConnection(conn,dataSource);
        }
    }

}

jdbc.properties :

url=jdbc:mysql://localhost:3306/csx_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=Asia/shanghai
username=root
password=root

第三步:书写DAO,提供SQL支持

VoteDao:

package dao;

import entity.Vote;

import java.util.List;

public interface VoteDao {

    /**
     * 修改投票数据
     * @param vote
     * @return
     */
    public int updateVote(Vote vote);

    /**
     * 查询所有投票信息
     * @return
     */
    public List<Vote> selectVotes();


}

VoteDaoImpl: 

package dao.impl;

import dao.VoteDao;
import entity.Vote;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import utils.JDBCUtils;

import java.util.List;

public class VoteDaoImpl implements VoteDao {
    private JdbcTemplate template= JDBCUtils.getJDBCTemplate();
    /**
     * 修改投票数据
     *
     * @param vote
     * @return
     */
    @Override
    public int updateVote(Vote vote) {
       String sql="update t_vote set v_num=v_num+1 where v_name=?";
        int n = template.update(sql, vote.getVName());
        return n;
    }

    /**
     * 查询所有投票信息
     *
     * @return
     */
    @Override
    public List<Vote> selectVotes() {
        String sql ="select * from t_vote";
        List<Vote> query = template.query(sql, new BeanPropertyRowMapper<>(Vote.class));

        return query;

    }
}

 第四步:书写Service,调用DAO的SQL支持完成业务功能(投票和统计)

VoteService:

package service;

import entity.Vote;

import java.util.List;

public interface VoteService {
    /**
     * 修改投票
     * @return
     */
    public boolean changeVote(String vName);


    public List<Vote> queryVotes();

}

VoteServiceImpl:

package service.impl;

import dao.VoteDao;
import dao.impl.VoteDaoImpl;
import entity.Vote;
import service.VoteService;
import utils.JDBCUtils;

import java.sql.Connection;
import java.util.List;

public class VoteServiceImpl implements VoteService {
    private VoteDao voteDao =new VoteDaoImpl();
    /**
     * 修改投票
     *
     * @return
     */
    @Override
    public boolean changeVote(String vName) {
        boolean boo =false;
        Connection conn =null;
        try{
            conn = JDBCUtils.startTransaction();
            Vote vote =new Vote(null,vName,null);
            int i = voteDao.updateVote(vote);
            if (i==1){
                boo=true;
            }else {
                throw new RuntimeException("投票失败!");
            }
            JDBCUtils.commit(conn);
        }catch (Exception e){
            JDBCUtils.rollback(conn);
            throw  new RuntimeException(e);
        }
        return boo;
}


    @Override
    public List<Vote> queryVotes() {
        return voteDao.selectVotes();
    }
}

第五步:书写Servlet,接收页面请求,并跳转到统计页面

VoteServlet:

package servlet;

import entity.Vote;
import service.VoteService;
import service.impl.VoteServiceImpl;

import javax.servlet.ServletException;
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.util.List;

@WebServlet("/vote")
public class VoteServlet extends HttpServlet {
    private VoteService voteService =new VoteServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String []techInterest = request.getParameterValues("techInterest");

        try {
            for (String i:techInterest){
                switch (i){
                    case "Java":
                        voteService.changeVote("Java");
                        break;
                    case ".NET":
                        voteService.changeVote(".NET");
                        break;
                    case "Android" :
                        voteService.changeVote("Android");
                        break;
                    case "PHP":
                        voteService.changeVote("PHP");
                        break;
                }
            }
            List<Vote> votes = voteService.queryVotes();
           System.out.println(votes);
            request.setAttribute("list",votes);
            request.getRequestDispatcher("voteResultNew.jsp").forward(request,response);
//            response.sendRedirect("vote_success.html");
        } catch (IOException e) {
            response.sendRedirect("vote_failed.html");
            throw new RuntimeException(e);
        }
    }
}

webapp结构

分析:

index.jsp:是默认首页,创建javaweb项目时自动创建的,不是我们关注的重点

vote.html:进行投票的页面,也是进行数据传递的重要页面

vote_failed.html:失败页面,不包括任何代码,就是演示一下如何跳转

vote_success.html:成功页面,不包括任何代码,就是演示一下如何跳转

voteResult.jsp:统计投票结果的页面,是投票之后要跳转进的页面

voteResult.jsp:统计投票结果页面,使用了echarts进行了页面美化

红色是我们必须使用的页面和jsp

 web.xml:

<?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_3_1.xsd"
         version="3.1">
  <!-- 配置内容 -->
</web-app>

vote.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>技术兴趣投票</title>
</head>
<body>
<h2>技术兴趣投票</h2>
<form action="/vote" method="post">
    <p>请选择您最感兴趣的技术:</p>

    <!-- Java 单选按钮 -->
    <input type="radio" id="java" name="techInterest" value="Java">
    <label for="java">Java</label><br>

    <!-- .NET 单选按钮 -->
    <input type="radio" id="dotnet" name="techInterest" value=".NET">
    <label for="dotnet">.NET</label><br>

    <!-- Android 单选按钮 -->
    <input type="radio" id="android" name="techInterest" value="Android">
    <label for="android">Android</label><br>

    <!-- PHP 单选按钮 -->
    <input type="radio" id="php" name="techInterest" value="PHP">
    <label for="php">PHP</label><br>

    <!-- 提交按钮 -->
    <input type="submit" value="提交">
</form>
</body>
</html>

voteResult.jsp:

<%@ page import="entity.Vote" %>
<%@ page import="java.util.List" %>
<%--
  Created by IntelliJ IDEA.
  User: 21038
  Date: 2024/9/13
  Time: 14:04
  To change this template use File | Settings | File Templates.
--%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    List<Vote> list=(List<Vote>) request.getAttribute("list");
//    System.out.println(list);
    for(Vote v:list){
%>
<%=v.getVName() %> &nbsp;&nbsp;
<p><div style="display: inline-block; background-color: red; width:<%=v.getVNum() %>px;height: 20px;"></div></p>
<%} %>
</body>
</html>

voteResultNew.jsp:

<%@ page import="entity.Vote" %>
<%@ page import="java.util.List" %><%--
  Created by IntelliJ IDEA.
  User: 21038
  Date: 2024/9/13
  Time: 16:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="entity.Vote" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<script src="https://cdn.staticfile.net/echarts/4.7.0/echarts.js"></script>
<script src="https://cdn.staticfile.net/vue/2.2.2/vue.min.js"></script>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));


    var arr=[];
    <%
     List<Vote> list=(List<Vote>) request.getAttribute("list");
     for(Vote v:list){
 %>
    arr.push(<%=v.getVNum() %>)
    <%} %>
    var option = {
        title: {
            text: '最受欢迎技术投票结果'
        },
        tooltip: {},
        legend: {
            data: ['人数']
        },
        xAxis: {
            data: ['Java', '.NET', 'Android', 'PHP']
        },
        yAxis: {},
        series: [
            {
                name: '人数',
                type: 'bar',
                data: arr
            }
        ]
    };

    // 使用刚指定的配置项和数据显示图表。
     myChart.setOption(option);
</script>
</body>
</html>

第六步:运行测试

如何启动一个JavaWeb项目,和运行tomcat等操作,我在其他博客中都有讲,可以参考:

JavaWeb项目启动

tomcat部署和启动

这里主要演示项目的运行结果:

项目启动成功后,在浏览器的地址栏输入localhost:8080/vote.html

任意点击一个选项并提交,会直接跳转到统计结果:

在VoteServlet类中的这个位置修改跳转的统计页面:

使用voteResult.jsp作为跳转页面:

 

使用voteResultNew.jsp作为跳转页面:

 总结

编写步骤:

1.创建视图:(voteResult.jsp)

2.创建控制器:VoteServlet.java

3.创建模型: service:业务层 dao:数据层

标签:投票系统,return,MVC,new,vote,import,设计模式,public,conn
From: https://blog.csdn.net/weixin_52937170/article/details/142219424

相关文章

  • MVCC与锁
    MVCC与锁锁基本原理当事务想要改动记录时,会查看内存中有没有跟该记录相关联的锁结构没有的话就生成一个is_waiting为false的锁结构与之关联,代表获取锁成功;如果发现该记录已经有锁关联了,会生成一个is_waiting为true的锁结构,代表获取锁失败,进入等待状态;如果加锁的事务结束,将释......
  • 读书笔记:Head First 设计模式
    HeadFirst设计模式EricFreemanPDF下载(亲测有效):https://baijiahao.baidu.com/s?id=1756899911272841212&wfr=spider&for=pc前言如何使用本书一些HeadFirst学习原则:可视化。图片更容易让人记住,文字放图片里使用会话式和个人化风格。会话式讲述内容。让学习者想得更深引......
  • 学习记录:设计模式
    设计模式(DesignPattern):        是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。设计模式的分类:常见的GOF种设计模式:        单例(Singleton)模式:......
  • SpringMvc 完整上传文件流程(Ajax请求)头像,图片上传
    1、config包下的操作1.1、创建MyWebApplicationInit类如何创建第一个SpringMvc步骤以配置类的形式代替xml文件(点击链接查看)1.2、设置文件大小(自定义)1.3、创建SpringMvcConfig类并实现WebMvcConfigurer接口@EnableWebMvcpublicclassSpringMvcConfigimplementsWeb......
  • 设计模式——工厂模式
    工厂模式1简单工厂模式1.1需求用例看一个披萨的项目:要便于披萨种类的扩展,要便于维护披萨的种类很多(比如GreekPizz、CheesePizz等)披萨的制作有prepare,bake,cut,box完成披萨店订购功能。1.2使用传统的方式来完成类图分析publicOrderPizza(){ Pizzapizza=......
  • Spring,SpringBoot,SpringMvc
    1.Spring是什么?有什么特性?有哪些模块?常用注解?1.1Spring是什么?   一句话概况的话:Spring是一个轻量级,非入侵式的控制反转(IOC)和面向切面(AOP)的框架1.2有什么特性?    Spring特性:        1.AOP编程的支持    Spring提供了面向切面......
  • 学习高校课程-软件设计模式-软件设计原则(lec2)
    FeatureofGoodDesign(1)优秀设计的特点(一)Codereuse代码复用–Challenge:tightcouplingbetweencomponents,dependenciesonconcreteclassesinsteadofinterfaces,hardcodedoperations–Solution:designpatterns–挑战:组件之间的紧密耦合、对具体类而不......
  • Java设计模式之命令模式介绍和案例示范
    一、命令模式简介命令模式(CommandPattern)是一种行为型设计模式,它将请求封装为一个对象,从而使你可以用不同的请求对客户端进行参数化、对请求排队或记录日志,以及支持可撤销的操作。命令模式的核心思想是将发出请求的对象与执行请求的对象分离,从而解耦请求的调用与处理逻辑......
  • 学习高校课程-软件设计模式-OOP 和 UML 类图 OOP 与 Java(lec1)
    Lecture1:OOPandUMLClassDiagramsOOPwithJavaOOP和UML类图OOP与JavaObject-OrientedProgramming面向对象编程ClassHierarchies类层次结构Superclassandsubclass超类和子类PillarsofObject-OrientedProgramming面向对象编程的支柱Abstraction–M......
  • 《程序猿之设计模式实战 · 装饰者模式》
    ......