写点什么

学生管理系统(SSM 简易版)总结,斗鱼 Java 开发二面被刷

用户头像
极客good
关注
发布于: 刚刚
  • 注意: webapp 是默认没有 java 源文件也没有 test 目录的。


遵循 Maven 的统一项目结构,我们搭建出项目的完整目录结构如下图:



  • 我们并没有使用 Log4j 来输出日志,而是使用 logback

  • **提示:**我们可以在 IDEA 中右键目录然后选择【Make Directory as】,让 IDEA 识别不同的目录作用



这里的目录建好之后还需要设置一下,让 IDEA 识别目录作用,选择【File】>【Project Structure】:



设置好之后点击 OK,即完成了项目目录的搭建。

第三步:配置文件内容

在【pom.xml】文件中声明依赖的 jar 包 :


<?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/maven-v4_0_0.xsd">


<modelVersion>4.0.0</modelVersion>


<packaging>war</packaging>


<name>StudentManagerSSM</name>


<groupId>cn.wmyskxz</groupId>


<artifactId>StudentManagerSSM</artifactId>


<version>1.0-SNAPSHOT</version>


<build>


<plugins>


<plugin>


<groupId>org.mortbay.jetty</groupId>


<artifactId>maven-jetty-plugin</artifactId>


<version>6.1.7</version>


<configuration>


<connectors>


<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">


<port>8888</port>


<maxIdleTime>30000</maxIdleTime>


</connector>


</connectors>


<webAppSourceDirectory>{pom.artifactId}-${pom.version}


</webAppSourceDirectory>


<contextPath>/</contextPath>


</configuration>


</plugin>


</plugins>


</build>


<properties>


<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>


<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>


<spring.version>4.3.5.RELEASE</spring.version>


<mybatis.version>3.4.1</mybatis.version>


</properties>


<dependencies>


<dependency>


<groupId>javax.servlet</groupId>


<artifactId>jstl</artifactId>


<version>1.2</version>


</dependency>


<dependency>


<groupId>org.apache.taglibs</groupId>


<artifactId>taglibs-standard-impl</artifactId>


<version>1.2.5</version>


</dependency>


<dependency>


<groupId>javax</groupId>


<artifactId>javaee-api</artifactId>


<version>7.0</version>


</dependency>


<dependency>


<groupId>junit</groupId>


<artifactId>junit</artifactId>


<version>4.12</version>


</dependency>


<dependency>


<groupId>ch.qos.logback</groupId>


<artifactId>logback-classic</artifactId>


<version>1.2.2</version>


</dependency>


<dependency>


<groupId>com.fasterxml.jackson.core</groupId>


<artifactId>jackson-databind</artifactId>


<version>2.8.7</version>


</dependency>


<dependency>


<groupId>mysql</groupId>


<artifactId>mysql-connector-java</artifactId>


<version>5.1.41</version>


<scope>runtime</scope>


</dependency>


<dependency>


<groupId>com.mchange</groupId>


<artifactId>c3p0</artifactId>


<version>0.9.5.2</version>


</dependency>


<dependency>


<groupId>org.mybatis</groupId>


<artifactId>mybatis</artifactId>


<version>${mybatis.version}</version>


</dependency>


<dependency>


<groupId>org.mybatis</groupId>


<artifactId>mybatis-spring</artifactId>


<version>1.3.1</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-core</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-beans</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-context</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-jdbc</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-tx</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-web</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-webmvc</artifactId>


<version>${spring.version}</version>


</dependency>


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-test</artifactId>


<version>${spring.version}</version>


</dependency>


</dependencies>


</project>


  • <build> 标签是默认生成的

  • 我们在 <properties> 中声明了编码格式以及使用的 spring 和 mybatis 的版本号,然后在 <dependencies> 中声明了具体的 jar 包


在【web.xml】中声明编码过滤器并配置 DispatcherServlet :


<?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">


<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>


<servlet>


<servlet-name>SpringMVC</servlet-name>


<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


<init-param>


<param-name>contextConfigLocation</param-name>


<param-value>classpath:spring-*.xml</param-value>


</init-param>


<load-on-startup>1</load-on-startup>


<async-supported>true</async-supported>


</servlet>


<servlet-mapping>


<servlet-name>SpringMVC</servlet-name>


<url-pattern>/</url-pattern>


</servlet-mapping>


</web-app>


在【spring-mybatis.xml】中完成 spring 和 mybatis 的配置:


<?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" xmlns:tx="http://www.springframework.org/schema/tx"


xsi:schemaLocation="http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


<context:component-scan base-package="cn.wmyskxz.service"/>


<context:property-placeholder location="classpath:jdbc.properties"/>


<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}"/>


<property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>


<property name="minPoolSize" value="${c3p0.minPoolSize}"/>


<property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>


<property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>


<property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>


</bean>


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">


<property name="dataSource" ref="dataSource"/>


<property name="typeAliasesPackage" value="cn.wmyskxz.entity"/>


<property name="mapperLocations" value="classpath:mapper/*.xml"/>


</bean>


<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">


<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>


<property name="basePackage" value="cn.wmyskxz.dao"/>


</bean>


<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">


<property name="dataSource" ref="dataSource"/>


</bean>


<tx:annotation-driven transaction-manager="transactionManager"/>


</beans>


在【spring-mvc.xml】中完成 Spring MVC 的相关配置:


<?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"


xmlns:mvc="http://www.springframework.org/schema/mvc"


xsi:schemaLocation="http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context.xsd


http://www.springframework.org/schema/mvc


http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">


<context:component-scan base-package="cn.wmyskxz.controller"/>


mvc:annotation-driven/


mvc:default-servlet-handler/


<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">


<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>


<property name="prefix" value="/WEB-INF/views/"/>


<property name="suffix" val


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


ue=".jsp"/>


</bean>


</beans>


在【jdbc.properties】中配置 c3p0 数据库连接池:


jdbc.driver=com.mysql.jdbc.Driver


#数据库地址


jdbc.url=jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8


#用户名


jdbc.username=root


#密码


jdbc.password=root


#最大连接数


c3p0.maxPoolSize=30


#最小连接数


c3p0.minPoolSize=10


#关闭连接后不自动 commit


c3p0.autoCommitOnClose=false


#获取连接超时时间


c3p0.checkoutTimeout=10000


#当获取连接失败重试次数


c3p0.acquireRetryAttempts=2


在【logback.xml】中完成日志输出的相关配置:


<?xml version="1.0" encoding="UTF-8"?>


<configuration debug="true">


<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">


<encoder>


<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>


</encoder>


</appender>


<root level="debug">


<appender-ref ref="STDOUT"/>


</root>


</configuration>


以上就完成了 SSM 框架的基本配置:


  • 添加进了 SSM 项目所需要的 jar 包

  • 配置好了 spring/mybatis/spring MVC 的相关配置信息(自动扫描 cn.wmyskxz 包下的带有注解的类)

  • 通过 xml 配置的方式配置好了日志和数据库

⑤ 实体类设计

实体类仅仅是对数据库中表的一一映射(表中字段名应该和实体类中的名称一一对应),同时可能还需要兼顾对业务能力的支持。


  • 在 Packge【cn.wmyskxz.entity】下创建 Student 类:


```


package cn.wmyskxz.entity;


import java.util.Date;


/**


  • Student 实体类

  • @author: @我没有三颗心脏

  • @create: 2018-04-23-下午 13:34


*/


public class Student {


private int id;


private int student_id;


private String name;


private int age;


private String sex;


private Date birthday;


/* getter and setter */


}


```

⑤ DAO 类的设计

DAO,即 Date Access Object,数据库访问对象,就是对数据库相关操作的封装,让其他地方看不到 JDBC 的代码。


在【cn.wmyskxz.dao】包下创建【StudentDao】接口:


package cn.wmyskxz.dao;


import cn.wmyskxz.entity.Student;


import java.util.List;


public interface StudentDao {


int getTotal();


void addStudent(Student student);


void deleteStudent(int id);


void updateStudent(Student student);


Student getStudent(int id);


List<Student> list(int start, int count);


}


然后在【resources/mapper】下创建好对应的映射文件【StudengDao.xml】:


<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"


"http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="cn.wmyskxz.dao.StudentDao">


<select id="getTotal" resultType="int">


SELECT COUNT(*) FROM student


</select>


<insert id="addStudent" parameterType="Student">


INSERT INTO student VALUES(NULL, #{student_id}, #{name}, #{age}, #{sex}, #{birthday})


</insert>


<delete id="deleteStudent" parameterType="int">


DELETE FROM student WHERE id = #{id}


</delete>


<update id="updateStudent" parameterType="Student">


UPDATE student SET student_id = #{student_id}, name = #{name},


age = #{age}, sex = #{sex}, birthday = #{birthday} WHERE id = #{id}


</update>


<select id="getStudent" resultMap="student" parameterType="int">


SELECT * FROM student WHERE id = #{id}


</select>


<resultMap id="student" type="student">


<id column="id" property="id"/>


<result column="student_id" property="student_id"/>


<result column="name" property="name"/>


<result column="age" property="age"/>


<result column="sex" property="sex"/>


<result column="birthday" property="birthday"/>


</resultMap>


<select id="list" resultMap="student">


SELECT * FROM student ORDER BY student_id desc limit #{param1}, #{param2}


</select>


</mapper>


编写好了 Dao 类是需要测试的,这里测试类就不给出了。

⑦ 业务类设计

  • 问题: 为什么不直接使用 Dao 类而是还要在上面封装一层 Service 层呢?

  • 回答:


基于责任分离的原则,Dao 层就应该专注于对数据库的操作,而在 Service 层我们可以增加一些非 CRUD 的方法去更好的完成本身抽离出来的 service 服务(业务处理)。


在【cn.wmyskxz.service】包下创建【StudentService】接口:


package cn.wmyskxz.service;


import cn.wmyskxz.entity.Student;


import java.util.List;


public interface StudentService {


/**


  • 获取到 Student 的总数

  • @return


*/


int getTotal();


/**


  • 增加一条数据

  • @param student


*/


void addStudent(Student student);


/**


  • 删除一条数据

  • @param id


*/


void deleteStudent(int id);


/**


  • 更新一条数据

  • @param student


*/


void updateStudent(Student student);


/**


  • 找到一条数据

  • @param id

  • @return


*/


Student getStudent(int id);


/**


  • 列举出从 start 位置开始的 count 条数据

  • @param start

  • @param count

  • @return


*/


List<Student> list(int start, int count);


}


并在相同包名下创建实现类【StudentServiceImpl】:


package cn.wmyskxz.service;


import cn.wmyskxz.dao.StudentDao;


import cn.wmyskxz.entity.Student;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Service;


import java.util.List;


/**


  • StudentService 的实现类

  • @author: @我没有三颗心脏

  • @create: 2018-04-23-下午 13:51


*/


@Service


public class StudentServiceImpl implements StudentService {


@Autowired


StudentDao studentDao;


public int getTotal() {


return studentDao.getTotal();


}


public void addStudent(Student student) {


studentDao.addStudent(student);


}


public void deleteStudent(int id) {


studentDao.deleteStudent(id);


}


public void updateStudent(Student student) {


studentDao.updateStudent(student);


}


public Student getStudent(int id) {


return studentDao.getStudent(id);


}


public List<Student> list(int start, int count) {


return studentDao.list(start, count);


}


}

⑧ 功能开发

在【cn.wmyskxz.controller】包下创建【StudentController】控制器,代码基本上都是复制黏贴之前在 Servlet 中的代码:


package cn.wmyskxz.controller;


import cn.wmyskxz.entity.Student;


import cn.wmyskxz.service.StudentService;


import cn.wmyskxz.util.Page;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Controller;


import org.springframework.web.bind.annotation.RequestMapping;


import org.springframework.web.servlet.ModelAndView;


import javax.servlet.http.HttpServletRequest;


import javax.servlet.http.HttpServletResponse;


import java.text.ParseException;


import java.text.SimpleDateFormat;


import java.util.Date;


import java.util.List;


/**


  • Student 控制器

  • @author: @我没有三颗心脏

  • @create: 2018-04-23-下午 13:27


*/


@Controller


@RequestMapping("")


public class StudentController {


@Autowired


private StudentService studentService;


@RequestMapping("/addStudent")


public String addStudent(HttpServletRequest request, HttpServletResponse response) {


Student student = new Student();


int studentID = Integer.parseInt(request.getParameter("student_id"));


String name = request.getParameter("name");


int age = Integer.parseInt(request.getParameter("age"));


String sex = request.getParameter("sex");


Date birthday = null;


// String 类型按照 yyyy-MM-dd 的格式转换为 java.util.Date 类


SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");


try {


birthday = simpleDateFormat.parse(request.getParameter("birthday"));


} catch (ParseException e) {


e.printStackTrace();


}


student.setStudent_id(studentID);


student.setName(name);


student.setAge(age);


student.setSex(sex);


student.setBirthday(birthday);


studentService.addStudent(student);


return "redirect:listStudent";


}


@RequestMapping("/listStudent")


public String listStudent(HttpServletRequest request, HttpServletResponse response) {


// 获取分页参数


int start = 0;


int count = 10;


try {


start = Integer.parseInt(request.getParameter("page.start"));


count = Integer.parseInt(request.getParameter("page.count"));


} catch (Exception e) {


}


Page page = new Page(start, count);


List<Student> students = studentService.list(page.getStart(), page.getCount());


int total = studentService.getTotal();


page.setTotal(total);


request.setAttribute("students", students);


request.setAttribute("page", page);


return "listStudent";


}


@RequestMapping("/deleteStudent")


public String deleteStudent(int id) {


studentService.deleteStudent(id);


return "redirect:listStudent";


}


@RequestMapping("/editStudent")


public ModelAndView editStudent(int id) {


ModelAndView mav = new ModelAndView("editStudent");


Student student = studentService.getStudent(id);


mav.addObject("student", student);


return mav;


}


@RequestMapping("/updateStudent")


public String updateStudent(HttpServletRequest request, HttpServletResponse response) {


Student student = new Student();


int id = Integer.parseInt(request.getParameter("id"));


int student_id = Integer.parseInt(request.getParameter("student_id"));


String name = request.getParameter("name");


int age = Integer.parseInt(request.getParameter("age"));


String sex = request.getParameter("sex");


SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");


Date birthday = null;


try {


birthday = simpleDateFormat.parse(request.getParameter("birthday"));


} catch (ParseException e) {


e.printStackTrace();


}


student.setId(id);


student.setStudent_id(student_id);


student.setName(name);


student.setAge(age);


student.setSex(sex);


student.setBirthday(birthday);


studentService.updateStudent(student);


return "redirect:listStudent";


}


}


  • 注意: 所有的学号都用 student_id 表示,为了契合在数据库中的字段名(包括下面的 JSP 文件)


JSP 文件也直接黏之前的就好了,不过需要注意所有的 name 属性


  • 【listStudent.jsp】:


<!DOCTYPE html>


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


pageEncoding="UTF-8" %>


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


<html>


<head>


<%-- 引入 JQ 和 Bootstrap --%>


<script src="js/jquery/2.0.0/jquery.min.js"></script>


<link href="css/bootstrap/3.3.6/bootstrap.min.css" rel="stylesheet">


<script src="js/bootstrap/3.3.6/bootstrap.min.js"></script>


<link href="css/style.css" rel="stylesheet">


<title>学生管理页面 - 首页</title>


<script> $(function () {


$("ul.pagination li.disabled a").click(function () {


return false;


});


}); </script>


</head>


<body>


<div class="listDIV">


<table class="table table-striped table-bordered table-hover table-condensed">


<caption>学生列表 - 共 ${page.total}人</caption>


<thead>


<tr class="success">


<th>学号</th>


<th>姓名</th>


<th>年龄</th>


<th>性别</th>


<th>出生日期</th>


<th>编辑</th>


<th>删除</th>


</tr>


</thead>


<tbody>


<c:forEach items="${students}" var="s" varStatus="status">


<tr>


<td>${s.student_id}</td>


<td>${s.name}</td>


<td>${s.age}</td>


<td>${s.sex}</td>


<td>${s.birthday}</td>


<td><a href="/editStudent?id=${s.id}"><span class="glyphicon glyphicon-edit"></span> </a></td>


<td><a href="/deleteStudent?id=${s.id}"><span class="glyphicon glyphicon-trash"></span> </a></td>


</tr>


</c:forEach>


</tbody>


</table>


</div>


<nav class="pageDIV">


<ul class="pagination">


<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>


<a href="?page.start=0">


<span>?</span>


</a>


</li>


<li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>


<a href="?page.start=${page.start-page.count}">


<span>?</span>


</a>


</li>


<c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">


<c:if test="${status.countpage.count-page.start<=30 && status.countpage.count-page.start>=-10}">


<li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>>


<a


href="?page.start=${status.index*page.count}"


<c:if test="${status.index*page.count==page.start}">class="current"</c:if>


${status.count}</a>


</li>


</c:if>


</c:forEach>


<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>


<a href="?page.start=${page.start+page.count}">


<span>?</span>


</a>


</li>


<li <c:if test="${!page.hasNext}">class="disabled"</c:if>>


<a href="?page.start=${page.last}">


<span>?</span>


</a>


</li>


</ul>


</nav>


<div class="addDIV">


<div class="panel panel-success">


<div class="panel-heading">


<h3 class="panel-title">增加学生</h3>


</div>


<div class="panel-body">

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
学生管理系统(SSM简易版)总结,斗鱼Java开发二面被刷