前言
- 本博客将介绍基于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() %>
<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等操作,我在其他博客中都有讲,可以参考:
这里主要演示项目的运行结果:
项目启动成功后,在浏览器的地址栏输入localhost:8080/vote.html
任意点击一个选项并提交,会直接跳转到统计结果:
在VoteServlet类中的这个位置修改跳转的统计页面:
使用voteResult.jsp作为跳转页面:
使用voteResultNew.jsp作为跳转页面:
总结
标签:投票系统,return,MVC,new,vote,import,设计模式,public,conn From: https://blog.csdn.net/weixin_52937170/article/details/142219424编写步骤:
1.创建视图:(voteResult.jsp)
2.创建控制器:VoteServlet.java
3.创建模型: service:业务层 dao:数据层