Java(SSM整合)
0. 项目描述
- 本项目用作练手,是一个极简小项目。
- 主要实现了一个学生信息的增删改查管理功能。
- 数据库表字段:学生编号,学生姓名,学生性别,学生年龄。
- 主要有:
- 两个页面:
- 学生信息列表管理界面(另外扩充了一个使用分页插件的页面) 。
- 学生信息新增界面。
- 三个按钮:
- 查询按钮(ByName、模糊查询)
- 删除按钮
- 新增按钮(暂 未实现 学生编号唯一性校验,会直接报500错误)
- 跳转按钮(扩充):分页与普通页面之间跳转,以及分页版独有的按钮。
- 两个页面:
- 大框架基于SSM
1. 环境搭建(工具部分)
- 从零开始搭建的大概思路
1.1 Java环境:JDK
- 官网下载JDK,本人使用JDK1.8.0_301,默认下载在C盘。
- 配置环境变量
- 过程略
- 参考:https://blog.csdn.net/Zachsj/article/details/111574311
1.2 数据库环境:MySQL
- 官网下载,本人改使用2022年最新版本,8.0.29。下载在H:\Environment中。
- 配置环境变量
- 过程略
- 参考1(版本5+):https://blog.csdn.net/Zachsj/article/details/124524086
- 参考2(版本8+):https://blog.csdn.net/Zachsj/article/details/125722788
1.3 IDEA工具
- 官网下载最新版试用,或者购买,白嫖方法不能提供(自查)。
- 网上找优化配置方法,主要是4个UTF-8,其它的看喜好。(全局,项目,配置文件,最后尤其是Console的编码)。
1.4 Maven
- 官网下载,本人版本3.6.1可用,下载到H:\Environment中
- 配置环境变量等
- 过程略
- 参考:https://blog.csdn.net/Zachsj/article/details/124830278
1.5 Tomcat
- 官网下载,本人版本2022年最新9.0.64可用,下载到H:\Environment中
- H:\Environment\apache-tomcat-9.0.64\conf的logging.properties文件里,最后有5个UTF-8,把第一个和第二个改成GBK,解决tomcat乱码问题。另外,配置Tomcat时,VM options填入
-Dfile.encoding=utf-8
,解决server的乱码,同时需要IDEA全部配置(大概有4个)为UTF-8。(全局,项目,配置文件,最后尤其是Console的编码)。 - 过程略
- 参考:https://blog.csdn.net/Zachsj/article/details/124830278
2. 环境搭建(代码部分)
2.1 数据库脚本
- 数据库脚本:
/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 8.0.29 : Database - studentinfo
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`studentinfo` /*!40100 DEFAULT CHARACTER SET utf8mb3 */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `studentinfo`;
/*Table structure for table `student` */
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`studentId` int NOT NULL AUTO_INCREMENT COMMENT '学生编号',
`studentName` varchar(20) NOT NULL COMMENT '学生姓名',
`studentSex` varchar(2) NOT NULL COMMENT '学生性别',
`studentAge` int NOT NULL COMMENT '学生年龄',
PRIMARY KEY (`studentId`)
) ENGINE=InnoDB AUTO_INCREMENT=2016022325 DEFAULT CHARSET=utf8mb3;
/*Data for the table `student` */
insert into `student`(`studentId`,`studentName`,`studentSex`,`studentAge`) values
(1883022318,'乌丸莲耶','男',140),
(1971022318,'阿笠博士','男',52),
(1974022318,'木之下芙纱绘','女',49),
(1986022318,'工藤优作','男',37),
(1986022319,'工藤有希子','女',37),
(1986022320,'毛利小五郎','男',37),
(1986022321,'妃英理','女',37),
(1995022318,'佐藤美和子','女',28),
(1997022318,'高木涉','男',26),
(2006022318,'工藤新一','男',17),
(2006022319,'宫野志保','女',18),
(2006022320,'毛利兰','女',17),
(2006022321,'铃木园子','女',17),
(2006022322,'世良真纯','女',17),
(2006022323,'京极真','男',17),
(2006022324,'服部平次','男',17),
(2006022325,'远山和叶','女',17),
(2006022326,'黑羽快斗','男',17),
(2006022327,'中森青子','女',17),
(2006022328,'工藤兰','女',17),
(2016022318,'江户川柯南','男',7),
(2016022319,'灰原哀','女',8),
(2016022320,'吉田步美','女',7),
(2016022321,'圆谷光彦','男',7),
(2016022322,'小岛元太','男',7),
(2016022323,'工藤哀','女',8),
(2016022324,'工藤静香','女',7);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
2.2 创建项目以及pom.xml
- 创建普通maven项目,SSM-StudentInfo-Ultimate
- 先添加web支持,再用IDEA连一下数据库(不连接也行)。
- 始终注意SSM-StudentInfo-Ultimate.iml,IDEA的配置文件,始终!!!注意Component是否多了一段!!!
- SSM-StudentInfo-Ultimate.iml(正常是这样的!!!就可以了)
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="web" name="Web">
<configuration>
<descriptors>
<deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/web/WEB-INF/web.xml" />
</descriptors>
<webroots>
<root url="file://$MODULE_DIR$/web" relative="/" />
</webroots>
<sourceRoots>
<root url="file://$MODULE_DIR$/src/main/java" />
<root url="file://$MODULE_DIR$/src/main/resources" />
</sourceRoots>
</configuration>
</facet>
</component>
</module>
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zach</groupId>
<artifactId>SSM-StudentInfo-Ultimate</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--依赖:junit、数据库驱动、数据库连接池、
servlet、jsp、jstl、
mybatis、mybatis-spring、spring、
lombok、pagehelper-->
<dependencies>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- 数据库连接池:c3p0、dbcp-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<!--servlet、jsp、jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<!--lombok自动生成setter、getter方法等-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!--pagehelper分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
<!--解决静态资源导出问题-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2.3 添加web支持以及web.xml
- 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_4_0.xsd"
version="4.0">
<!--Spring的乱码过滤:encodingFilter-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--这里加载的是总的配置文件:只要它可以(autodetected)就可以了-->
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--session:过期时间:15min-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
2.4 逐渐搭建项目结构
2.5 配置文件
- mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--Mybatis自带的日志输出接口-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--配置数据源,交给Spring去做-->
<typeAliases>
<!--<package name="com.zach.pojo"/>-->
<!--日志的Reader entry有乱码问题且暂时无法解决,但可以用下面的方式直接不生成Reader entry...-->
<typeAlias type="com.zach.pojo.Student" alias="Student"/>
</typeAliases>
<mappers>
<mapper class="com.zach.dao.StudentMapper"/>
</mappers>
</configuration>
- database.properties
# 如果是MySQL5.x 需要去掉下面这个.cj
jdbc.driver=com.mysql.cj.jdbc.Driver
# 如果是MySQL8.x 需要增加一个时区的配置 &serverTimezone=Asia/shanghai (有时不加亦无事)
# useSSL=false 个人一般都是false,特殊情况有可能=true
jdbc.url=jdbc:mysql://localhost:3306/studentinfo?useSSL=false&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--只要这个applicationContext.xml能(autodetected)就可以了,因为其它三个导入到这里了。-->
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
- spring-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1. 关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/>
<!--2. 配置数据库连接池
dbcp:半自动化操作,不能自动连接
c3p0:自动化操作,自动化的加载配置文件,并且可以自动设置到对象中
druid:
hikari:-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false"/>
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000"/>
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--3. 配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置MyBatis全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--配置pagehelper分页插件-->
<property name="plugins">
<array>
<!--传入插件的对象-->
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<prop key="helperDialect">mysql</prop>
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
<!--4. 配置扫描Dao接口包,动态实现Dao接口注入到spring容器中-->
<!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.zach.dao"/>
</bean>
</beans>
- spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1. 注解驱动-->
<mvc:annotation-driven/>
<!--2. 静态资源过滤-->
<mvc:default-servlet-handler/>
<!--3. 扫描包:controller-->
<context:component-scan base-package="com.zach.controller"/>
<!--4. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- spring-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1. 扫描service相关的bean -->
<context:component-scan base-package="com.zach.service" />
<!--2. 将我们的所有业务类,(StudentServiceImpl)注入到IOC容器中,使之可以通过配置或注解实现-->
<bean id="studentServiceImpl" class="com.zach.service.StudentServiceImpl">
<property name="studentMapper" ref="studentMapper"/>
</bean>
<!--3. 配置事务管理器(声明式事务) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--4. aop事务支持!(aop切面编程)(暂无)-->
</beans>
3. Java代码
- Student
package com.zach.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author : Zach
* @date : 2022-07-14 22:07
* @description : TODO
* @modified by : Zach
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int studentId; //学生编号,在数据库中会自动按照数据大小默认排序,下次试试String...
private String studentName; //学生姓名
private String studentSex; //学生性别,最多两个中文。
private int studentAge; //学生年龄,在数据库中设置长度3,但是可以很长...
}
- StudentMapper
package com.zach.dao;
import com.zach.pojo.Student;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author : Zach
* @date : 2022-07-14 22:07
* @description : TODO
* @modified by : Zach
*/
public interface StudentMapper {
//增加一个学生
int addStudent(Student student);
//删除一个学生(byId)
int deleteStudentById(@Param("studentId") int id);
//更新一个学生
int updateStudent(Student student);
//查询一个学生(byId)
Student queryStudentById(@Param("studentId") int id);
//查询学生(byName)
List<Student> queryStudentByName(@Param("studentName") String studentName);
//查询所有学生
List<Student> queryAllStudents();
//查询一共有几个学生
int countStudents();
}
- StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zach.dao.StudentMapper">
<!--增加一个学生-->
<!--参数类型首字母应该用小写,但是大写也可以-->
<insert id="addStudent" parameterType="Student">
insert into studentinfo.student (studentId,studentName,studentSex,studentAge)
values (#{studentId},#{studentName},#{studentSex},#{studentAge});
</insert>
<!--删除一个学生(ById)-->
<!--参数类型例如int应该写成_int,int是包装类,但是包装类可以自动装箱和自动拆箱,无所谓-->
<delete id="deleteStudentById" parameterType="int">
delete
from studentinfo.student
where studentId = #{studentId};
</delete>
<!--更新一个学生-->
<update id="updateStudent" parameterType="Student">
update studentinfo.student
set studentId=#{studentId},studentName=#{studentName},studentSex=#{studentSex},studentAge=#{studentAge}
where studentId=#{studentId};
</update>
<!--查询一个学生(byId)-->
<select id="queryStudentById" resultType="Student" parameterType="int">
select *
from studentinfo.student
where studentId=#{studentId};
</select>
<!--查询学生(byName)-->
<select id="queryStudentByName" resultType="Student" parameterType="String">
select *
from studentinfo.student
where studentName like concat('%',#{studentName},'%')
</select>
<!--查询所有学生-->
<select id="queryAllStudents" resultType="Student">
select *
from studentinfo.student
</select>
<!--查询一共有几个学生-->
<select id="countStudents" resultType="int">
select count(studentId)
from studentinfo.student;
</select>
</mapper>
- StudentService
package com.zach.service;
import com.zach.pojo.Student;
import java.util.List;
/**
* @author : Zach
* @date : 2022-07-14 22:07
* @description : TODO
* @modified by : Zach
*/
public interface StudentService {
//虽然int类型的返回值没有用到,但是以后可能有用,不用改成void类型!(报黄就报黄吧...)
//增加一个学生
int addStudent(Student student);
//删除一个学生(ById)
int deleteStudentById(int id);
//更新一个学生
int updateStudent(Student student);
//查询一个学生(byId)
Student queryStudentById(int id);
//查询学生(byName)
List<Student> queryStudentByName(String studentName);
//查询所有学生
List<Student> queryAllStudents();
//查询一共有几个学生
int countStudents();
}
- StudentServiceImpl
package com.zach.service;
import com.zach.dao.StudentMapper;
import com.zach.pojo.Student;
import java.util.List;
/**
* @author : Zach
* @date : 2022-07-14 22:07
* @description : TODO
* @modified by : Zach
*/
public class StudentServiceImpl implements StudentService{
//service层调dao层:组合Dao
//调用dao层的操作,设置一个set接口,方便Spring管理。(set注入)
private StudentMapper studentMapper;
public void setStudentMapper(StudentMapper studentMapper) {
this.studentMapper = studentMapper;
}
@Override
public int addStudent(Student student) {
return studentMapper.addStudent(student);
}
@Override
public int deleteStudentById(int id) {
return studentMapper.deleteStudentById(id);
}
@Override
public int updateStudent(Student student) {
return studentMapper.updateStudent(student);
}
@Override
public Student queryStudentById(int id) {
return studentMapper.queryStudentById(id);
}
@Override
public List<Student> queryStudentByName(String studentName) {
return studentMapper.queryStudentByName(studentName);
}
@Override
public List<Student> queryAllStudents() {
return studentMapper.queryAllStudents();
}
@Override
public int countStudents() {
return studentMapper.countStudents();
}
}
- StudentController
package com.zach.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zach.pojo.Student;
import com.zach.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author : Zach
* @date : 2022-07-14 22:07
* @description : TODO
* @modified by : Zach
*/
@Controller
@RequestMapping("/student")
public class StudentController {
//controller 调 service层
//自动注入: 灵活,启动快。但不可靠,低可维护性,可测试性差,循环关系不检测。
//构造器注入:不灵活,启动慢。但可靠,高可维护性,可测试性好,循环关系自动监测。
//set注入:与自动注入基本相同。但可测试性好。(此处就使用set注入了)
//@Autowired //会有黄色下划波浪线:IDEA不推荐
@Qualifier("studentServiceImpl")
private StudentService studentService;
@Autowired
public void setStudentService(StudentService studentService) {
this.studentService = studentService;
}
//跳转到:管理学生的页面,但先查询全部学生(不使用分页插件)
@RequestMapping("/manageStudentPage")
public String manageStudentPage(Model model){
List<Student> studentList = studentService.queryAllStudents();
model.addAttribute("studentList",studentList);
return "manageStudentPage";
}
//跳转到:管理学生的页面,但先查询全部学生(但使用分页插件)
@RequestMapping("/manageStudentPageLimited")
public String manageStudentPageLimited(Model model,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "5") int size){
PageHelper.startPage(page,size);//必须写在第一行才会只返回5个数据。
List<Student> studentList = studentService.queryAllStudents();
PageInfo<Student> studentPageInfo = new PageInfo<>(studentList);
model.addAttribute("studentList",studentPageInfo);
return "manageStudentPageLimited";
}
//跳转到:新增学生的页面
@RequestMapping("/addStudentPage")
public String addStudentPage(){
return "addStudentPage";
}
//新增学生的请求
@RequestMapping("/addStudent")
public String addStudent(Student Student){
studentService.addStudent(Student);
return "redirect:/student/manageStudentPageLimited";//新增学生后重定向
}
//跳转到:修改学生信息的页面
@RequestMapping("/updateStudentPage")
public String updateStudentPage(Model model,int id){
Student student = studentService.queryStudentById(id);
model.addAttribute("studentInfo", student);
return "updateStudentPage";
}
//修改学生信息的请求
@RequestMapping("/updateStudent")
public String updateStudent(Student student){
studentService.updateStudent(student);
return "redirect:/student/manageStudentPageLimited";//修改学生后重定向
}
//删除学生的请求
@RequestMapping("/deleteStudent/{studentId}")
public String deleteStudent(@PathVariable("studentId") int id){
studentService.deleteStudentById(id);
return "redirect:/student/manageStudentPageLimited";//删除学生后重定向
}
//查询学生信息的请求(ByName)
@RequestMapping("/queryStudentByName")
public String queryStudentByName(Model model, String studentName){
List<Student> studentList = studentService.queryStudentByName(studentName);
int count = studentService.countStudents();//查询一共有几个学生
if (studentList.size()==0){//列表长度=0,确实没查到,而不是查空
studentList = studentService.queryAllStudents();
model.addAttribute("msg", "未查到");
}else if (studentList.size()==count){//列表长度=所有学生数,说明其实是查了空值。
studentList = studentService.queryAllStudents();
model.addAttribute("msg", "请输入");
}
model.addAttribute("studentList",studentList);
return "manageStudentPage";//查询学生后返回,而不是重定向
}
//查询学生信息的请求(ByNameByLimited)
@RequestMapping("/queryStudentByNameByLimited")
public String queryStudentByNameByLimited(Model model, String studentName,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "5") int size){
List<Student> studentList = studentService.queryStudentByName(studentName);//这里的查询结果作判断用。
if (studentName.equals("")) {//1. 如果查空,就当查了1,置空,有显示全员的按钮。
PageHelper.startPage(page,size);//写在第一行会直接先处理成5个数据,所以在这里写。
studentList = studentService.queryStudentByName("1");//重查,替换方法第一行的查询语句。查1,方便置空。
PageInfo<Student> studentPageInfo = new PageInfo<>(studentList);//pagehelper分页插件的方法。
model.addAttribute("msg", "请输入");
model.addAttribute("studentList",studentPageInfo);
return "manageStudentPageLimited";//查询学生后返回,而不是重定向。
} else if (studentList.size()==0){//2. 确实查无此人,也别返回全部的人了,直接给它查1,置空,有显示全员的按钮。
PageHelper.startPage(page,size);//写在第一行会直接先处理成5个数据,所以在这里写。
studentList = studentService.queryStudentByName("1");//重查,替换方法第一行的查询语句。查1,方便置空。
PageInfo<Student> studentPageInfo = new PageInfo<>(studentList);//pagehelper分页插件的方法。
model.addAttribute("msg", "未查到");
model.addAttribute("studentList",studentPageInfo);
return "manageStudentPageLimited";//查询学生后返回,而不是重定向。
} else if (studentList.size()>5) {//3. 查到人数超过5,由于本页面一次只能显示5个,技术力不够,暂时先提交给另一个页面处理。
model.addAttribute("studentList", studentList);
return "manageStudentPage";//查询学生超过5人,随后返回至普通学生列表,而不是重定向。
} else {//4. 其他情况:也就是查询到了人,但是人数在[1,4]之间,属于正常情况。
PageHelper.startPage(page,size);//写在第一行会直接先处理成5个数据,所以在这里写。
studentList = studentService.queryStudentByName(studentName);//重查,替换方法第一行的查询语句。正常查询。
PageInfo<Student> studentPageInfo = new PageInfo<>(studentList);//pagehelper分页插件的方法。
model.addAttribute("studentList",studentPageInfo);
return "manageStudentPageLimited";//查询学生后返回,而不是重定向。
}
}
}
4. Jsp页面
- index.jsp
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML>
<html>
<head>
<title>Entrance</title>
<style>
h1 {
width: 600px;
height: 50px;
margin: 100px auto;
text-align: center;
line-height: 50px;
color: saddlebrown;
background-color: #0093E9;
background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
border-radius: 20px;
}
a {
text-decoration: none;
color: mediumpurple;
font-size: 18px;
}
h3 {
width: 350px;
height: 40px;
margin: 150px auto;
text-align: center;
line-height: 40px;
background-color: #0093E9;
background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
border-radius: 20px;
}
</style>
</head>
<body style="
background-attachment: fixed;
background-color: #E0C3FC;
background-image: -webkit-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -moz-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -o-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
">
<h1>
欢迎来到米花大学!
</h1>
<h3>
<a href="${pageContext.request.contextPath}/student/manageStudentPage">点击进入学生信息管理系统(普通版)</a>
</h3>
<h3>
<a href="${pageContext.request.contextPath}/student/manageStudentPageLimited">点击进入学生信息管理系统(分页版)</a>
</h3>
</body>
</html>
- manageStudentPage.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>manageStudentNormal</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="
background-attachment: fixed;
background-color: #E0C3FC;
background-image: -webkit-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -moz-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -o-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
">
<div class="container">
<div class="row clearfix">
<div class="col-md-12">
<div class="page-header">
<h1><small>学生信息列表(普通版)</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/student/addStudentPage">新增一个学生</a>
</div>
<div class="col-md-2">
<a href="${pageContext.request.contextPath}/student/manageStudentPage" class="btn btn-primary">查看所有学生</a>
</div>
<div class="col-md-2">
<a href="${pageContext.request.contextPath}/student/manageStudentPageLimited" class="btn btn-primary">前往分页版</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-4 column col-md-offset-4">
<%--查询学生--%>
<form class="form-inline" action="${pageContext.request.contextPath}/student/queryStudentByName" method="post">
<span style="color: red;font-weight: bold">${msg}</span>
<label>
<input type="text" name="studentName" class="form-control" placeholder="请输入要查询的学生姓名">
</label>
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>学生编号</th>
<th>学生姓名</th>
<th>学生性别</th>
<th>学生年龄</th>
<th>相关操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${studentList}" var="student" >
<tr>
<td>${student.studentId}</td>
<td>${student.studentName}</td>
<td>${student.studentSex}</td>
<td>${student.studentAge}</td>
<td>
<a href="${pageContext.request.contextPath}/student/updateStudentPage?id=${student.studentId}">修改</a> |
<a href="${pageContext.request.contextPath}/student/deleteStudent/${student.studentId}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
- manageStudentPageLimited.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>manageStudentLimited</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
h4 {
width: 100px;
height: 35px;
margin: 50px auto;
text-align: center;
line-height: 35px;
background-color: #0093E9;
background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
border-radius: 20px;
}
</style>
</head>
<body style="
background-attachment: fixed;
background-color: #E0C3FC;
background-image: -webkit-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -moz-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -o-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
">
<div class="container">
<div class="row clearfix">
<div class="col-md-12">
<div class="page-header">
<h1><small>学生信息列表(分页版)</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-2">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/student/addStudentPage">新增一个学生</a>
</div>
<div class="col-md-2">
<a href="${pageContext.request.contextPath}/student/manageStudentPageLimited" class="btn btn-primary">查看所有学生</a>
</div>
<div class="col-md-2">
<a href="${pageContext.request.contextPath}/student/manageStudentPage" class="btn btn-primary">前往普通版</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-4 column col-md-offset-4">
<%--查询学生--%>
<form class="form-inline" action="${pageContext.request.contextPath}/student/queryStudentByNameByLimited" method="post">
<span style="color: red;font-weight: bold">${msg}</span>
<label>
<input type="text" name="studentName" class="form-control" placeholder="请输入要查询的学生姓名">
</label>
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>学生编号</th>
<th>学生姓名</th>
<th>学生性别</th>
<th>学生年龄</th>
<th>相关操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${studentList.list}" var="student">
<tr>
<td>${student.studentId}</td>
<td>${student.studentName}</td>
<td>${student.studentSex}</td>
<td>${student.studentAge}</td>
<td>
<a href="${pageContext.request.contextPath}/student/updateStudentPage?id=${student.studentId}">修改</a> |
<a href="${pageContext.request.contextPath}/student/deleteStudent/${student.studentId}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-4 column col-md-offset-4">
<ul class="pagination">
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=${studentList.pageNum-1}">上一页</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=1">1</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=2">2</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=3">3</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=4">4</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=5">5</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=6">6</a></li>
<li><a href="${pageContext.request.contextPath}/student/manageStudentPageLimited?page=${studentList.pageNum+1}">下一页</a></li>
</ul>
</div>
</div>
<h4>第${studentList.pageNum}页</h4>
</div>
</div>
</div>
</body>
</html>
- addStudentPage.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>addStudent</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="
background-attachment: fixed;
background-color: #E0C3FC;
background-image: -webkit-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -moz-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -o-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
">
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>新增学生</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/student/addStudent" method="post">
<div class="form-group">
<label>
学生编号:
<input type="text" name="studentId" required>
</label>
</div>
<div class="form-group">
<label>
学生姓名:
<input type="text" name="studentName" required>
</label>
</div>
<div class="form-group">
<label>
学生性别:
<input type="text" name="studentSex" required>
</label>
</div>
<div class="form-group">
<label>
学生年龄:
<input type="text" name="studentAge" required>
</label>
</div>
<div class="form-group">
<input type="submit" value="添加">
</div>
</form>
</div>
</body>
</html>
- updateStudentPage.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>updateStudent</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="
background-attachment: fixed;
background-color: #E0C3FC;
background-image: -webkit-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -moz-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: -o-linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
background-image: linear-gradient(160deg, #E0C3FC 1%, #8EC5FC 99%);
">
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>修改学生信息</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/student/updateStudent" method="post">
<div class="form-group">
<label>
学生编号: ${studentInfo.studentId}
<input type="hidden" name="studentId" value="${studentInfo.studentId}" readonly="readonly"/>
</label>
</div>
<div class="form-group">
<label>
学生姓名:
<input type="text" name="studentName" value="${studentInfo.studentName}" required/>
</label>
</div>
<div class="form-group">
<label>
学生性别:
<input type="text" name="studentSex" value="${studentInfo.studentSex}" required/>
</label>
</div>
<div class="form-group">
<label>
学生年龄:
<input type="text" name="studentAge" value="${studentInfo.studentAge}" required/>
</label>
</div>
<div class="form-group">
<input type="submit" value="提交修改"/>
<input type="reset" value="重置"/>
</div>
</form>
</div>
</body>
</html>
5. 简单预览
- 名字是乱写的!
- 祝好运。