写在前面
这是我第一次接触到ssm框架,之前一直想学习java的框架知识,这次有机会跟着学校的实训课程学习了这个框架。写的不好,但很适合初学者。
项目结构
引入依赖
<?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.xkp</groupId>
<artifactId>ssmdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>ssmdemo Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<springframework.version>4.3.18.RELEASE</springframework.version>
</properties>
<dependencies>
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springJDBC包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- spring事务包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- spring对web的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- springwebMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mybatis的分页助手-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!--Mybatis与spring整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<!--连接池:德鲁伊数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.5</version>
</dependency>
<!-- hibernate的验证框架-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>ssmdemo</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
准备工作
创建数据库
建立entity,dao层(接口),service层(接口+实现类).
entity层:
Club.java:
package com.xkp.ssm.entity;
import java.util.Date;
public class Club {
private Integer id;
private String name;
private String loc;
private String stadium;
private Integer rank;
private Integer score;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getStadium() {
return stadium;
}
public void setStadium(String stadium) {
this.stadium = stadium;
}
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
@Override
public String toString() {
return "Club{" +
"id=" + id +
", name='" + name + '\'' +
", loc='" + loc + '\'' +
", stadium='" + stadium + '\'' +
", rank=" + rank +
", score=" + score +
'}';
}
}
Dao层(纯接口)采用mapper代理:
ClubDao.java:
package com.xkp.ssm.dao;
import com.xkp.ssm.entity.Club;
import java.util.List;
public interface ClubDao {
//数据库基本操作
/**
* 添加球队记录
* @param club
* @throws Exception
*/
void addClub(Club club) throws Exception;
/**
* 修改一条球队
* @param club
* @throws Exception
*/
void updateClub(Club club) throws Exception;
/**
* 删除一条球队记录
* @param id
* @throws Exception
*/
void deleteClub(int id) throws Exception;
/**
* 根据主键查询用户信息
* @param id
* @return
* @throws Exception
*/
Club getClubById(int id) throws Exception;
/**
* 查询所有用户信息
* @return
*/
List<Club> getClubs();
}
Service层:
ClubService.java(接口):
package com.xkp.ssm.service;
import com.github.pagehelper.PageInfo;
import com.xkp.ssm.entity.Club;
public interface ClubService {
void addClub(Club club) throws Exception;
void updateClub(Club club) throws Exception;
void deleteUser(int id) throws Exception;
Club getClubById(int id) throws Exception;
/**
* 分页查询
*/
PageInfo<Club> getClubs(int page, int pageSize) throws Exception;
}
ClubServiceImpl.java(接口的实现类):
package com.xkp.ssm.service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xkp.ssm.dao.ClubDao;
import com.xkp.ssm.entity.Club;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ClubServiceImpl implements ClubService {
@Autowired
private ClubDao clubDao;
@Override
public void addClub(Club club) throws Exception {
clubDao.addClub(club);
}
@Override
public void updateClub(Club club) throws Exception {
clubDao.updateClub(club);
}
@Override
public void deleteUser(int id) throws Exception {
clubDao.deleteClub(id);
}
@Override
public Club getClubById(int id) throws Exception {
return clubDao.getClubById(id);
}
@Override
public PageInfo<Club> getClubs(int page, int pageSize) throws Exception {
PageHelper.startPage(page,pageSize);
List<Club> clubList = clubDao.getClubs();
PageInfo<Club> pageInfo = new PageInfo<>(clubList);
return pageInfo;
}
}
添加配置
log4j日志:
src/main/resources/log4j.properties
#指定logger
#设定log4j的日志级别和输出的目的地
#INFO日志级别 ,Console和logfile输出的目的地
#等级 OFF,FATAL,ERROR,WARN,INFO,DEBUG,TRACE
log4j.rootLogger=INFO,Console,logfile
#指定appender
#设定Logger的Console,其中Console为自定义名称,类型为控制台输出
log4j.appender.Console=org.apache.log4j.ConsoleAppender
#设定Logger的logfile,其中logfile为自定义名称,类型为文件
#org.apache.log4j.FileAppender文件
#org.apache.log4j.RollingFileAppender文件大小到达指定尺寸后产生一个新的文件
#org.apache.log4j.DailyRollingFileAppender每天产生一个日志文件
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
#设定文件的输出路径
log4j.appender.logfile.File=D:/log/ssm.log
#设定文件最大尺寸 单位可以使KB,MB,GB
log4j.appender.logfile.MaxFileSize=2048KB
#输出格式
#设定appender布局Layout
# %d 输出日志的日期和时间,指定格式:%d{yyyy-MM-dd HH:mm:ss SSS}
# %p 输出的日志级别
# %c 输出所属类的全类名
# %M 方法名
# %m 输出代码中指定消息
# %n 一个换行符
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d %p %c.%M() --%m%n
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p %c.%M() --%m%n
数据库基本信息:
src/main/resources/db.properties
jdbc.mysql.url = jdbc:mysql://localhost:3306/java?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT
jdbc.mysql.className = com.mysql.cj.jdbc.Driver
jdbc.mysql.username = root
jdbc.mysql.password = root
#druid德鲁伊
druid.initialSize=3
druid.minIdle=2
druid.maxActive=15
druid.maxWait=10000
druid.filters=stat,wall,log4j
druid.timeBetweenEvictionRunsMillis=60000
druid.minEvictableIdleTimeMillis=30000
druid.validationQuery=select 1 from dual
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
druid.poolPreparedStatements=true
druid.maxOpenPreparedStatements=20
Mybatis的映射文件:(增删改查基本操作)
src/main/resources/mybatis/mapper/ClubMapper.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="com.xkp.ssm.dao.ClubDao">
<insert id="addClub" parameterType="club">
insert into tb_club(tb_club.name,tb_club.loc,tb_club.stadium,tb_club.rank,tb_club.score) values(#{name},#{loc},#{stadium},#{rank},#{score})
</insert>
<delete id="deleteClub" parameterType="int">
delete from tb_club where id=#{id}
</delete>
<update id="updateClub" parameterType="club">
update tb_club set tb_club.name=#{name},tb_club.loc=#{loc},tb_club.stadium=#{stadium},tb_club.rank=#{rank},tb_club.score=#{score}
where tb_club.id=#{id}
</update>
<select id="getClubById" parameterType="int" resultType="club">
SELECT
tb_club.id,
tb_club.name,
tb_club.loc,
tb_club.stadium,
tb_club.rank,
tb_club.score
FROM
tb_club
where
tb_club.id= #{id}
</select>
<select id="getClubs" resultType="club">
SELECT
tb_club.id,
tb_club.name,
tb_club.loc,
tb_club.stadium,
tb_club.rank,
tb_club.score
FROM
tb_club
order by tb_club.rank asc
</select>
</mapper>
mybatis的全局配置:
src/main/resources/mybatis/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>
<!-- 加载外部资源文件:移入spring的配置(废除) -->
<!-- 全局参数设置 -->
<settings>
<!-- 下划线转驼峰 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启延迟加载 -->
<!--<setting name="lazyLoadingEnabled" value="true"/>-->
<!--<setting name="aggressiveLazyLoading" value="false"/>-->
<!-- 开启二级缓存 -->
<!--<setting name="cacheEnabled" value="true"/>-->
</settings>
<!-- 批量类型别名:在spring中也可配置 -->
<typeAliases>
<package name="com.xkp.ssm.entity"/>
</typeAliases>
<!-- 配置mybatis的插件:在spring中也可配置 -->
<plugins>
<!-- 配置分页助手插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="reasonable" value="true"/>
</plugin>
</plugins>
<!-- 环境:移入spring的配置(废除) -->
<!-- 映射器:在spring中也可配置,建议配置在spring中 -->
<!--<mappers>-->
<!--<package name="com.ssm.dao"/>-->
<!--</mappers>-->
</configuration>
Spring的配置:
src/main/resources/spring/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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 注解扫描 -->
<context:component-scan base-package="com.xkp.ssm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 读取资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源:阿里巴巴旗下的德鲁伊连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!-- 基础信息 -->
<property name="driverClassName" value="${jdbc.mysql.className}"/>
<property name="url" value="${jdbc.mysql.url}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
<!-- 关键信息 -->
<!-- 初始化连接池时建立物理连接个数 -->
<property name="initialSize" value="${druid.initialSize}"/>
<!-- 最小连接数 -->
<property name="minIdle" value="${druid.minIdle}"/>
<!-- 最大连接数 -->
<property name="maxActive" value="${druid.maxActive}"/>
<!-- 连接超时等待时间,单位毫秒 -->
<property name="maxWait" value="${druid.maxWait}"/>
<!-- 提升性能,监控系统 -->
<!-- 监控系统:stat监控统计,wall防御sql注入,log4j日志 -->
<property name="filters" value="${druid.filters}"/>
<!-- 进行检测的间隔时间,检测需要关闭的空闲连接,单位毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}"/>
<!-- 连接在连接池中存活的最小时间,单位毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}"/>
<!-- 用于检测连接是否有效的sql -->
<property name="validationQuery" value="${druid.validationQuery}"/>
<!-- 申请连接时的检测,建议配置为true,不影响性能 -->
<property name="testWhileIdle" value="${druid.testWhileIdle}"/>
<!-- 申请连接时与归还连接时的检测,都会影响性能建议配置为false -->
<property name="testOnBorrow" value="${druid.testOnBorrow}"/>
<property name="testOnReturn" value="${druid.testOnReturn}"/>
<!-- 是否缓存PreparedStatement,也成为PSCache。PSCache对oracle中的游标性能有巨大的提升,但是mysql不能使用 -->
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}"/>
<!-- 启用PSCache,如果该值大于0,会自动修改poolPreparedStatements的配置为true -->
<property name="maxOpenPreparedStatements" value="${druid.maxOpenPreparedStatements}"/>
</bean>
<!-- mybatis的SqlSessionFactory对象 -->
<bean id="sqlSessoinFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源对象 -->
<property name="dataSource" ref="dataSource"/>
<!-- 加载mybatis的核心配置 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<!-- 加载mapper映射文件,使用通配符进行批量加载 -->
<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
<!--<!– 批量配置类型别名 –>-->
<!--<property name="typeAliasesPackage" value="com.ssm.entity"/>-->
<!--<!– 插件 –>-->
<!--<property name="plugins">-->
<!--<array>-->
<!--<bean class="com.github.pagehelper.PageInterceptor">-->
<!--<property name="properties" value="reasonable=true"/>-->
<!--</bean>-->
<!--</array>-->
<!--</property>-->
</bean>
<!--
思路:mybatis阶段,mapper代理对象是由SqlSession中的getMapper()方法获取
ssm阶段,将所有的接口告知mybatis,为每个接口生成代理类对象,代理对象通过交给IOC容器
-->
<!-- mapper代理对象:单个代理对象配置,相等于配置一个dao的实现类 -->
<!--<bean id="deptDao" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!--<!– 代理对象接口的全限定名 –>-->
<!--<property name="mapperInterface" value="com.ssm.dao.DeptDao"/>-->
<!--</bean>-->
<!--<bean id="empDao" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
<!--<property name="mapperInterface" value="com.ssm.dao.EmpDao"/>-->
<!--</bean>-->
<!-- mapper代理对象的扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描基础包:如果有多个基础包,可以使用逗号分隔 -->
<property name="basePackage" value="com.xkp.ssm.dao"/>
<!-- 注入SqlSessionFactory对象 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessoinFactory"/>
</bean>
</beans>
src/main/resources/spring/applicationContext-tx.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 事务管理的配置 -->
<!-- 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源对象 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 事务属性-->
<tx:attributes>
<tx:method name="insert*" isolation="READ_COMMITTED"/>
<tx:method name="add*" isolation="READ_COMMITTED"/>
<tx:method name="save*" isolation="READ_COMMITTED"/>
<tx:method name="update*" isolation="READ_COMMITTED"/>
<tx:method name="edit*" isolation="READ_COMMITTED"/>
<tx:method name="delete*" isolation="READ_COMMITTED"/>
<tx:method name="del*" isolation="READ_COMMITTED"/>
<tx:method name="remove*" isolation="READ_COMMITTED"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="list*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="load*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务切入点:通过AOP实现事务管理-->
<aop:config>
<aop:pointcut id="exp" expression="execution(* com.xkp.ssm.service.*.*(..))"/>
<!-- 将切点表达式应用在事务上-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="exp"/>
</aop:config>
</beans>
SpringMVC的配置
src/main/resources/springmvc/springmvc.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:p="http://www.springframework.org/schema/p"
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.xsd">
<!-- 注解扫描 -->
<!--<context:component-scan base-package="com.ssm" use-default-filters="false">-->
<!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--</context:component-scan>-->
<context:component-scan base-package="com.xkp.ssm.controller"/>
<!-- MVC注解驱动-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 处理静态资源-->
<mvc:default-servlet-handler/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置自定义类型转换器 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.xkp.ssm.converter.DateConverter"></bean>
</set>
</property>
</bean>
</beans>
web的配置
src/main/webapp/WEB-INF/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中自带的字符编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 通过隐藏域传参解决form表单的PUT与DELETE方式的请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 解决put请求传递参数的问题-->
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</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:springmvc/springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 上下对象ServletContext的初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<!--
*表示通配符
表示读取src/main/resources目录下查找spring目录,并加载该目录下所有的以applicationContext开头的xml文件
-->
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<!-- springIOC容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 德鲁伊数据源中的监控系统 -->
<!-- 监控系统的Servlet -->
<servlet>
<servlet-name>StatViewServlet</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<param-name>loginUsername</param-name>
<param-value>zhangsan</param-value>
</init-param>
<init-param>
<param-name>loginPassword</param-name>
<param-value>123456</param-value>
</init-param>
<init-param>
<param-name>allow</param-name>
<param-value>127.0.0.1</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>StatViewServlet</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!-- 监控系统的过滤器:排除路径,指定无需监控的请求路径 -->
<filter>
<filter-name>WebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>/druid/*,*.jsp,*.js,*.css,/bootstrap/*,/font-awesome/*,*.jpg,*.png,*.gif</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 欢迎页面 -->
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/login.jsp</welcome-file>
</welcome-file-list>
</web-app>
前端页面
src/main/webapp/WEB-INF/jsp/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1><a href="club/list">足球俱乐部管理</a></h1>
</body>
</html>
src/main/webapp/WEB-INF/jsp/clublist.jsp
<%--
Created by IntelliJ IDEA.
User: bsx
Date: 2020/12/7
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6">
<h1>俱乐部信息</h1>
<a href="toAdd"><span class="btn-info">新增俱乐部</span></a>
<table class="table table-condensed table-bordered table-hover">
<tr>
<th>排名</th>
<th>球队</th>
<th>城市</th>
<th>主场</th>
<th>积分</th>
<th>操作</th>
</tr>
<c:forEach items="${pageInfo.list}" var="club">
<tr>
<td>${club.rank}</td>
<td>${club.name}</td>
<td>${club.loc}</td>
<td>${club.stadium}</td>
<td>${club.score}</td>
<td>
<a href="del?id=${club.id}"><span class="btn btn-danger btn-small">删除</span></a>
<a href="toedit?id=${club.id}"><span class="btn btn-success btn-small">修改</span></a>
</td>
</tr>
</c:forEach>
</table>
<%-- 分页--%>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="${pageContext.request.contextPath}/club/list?page=${pageInfo.prePage}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<c:forEach items="${pageInfo.navigatepageNums}" var="page">
<c:if test="${page==pageInfo.pageNum}">
<li class="active"><a href="${pageContext.request.contextPath}/club/list?page=${page}">${page}</a></li>
</c:if>
<c:if test="${page!=pageInfo.pageNum}">
<li><a href="${pageContext.request.contextPath}/club/list?page=${page}">${page}</a></li>
</c:if>
</c:forEach>
<li>
<a href="${pageContext.request.contextPath}/club/list?page=${pageInfo.nextPage}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
<div class="col-md-3"></div>
</div>
</body>
</html>
src/main/webapp/WEB-INF/jsp/clubadd.jsp
<%--
Created by IntelliJ IDEA.
User: bsx
Date: 2020/12/7
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增俱乐部</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
</head>
<body>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<h1>新增俱乐部</h1>
<form action="add">
<div class="form-group">
<label>球队名称</label>
<input type="text" class="form-control" name="name" placeholder="请输入球队名称">
</div>
<div class="form-group">
<label>城市</label>
<input type="text" class="form-control" name="loc" placeholder="请输入球队名所在城市">
</div>
<div class="form-group">
<label>主场</label>
<input type="text" class="form-control" name="stadium" placeholder="请输入球队的主体育场名称">
</div>
<div class="form-group">
<label>积分</label>
<input type="text" class="form-control" name="score" placeholder="请输入球队的当前积分">
</div>
<div class="form-group">
<label>排名</label>
<input type="text" class="form-control" name="rank" placeholder="请输入球队的当前排名">
</div>
<button type="submit">添加</button>
</form>
</div>
<div class="col-md-3"></div>
</div>
</body>
</html>
src/main/webapp/WEB-INF/jsp/clubedit.jsp
<%--
Created by IntelliJ IDEA.
User: bsx
Date: 2020/12/7
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改俱乐部</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
</head>
<body>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<h1>修改俱乐部</h1>
<form action="edit">
<input type="hidden" name="id" value="${club.id}">
<div class="form-group">
<label>球队名称</label>
<input type="text" class="form-control" name="name" value="${club.name}" placeholder="请输入球队名称">
</div>
<div class="form-group">
<label>城市</label>
<input type="text" class="form-control" name="loc" value="${club.loc}" placeholder="请输入球队名所在城市">
</div>
<div class="form-group">
<label>主场</label>
<input type="text" class="form-control" name="stadium" value="${club.stadium}" placeholder="请输入球队的主体育场名称">
</div>
<div class="form-group">
<label>积分</label>
<input type="text" class="form-control" name="score" value="${club.score}" placeholder="请输入球队的当前积分">
</div>
<div class="form-group">
<label>排名</label>
<input type="text" class="form-control" name="rank" value="${club.rank}" placeholder="请输入球队的当前排名">
</div>
<button type="submit">提交</button>
</form>
</div>
<div class="col-md-3"></div>
</div>
</body>
</html>
Controller类
src/main/java/com/xkp/ssm/controller/ClubController.java
ClubController.java
package com.xkp.ssm.controller;
import com.xkp.ssm.entity.Club;
import com.xkp.ssm.service.ClubService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("club")
public class ClubController {
@Autowired
private ClubService clubService;
@RequestMapping("list")
public String showClubList(Model model,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "5") int pageSize)
throws Exception {
model.addAttribute("pageInfo",clubService.getClubs(page,pageSize));
return "clublist";
}
@RequestMapping("toAdd")
public String showClubAdd(){
return "clubadd";
}
@RequestMapping("toEdit")
public String showClubEdit(){
return "clubedit";
}
@RequestMapping("add")
public String addClub(Club club) throws Exception {
clubService.addClub(club);
return "redirect:list";
}
@RequestMapping("del")
public String deletClub(int id) throws Exception {
clubService.deleteUser(id);
return "redirect:list";
}
@RequestMapping("toedit")
public String toEdit(int id,Model model) throws Exception {
model.addAttribute("club",clubService.getClubById(id));
return "clubedit";
}
@RequestMapping("edit")
public String editClub(Club club) throws Exception {
clubService.updateClub(club);
return "redirect:list";
}
}
启动(界面忒丑,重点在于展示功能实现~)
配置Tomcat并启动
启动后首页(太丑了~~~)
点击后进入球队列表页面:(分页显示)
新增操作:
修改(编辑)操作:
删除操作:
总结与展望
前端页面过于丑陋,但好在基本的业务逻辑都能实现。
后期可以考虑美化前端页面,此外我一直想做的工作是整合echarts插件(后期在操作)。