SSM框架实例(单表查询)
SSM,即Spring+Spring MVC+Mybatis框架
要求:
基于SSM框架的做一个关于教室信息的增删改查
步骤:
一、创建数据库并添加部分测试数据
该实例使用的是MySQL,DBMS为sqlyog
建立表,注意字符集设置:
添加部分测试数据:
二、创建Maven项目
略
三、配置依赖包
注意,同类型依赖包版本必需一致
以及mysql-connector-java版本要与本地mysql版本对应,否则会报错。
<dependencies>
<!--该依赖包是spring框架必需-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--该依赖包是jdbc连接必需-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--该依赖包是spring mvc框架必需-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--该依赖包是mybatis框架必需-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--该依赖包是spring和mybatis整合必需-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!--该依赖包是mysql数据库连接必需-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--该依赖包是连接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.8.0</version>
</dependency>
<!--该依赖包是简化实体类getter、setter、toString-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!--该依赖包是jstl工具类-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
以及为了保证找到xml配置文件所必需配置(代码放在build里面):
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
``
四、编写配置文件
①db.properties
jdbc.driver = com.mysql.cj.jdbc.Driver (这里注意,较新版本的mysql要添加.cj,但旧版本一定不要添加,否则报错,复制时记得删除括号及内容)
jdbc.url = jdbc:mysql://localhost:3306/数据库名?useUnicode=true&useSSL=false&characterEncoding=UTF-8&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
jdbc.username = 数据库账号
jdbc.password = 数据库密码
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
② spring-config.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
http://www.springframework.org/schema/tx/spring-tx.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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--上面建议直接全部复制,包含了切面、事务管理必需的配置-->
<!--自动扫描注解-->
<context:component-scan base-package="cn.edu.ujn.guoxy392"></context:component-scan>
<!--数据库的数据源-->
<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxTotal" value="${jdbc.maxTotal}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="initialSize" value="${jdbc.initialSize}" />
</bean>
<!-- 事务管理器,依赖于数据源 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--配置MyBatis工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="mapperLocations" value="classpath:cn/edu/ujn/guoxy392/dao/*.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.edu.ujn.guoxy392.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
③mybaties-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>
<!-- 延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="false" />
<!-- 配置积极加载or按需加载 -->
<setting name="aggressiveLazyLoading" value="true" />
<setting name="mapUnderscoreToCamelCase" value="true" />
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
</configuration>
④springmvc-config.xml
<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"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置包扫描器 (Spring配置文件中已经配置,此处可以省略)-->
<context:component-scan base-package="cn.edu.ujn.guoxy392" />
<!-- 加载注解驱动 -->
<mvc:annotation-driven />
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven>
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置自定义转换器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.edu.ujn.guoxy392.converter.DateConverter"></bean>
</set>
</property>
</bean>
</beans>
⑤web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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-config.xml</param-value>
</init-param>
<!-- 表示容器在启动时立即加载Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<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>
</web-app>
五、建立文件结构
如图:
entity:实体类层
dao:数据库操作层
service:业务逻辑层
controller:控制层(前后端交互)
converter:自定义的转换类
六、实体类
根据数据库内字段,如下:
package cn.edu.ujn.guoxy392.entity;
import lombok.Data;
import java.util.Date;
@Data
public class Classroom {
private int id;
private String roomname;
private String roomnum;
private String roomtype;
private int seatnum;
private String remark;
private Date addtime;
}
为了方便,与字段名一致
七、Dao层
dao层包含了xml形式的映射文件和接口
接口:包含了所要写的所有对数据库操作的方法
package cn.edu.ujn.guoxy392.dao;
import cn.edu.ujn.guoxy392.entity.Classroom;
import java.util.List;
public interface ClassroomMapper {
public int addClassroom(Classroom classroom);
public int deleteClassroomById(int id);
public int updateClassroomById(Classroom classroom);
public Classroom findClassroomById(int id);
public List<Classroom> findAll();
}
xml映射文件:
注意,namespace地址必须是上面的接口地址,每个标签(insert、delete等)的id与接口内方法名一致。
<?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.edu.ujn.guoxy392.dao.ClassroomMapper">
<insert id="addClassroom" parameterType="cn.edu.ujn.guoxy392.entity.Classroom">
insert into info_classroom(roomname,roomnum,roomtype,seatnum,remark,addtime) values(#{roomname},#{roomnum},#{roomtype},#{seatnum},#{remark},#{addtime})
</insert>
<delete id="deleteClassroomById" parameterType="int">
delete from info_classroom where id = #{id}
</delete>
<update id="updateClassroomById" parameterType="cn.edu.ujn.guoxy392.entity.Classroom">
update info_classroom
<set>
<if test="roomname!=null and roomname!=''">
roomname = #{roomname},
</if>
<if test="roomnum!=null and roomnum!=''">
roomnum = #{roomnum},
</if>
<if test="roomtype!=null and roomtype!=''">
roomtype = #{roomtype},
</if>
<if test="seatnum!=null and seatnum!=0">
seatnum = #{seatnum},
</if>
<if test="remark!=null and remark!=''">
remark = #{remark},
</if>
</set>
where id = #{id}
</update>
<select id="findAll" resultType="cn.edu.ujn.guoxy392.entity.Classroom">
select * from info_classroom
</select>
<select id="findClassroomById" parameterType="int" resultType="cn.edu.ujn.guoxy392.entity.Classroom">
select * from info_classroom where id = #{id}
</select>
</mapper>
八、service层
业务逻辑层,包含接口、实现类
接口:
package cn.edu.ujn.guoxy392.service;
import cn.edu.ujn.guoxy392.entity.Classroom;
import java.util.List;
public interface IClassroomService {
public int addClassroom(Classroom classroom);
public int deleteClassroomById(int id);
public int updateClassroomById(Classroom classroom);
public Classroom findClassroomById(int id);
public List<Classroom> findAll();
}
实现类:
注意添加注解
package cn.edu.ujn.guoxy392.service;
import cn.edu.ujn.guoxy392.dao.ClassroomMapper;
import cn.edu.ujn.guoxy392.entity.Classroom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("classroomService")
public class ClassroomServiceImpl implements IClassroomService{
@Autowired
private ClassroomMapper classroomMapper;
@Override
public int addClassroom(Classroom classroom) {
return classroomMapper.addClassroom(classroom);
}
@Override
public int deleteClassroomById(int id) {
return classroomMapper.deleteClassroomById(id);
}
@Override
public int updateClassroomById(Classroom classroom) {
return classroomMapper.updateClassroomById(classroom);
}
@Override
public Classroom findClassroomById(int id) {
return classroomMapper.findClassroomById(id);
}
@Override
public List<Classroom> findAll() {
return classroomMapper.findAll();
}
}
九、controller层
package cn.edu.ujn.guoxy392.controller;
import cn.edu.ujn.guoxy392.entity.Classroom;
import cn.edu.ujn.guoxy392.service.IClassroomService;
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 java.util.List;
@Controller
@RequestMapping("/classroom")
public class ClassroomHandler {
@Autowired
private IClassroomService iClassroomService;
@RequestMapping("/findClassroomById")
public String findClassroomById(Model model){
Classroom classroom = iClassroomService.findClassroomById(1);
model.addAttribute("classroom", classroom);
return "main";
}
@RequestMapping("addClassroom")
public String addClassroom(Classroom classroom){
iClassroomService.addClassroom(classroom);
return "redirect:/classroom/findAll";
}
@RequestMapping("/deleteClassroomById")
public String deleteClassroomById(int id){
iClassroomService.deleteClassroomById(id);
return "redirect:/classroom/findAll";
}
@RequestMapping("/updateClassroomById")
public String updateClassroomById(Classroom classroom){
iClassroomService.updateClassroomById(classroom);
return "redirect:/classroom/findAll";
}
@RequestMapping("/findAll")
public String findAll(Model model){
List<Classroom> list = iClassroomService.findAll();
model.addAttribute("classroom",list);
return "show";
}
}
十、自定义转换类
package cn.edu.ujn.guoxy392.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String, Date> {
private String pattern = "yyyy-mm-dd HH:mm:ss";
@Override
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
try {
return sdf.parse(s);
} catch (ParseException e) {
throw new IllegalArgumentException(
"无效的日期格式,请使用这种格式:"+pattern
);
}
}
}
十一、前端
show:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2020/10/29
Time: 19:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Welcome!</h1>
<table border=1>
<tr>
<td align="center">编号</td>
<td align="center">教室名</td>
<td align="center">教室编号</td>
<td align="center">教室类型</td>
<td align="center">座位数量</td>
<td align="center">备注</td>
<td align="center">添加时间</td>
<td align="center">操作</td>
</tr>
<c:forEach items="${classroom}" var="classroom">
<tr>
<td align="center">${classroom.id}</td>
<td align="center">${classroom.roomname}</td>
<td align="center">${classroom.roomnum}</td>
<td align="center">${classroom.roomtype}</td>
<td align="center">${classroom.seatnum}</td>
<td align="center">${classroom.remark}</td>
<td align="center">${classroom.addtime}</td>
<td align="center"><a href="/classroom/deleteClassroomById?id=${classroom.id}">删除</a> <a href="/updateClassroom.jsp?id=${classroom.id}&roomname=${classroom.roomname}&roomnum=${classroom.roomnum}&roomtype=${classroom.roomtype}&seatnum=${classroom.seatnum}&remark=${classroom.remark}">修改</a> </td>
</tr>
</c:forEach>
</table>
<br/>
<a href="/addClassroom.jsp">添加新用户</a>
</body>
</html>
addClassroom:
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2020/11/17
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</title>
</head>
<body>
<form action="/classroom/addClassroom">
教室名:<input type="text" name="roomname">
教室编号:<input type="text" name="roomnum">
教室类型:<input type="text" name="roomtype">
座位数量:<input type="text" name="seatnum">
备注:<input type="text" name="remark">
添加时间(yyyy-MM-DD HH:MM:SS):<input type="text" name="addtime">
<input type="submit" value="提交">
</form>
</body>
</html>
updateClassroom:
<%--
Created by IntelliJ IDEA.
User: asus
Date: 2020/11/17
Time: 10:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/classroom/updateClassroomById">
<input type="hidden" name="id" value="${param.id}" readonly="readonly">
教室名:<input type="text" name="roomname" value="${param.roomname}">
教室编号:<input type="text" name="roomnum" value="${param.roomnum}">
教室类型:<input type="text" name="roomtype" value="${param.roomtype}">
座位数量:<input type="text" name="seatnum" value="${param.seatnum}">
备注:<input type="text" name="remark" value="${param.remark}">
<input type="submit" value="提交">
</form>
</body>
</html>