文章目录
在谷底也要开花。
7、SSM 整合伪分布式案例
第一节 创建工程,引入依赖
1、创建工程
①工程清单
工程名 | 地位 | 说明 |
---|---|---|
demo-imperial-court-ssm-show | 父工程 | 总体管理各个子工程 |
demo-module01-web | 子工程 | 唯一的 war 包工程 |
demo-module02-component | 子工程 | 管理项目中的各种组件 |
demo-module03-entity | 子工程 | 管理项目中的实体类 |
demo-module04-util | 子工程 | 管理项目中的工具类 |
demo-module05-environment | 子工程 | 框架环境所需依赖 |
demo-module06-generate | 子工程 | Mybatis 逆向工程 |
②工程间关系
2、各工程 POM 配置
①父工程
POM 位置如下:
各子工程创建好之后就会有下面配置,不需要手动编辑:
<groupId>pers.tianyu.maven</groupId>
<artifactId>demo-imperial-court-ssm-show</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>demo-module01-web</module>
<module>demo-module02-component</module>
<module>demo-module03-entity</module>
<module>demo-module04-util</module>
<module>demo-module05-environment</module>
<module>demo-module06-generate</module>
</modules>
②Mybatis 逆向工程
POM 位置如下:
<!-- 依赖MyBatis核心包 -->
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
</dependencies>
<!-- 控制Maven在构建过程中相关配置 -->
<build>
<!-- 构建过程中用到的插件 -->
<plugins>
<!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.0</version>
<!-- 插件的依赖 -->
<dependencies>
<!-- 逆向工程的核心依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
③环境依赖工程
POM 位置如下:
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<!-- Spring 持久化层所需依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.3.23</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.9</version>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.13.RELEASE</version>
</dependency>
<!-- Mybatis 和 Spring 的整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.12</version>
</dependency>
④工具类工程
无配置。
⑤实体类工程
无配置。
⑥组件工程
POM 位置如下:
<dependency>
<groupId>pers.tianyu.maven</groupId>
<artifactId>demo-module03-entity</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>pers.tianyu.maven</groupId>
<artifactId>demo-module04-util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>pers.tianyu.maven</groupId>
<artifactId>demo-module05-environment</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- ServletAPI -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
⑦Web 工程
POM 位置如下:
<dependency>
<groupId>pers.tianyu.maven</groupId>
<artifactId>demo-module02-component</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- junit5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<!-- Spring 的测试功能 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
第二节 搭建环境:持久化层
1、物理建模
我们仍然继续使用《第六章 单一架构案例》中创建的数据库和表。
2、Mybatis 逆向工程
逆向工程觉得麻烦可以不用,如果生成的类有xxx.java.1,是数据库串库,数据库有相同名字的表导致串库。
练习项目我是没有用Mybatis 逆向工程
①generatorConfig.xml
②执行逆向生成
③资源归位
[1]Mapper 配置文件
下面罗列各种资源应该存放的位置,排名不分先后:
[2]Mapper 接口
[3]实体类
Mybatis 逆向工程生成的实体类只有字段和 get、set 方法,我们可以自己添加无参构造器、有参构造器、toString() 方法。
3、建立数据库连接
①数据库连接信息
dev.driverClassName=com.mysql.cj.jdbc.Driver
dev.url=jdbc:mysql://localhost:3306/db_imperial_court?userUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
dev.username=root
dev.password=root
dev.initialSize=10
dev.maxActive=20
dev.maxWait=10000
②配置数据源
<!-- 引入jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置Druid数据源-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="driverClassName" value="${dev.driverClassName}"/>
<property name="url" value="${dev.url}"/>
<property name="username" value="${dev.username}"/>
<property name="password" value="${dev.password}"/>
<property name="initialSize" value="${dev.initialSize}"/>
<property name="maxActive" value="${dev.maxActive}"/>
<property name="maxWait" value="${dev.maxWait}"/>
</bean>
③测试
@ExtendWith(SpringExtension.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class ImperialCourtTest {
@Autowired
private DataSource dataSource;
private Logger logger = LoggerFactory.getLogger(ImperialCourtTest.class);
@Test
public void testConnection() throws SQLException {
Connection connection = dataSource.getConnection();
logger.debug(connection.toString());
}
}
TIP
配置文件为什么要放到 Web 工程里面?
Web 工程将来生成 war 包。
war 包直接部署到 Tomcat 运行。
Tomcat 从 war 包(解压目录)查找配置文件最直接。
如果不是把配置文件放在 Web 工程,而是放在 Java 工程,那就等于将配置文件放在了 war 包内的 jar 包中。
配置文件在 jar 包中读取相对困难。
4、Spring 整合 Mybatis
①配置 SqlSessionFactoryBean
目的1:装配数据源
目的2:指定 mybatis 配置文件的位置
<!--配置用于创建SqlSessionFactory的工厂bean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<!-- 装配数据源 -->
<property name="dataSource" ref="dataSource"/>
<!--设置MyBatis配置文件的路径(可以不设置)-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 指定 Mapper 配置文件的位置 -->
<!--<property name="mapperLocations" value="classpath:pers/tianyu/imperial/court/mapper/*Mapper.xml"/>-->
</bean>
②扫描 Mapper 接口
<!-- 配置Mapper接口扫描 -->
<mybatis:scan base-package="pers.tianyu.imperial.court.mapper"/>
③MyBatis配置文件
<?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="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--实体类别名-->
<typeAliases>
<package name="pers.tianyu.imperial.court.entity"/>
</typeAliases>
</configuration>
④测试
@Autowired
private EmpMapper empMapper;
@Test
public void testEmpMapper() {
List<Emp> empList = empMapper.selectByExample(new EmpExample());
for (Emp emp : empList) {
System.out.println("emp = " + emp);
}
}
第三节 搭建环境:事务控制
1、声明式事务配置
<!--扫面组件-->
<context:component-scan base-package="pers.tianyu.imperial.court.service">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--事务管理器-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启事务注解驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
2、注解写法
①查询操作
@Transactional(readOnly = true)
②增删改操作
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
TIP
在具体代码开发中可能会将相同设置的 @Transactional 注解提取到 Service 类上。
第四节 搭建环境:表述层
1、设定 Web 工程
略
2、web.xml 配置
①配置 ContextLoaderListener
<!-- 配置监听器,用于加载applicationContion.xml文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--自定义Spring配置文件的位置和名称-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
②配置 DispatcherServlet
<!-- 配置前端控制器 -->
<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.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>
③配置 CharacterEncodingFilter
<!-- 配置springMVC的编码过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
④配置 HiddenHttpMethodFilter
<!-- 配置springMVC获取请求方式过滤器,配合RESTful风格使用 -->
<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>
3、显示首页
①配置 SpringMVC
[1]标配
<!-- 开启 SpringMVC 的注解驱动功能 -->
<mvn:annotation-driven />
<!-- 让 SpringMVC 对没有 @RequestMapping 的请求直接放行 -->
<mvc:default-servlet-handler />
[2]配置视图解析相关
<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
注意:需要我们自己手动创建 templates 目录。
[3]配置自动扫描的包
<!-- 开启注解扫描,只扫描mvc注解 -->
<context:component-scan base-package="pers.tianyu.imperial.court.controller"/>
②配置 view-controller 访问首页
<!--视图控制器-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
③创建首页模板文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!-- @{/auth} 解析后:/demo/auth -->
<form th:action="@{/auth/login}" method="post">
<!-- th:text 解析表达式后会替换标签体 -->
<!-- ${attrName} 从请求域获取属性名为 attrName 的属性值 -->
<p th:text="${message}"></p>
<p th:text="${systemMessage}"></p>
账号:<input type="text" name="loginAccount"/><br/>
密码:<input type="password" name="loginPassword"><br/>
<button type="submit">进宫</button>
</form>
</body>
</html>
第五节 搭建环境:辅助功能
1、登录失败异常
public class LoginFailedException extends RuntimeException{
public LoginFailedException() {
}
public LoginFailedException(String message) {
super(message);
}
public LoginFailedException(String message, Throwable cause) {
super(message, cause);
}
public LoginFailedException(Throwable cause) {
super(cause);
}
public LoginFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
2、常量类
public class ImperialCourtConst {
public static final String LOGIN_FAILED_MESSAGE = "账号、密码错误,不可进宫!";
public static final String ACCESS_DENIED_MESSAGE = "宫闱禁地,不得擅入!";
public static final String LOGIN_EMP_ATTR_NAME = "loginInfo";
public static final String MEMORIALS_LIST = "memorialsList";
public static final String MEMORIALS = "memorials";
}
3、MD5 工具
4、日志配置文件
第六节 业务功能:登录、退出
1、AuthController
@Controller
public class AuthController {
@Autowired
private EmpService empService;
@RequestMapping("/auth/login")
public String doLogin(@RequestParam("loginAccount") String loginAccount, @RequestParam("loginPassword") String loginPassword, HttpSession session, Model model) {
// 1、尝试查询登录信息
Emp emp = empService.getEmpByLogin(loginAccount, loginPassword);
// 2、判断登录是否成功
if (emp == null) {
// 3、如果登录失败则回到登录页面显示提示消息
model.addAttribute("message", ImperialCourtConst.ACCESS_DENIED_MESSAGE);
return "index";
} else {
// 4、如果登录成功则将登录信息存入 Session 域
session.setAttribute(ImperialCourtConst.LOGIN_EMP_ATTR_NAME,emp);
return "redirect:/work/showMemorialsDigestList";
}
}
@RequestMapping("/auth/logout")
public String doLogout(HttpSession session){
// 1、将 HttpSession 对象强制失效
session.invalidate();
// 2、回到首页
return "redirect:/";
}
}
2、EmpService
@Service
@Transactional(readOnly = true)
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public Emp getEmpByLogin(String loginAccount, String loginPassword) {
// 1、密码加密
String encodedLoginPassword = MD5Util.encode(loginPassword);
// 2、查询方式封装查询条件
return empMapper.selectEmpByLoginAccount(loginAccount, encodedLoginPassword);
}
}
3、EmpMapper
public interface EmpMapper {
Emp selectEmpByLoginAccount(@Param("loginAccount") String loginAccount, @Param("loginPassword") String loginPassword);
}
4、EmpMapper.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="pers.tianyu.imperial.court.mapper.EmpMapper">
<select id="selectEmpByLoginAccount" resultType="emp">
SELECT emp_id empId, emp_name empName, emp_position empPosition, login_account loginAccount, login_password loginPassword FROM t_emp
<where>
login_account = #{loginAccount} and login_password = #{loginPassword}
</where>
</select>
</mapper>
第七节 业务功能:奏折显示
1、WorkController
@Controller
public class WorkController {
@Autowired
private MemorialsService memorialsService;
@RequestMapping("/work/showMemorialsDigestList")
public String showMemorialsDigestList(Model model){
// 1、调用 Service 方法查询数据
List<Memorials> memorialsList = memorialsService.getAllMemorialsDigest();
// 2、将查询得到的数据存入请求域
model.addAttribute(ImperialCourtConst.MEMORIALS_LIST,memorialsList);
// 3、渲染视图
return "memorials-list";
}
}
2、MemorialsService
@Service
public class MemorialsServiceImpl implements MemorialsService {
@Autowired
private MemorialsMapper memorialsMapper;
@Override
@Transactional(readOnly = true)
public List<Memorials> getAllMemorialsDigest() {
// 1、查询
return memorialsMapper.selectAllMemorialsDigest();
}
}
3、MemorialsMapper
public interface MemorialsMapper {
List<Memorials> selectAllMemorialsDigest();
}
4、MemorialsMapper.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="pers.tianyu.imperial.court.mapper.MemorialsMapper">
<select id="selectAllMemorialsDigest" resultType="memorials">
SELECT memorials_id memorialsId,
memorials_title memorialsTitle,
CONCAT(LEFT(memorials_content, 10), '...') memorialsContent,
emp_name memorialsEmpName,
memorials_create_time memorialsCreateTime,
memorials_status memorialsStatus
FROM t_memorials m
LEFT JOIN t_emp e ON m.memorials_emp = e.emp_id
</select>
</mapper>
5、memorials-list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>乾清宫</title>
<style type="text/css">
table {
border-collapse: collapse;
margin: 0px auto 0px auto;
}
table th, td {
border: 1px solid black;
text-align: center;
}
div {
text-align: right;
}
</style>
</head>
<body>
<!-- 登录信息部分 -->
<div>
<span th:if="${session.loginInfo.empPosition == 'emperor'}">恭请皇上圣安</span>
<span th:if="${session.loginInfo.empPosition == 'minister'}">给<span th:text="${session.loginInfo.empName}">XXX</span>大人请安</span>
<a th:href="@{/auth/logout}">退朝</a>
</div>
<!-- 数据显示部分 -->
<table>
<thead>
<tr>
<th>奏折标题</th>
<th>内容摘要</th>
<th>上疏大臣</th>
<th>上疏时间</th>
<th>奏折状态</th>
<th>奏折详情</th>
</tr>
</thead>
<tbody th:if="${#lists.isEmpty(memorialsList)}">
<tr>
<td colspan="6">没有人上过折子</td>
</tr>
</tbody>
<tbody th:if="${not #lists.isEmpty(memorialsList)}">
<tr th:each="memorials : ${memorialsList}">
<td th:switch="${memorials.memorialsStatus}">
<span th:text="${memorials.memorialsTitle}" th:case="0" style="color: red;">奏折标题</span>
<span th:text="${memorials.memorialsTitle}" th:case="1" style="color: blue;">奏折标题</span>
<span th:text="${memorials.memorialsTitle}" th:case="2">奏折标题</span>
</td>
<td th:switch="${memorials.memorialsStatus}">
<span th:text="${memorials.memorialsContentDigest}" th:case="0" style="color: red;">内容摘要</span>
<span th:text="${memorials.memorialsContentDigest}" th:case="1" style="color: blue;">内容摘要</span>
<span th:text="${memorials.memorialsContentDigest}" th:case="2">内容摘要</span>
</td>
<td th:switch="${memorials.memorialsStatus}">
<span th:text="${memorials.memorialsEmpName}" th:case="0" style="color: red;">上疏大臣</span>
<span th:text="${memorials.memorialsEmpName}" th:case="1" style="color: blue;">上疏大臣</span>
<span th:text="${memorials.memorialsEmpName}" th:case="2">上疏大臣</span>
</td>
<td th:switch="${memorials.memorialsStatus}">
<span th:text="${memorials.memorialsCreateTime}" th:case="0" style="color: red;">上疏时间</span>
<span th:text="${memorials.memorialsCreateTime}" th:case="1" style="color: blue;">上疏时间</span>
<span th:text="${memorials.memorialsCreateTime}" th:case="2">上疏时间</span>
</td>
<td th:switch="${memorials.memorialsStatus}">
<span th:case="0" style="color: red;">未读</span>
<span th:case="1" style="color: blue;">已读</span>
<span th:case="2">已批示</span>
</td>
<td>
<a th:href="@{'/work/showMemorialsDetail/'+${memorials.memorialsId}}">奏折详情</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
第八节 业务功能:奏折详情
1、WorkController
@RequestMapping("/work/showMemorialsDetail/{memorialsId}")
public String showMemorialsDetail(@PathVariable("memorialsId") String memorialsId, Model model){
// 根据 memorialsId 从 Service 中查询 Memorials 对象
Memorials memorials = memorialsService.getMemorialsDetailById(memorialsId);
// 获取当前奏折对象的状态
Integer memorialsStatus = memorials.getMemorialsStatus();
// 判断奏折状态
if(memorialsStatus == 0){
// 更新奏折状态:数据库修改
memorialsService.updateMemorialsStatusToRead(memorialsId);
// 更新奏折状态:当前对象修改
memorials.setMemorialsStatus(1);
}
// 将 Memorials 对象存入请求域
model.addAttribute(ImperialCourtConst.MEMORIALS,memorials);
// 解析渲染视图
return "memorials_detail";
}
2、MemorialsService
@Override
@Transactional(readOnly = true)
public Memorials getMemorialsDetailById(String memorialsId) {
return memorialsMapper.selectMemorialsById(memorialsId);
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
public void updateMemorialsStatusToRead(String memorialsId) {
memorialsMapper.updateMemorialsStatusToRead(memorialsId);
}
3、MemorialsMapper
Memorials selectMemorialsById(@Param("memorialsId") String memorialsId);
void updateMemorialsStatusToRead(@Param("memorialsId") String memorialsId);
4、MemorialsMapper.xml
<select id="selectMemorialsById" resultType="memorials">
SELECT memorials_id memorialsId,
memorials_title memorialsTitle,
memorials_content memorialsContent,
emp_name memorialsEmpName,
memorials_create_time memorialsCreateTime,
feedback_time feedbackTime,
feedback_content feedbackContent,
memorials_status memorialsStatus FROM t_memorials m LEFT JOIN t_emp e ON
m.memorials_emp = e.emp_id
<where>memorials_id = #{memorialsId}</where>
</select>
<update id="updateMemorialsStatusToRead">
UPDATE t_memorials SET memorials_status = 1
<where>memorials_id = #{memorialsId}</where>
</update>
5、memorials_detail.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
table {
border-collapse: collapse;
margin: 0px auto 0px auto;
}
table th, td {
border: 1px solid black;
text-align: center;
}
div {
text-align: right;
}
</style>
</head>
<body>
<!-- 登录信息部分 -->
<div>
<span th:if="${session.loginInfo.empPosition == 'emperor'}">恭请皇上圣安</span>
<span th:if="${session.loginInfo.empPosition == 'minister'}">给<span th:text="${session.loginInfo.empName}">XXX</span>大人请安</span>
<a th:href="@{/auth/logout}">退朝</a>
</div>
<table>
<tr>
<td>奏折标题</td>
<td th:text="${memorials.memorialsTitle}"></td>
</tr>
<tr>
<td>上疏大臣</td>
<td th:text="${memorials.memorialsEmpName}"></td>
</tr>
<tr>
<td>上疏时间</td>
<td th:text="${memorials.memorialsCreateTime}"></td>
</tr>
<tr>
<td>奏折内容</td>
<td th:text="${memorials.memorialsContent}"></td>
</tr>
<tr th:if="${memorials.memorialsStatus == 2}">
<td>批复时间</td>
<td th:text="${memorials.feedbackTime}"></td>
</tr>
<tr th:if="${memorials.memorialsStatus == 2}">
<td>批复时间</td>
<td th:text="${memorials.feedbackContent}"></td>
</tr>
</table>
<div th:if="${memorials.memorialsStatus != 2}">
<form th:action="@{'/work/feedBack/'+${memorials.memorialsId}}" method="post">
<textarea name="feedbackContent"></textarea>
<button type="submit">御批</button>
</form>
</div>
<a th:href="@{/work/showMemorialsDigestList}">返回列表</a>
</body>
</html>
第九节 业务功能:奏折批复
1、WorkController
@RequestMapping("/work/feedBack/{memorialsId}")
public String feedBack(@PathVariable("memorialsId") String memorialsId, @RequestParam("feedbackContent") String feedbackContent){
// 执行更新
memorialsService.updateMemorialsFeedBack(memorialsId,feedbackContent);
// 重定向回显示奏折列表页面
return "redirect:/work/showMemorialsDigestList";
}
2、memorialsService
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
public void updateMemorialsFeedBack(String memorialsId, String feedbackContent) {
String feedbackTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
memorialsMapper.updateMemorialsFeedBack(feedbackContent, feedbackTime, memorialsId);
}
3、memorialsService.xml
<update id="updateMemorialsFeedBack">
UPDATE t_memorials SET memorials_status = 2, feedback_content = #{feedbackContent}, feedback_time =
#{feedbackTime}
<where>memorials_id = #{memorialsId}</where>
</update>
第十节 业务功能:登录检查
1、LoginInterceptor
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object attribute = session.getAttribute(ImperialCourtConst.LOGIN_EMP_ATTR_NAME);
//判断什么情况下没有登录
if(attribute == null){
request.setAttribute("systemMessage",ImperialCourtConst.ACCESS_DENIED_MESSAGE);
request.getRequestDispatcher("/").forward(request, response);
return false;
}else {
//放行:判断什么情况下登录
return true;
}
}
}
2、springmvc.xml
<!-- 自定义的拦截器 -->
<bean class="pers.tianyu.imperial.court.interceptor.LoginInterceptor" id="interceptor"></bean>
<!--配置登录拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- /**:拦截所有,/*拦截一层目录结构请求 -->
<mvc:mapping path="/work/**"/>
<!-- 自定义的拦截器引用 -->
<ref bean="interceptor"></ref>
</mvc:interceptor>
</mvc:interceptors>