7、SSM 整合伪分布式案例

文章目录


尚硅谷2022版Maven教程-讲师:封捷
老师的md课件

在谷底也要开花。

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

在这里插入图片描述
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 工具

在这里插入图片描述
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值