尚筹网-后台环境搭建01

1.环境搭建总目标:

2.环境配置:

集成开发IDE:IntelliJ IDEA 2021.3.1

开发工具:JDK.1.8.0

管理项目:Maven,版本采用3.6.3,采用多模块开发

数据库:MySql-5.7.23

本地服务器:Tomcat-8.5.20

3.创建工程:

3.1.工程架构图

3.2.工程创建计划

      • atcrowdfunding01-admin-parent
      • groupId:com.atguigu.crowd
      • artifactI:atcrowdfunding01-admin-parent
      • packaging:pom

      • atcrowdfunding02-admin-webui
      • groupId:com.atguigu.crowd
      • artifactI:atcrowdfunding02-admin-webui
      • packaging:war

      • atcrowdfunding03-admin-component
      • groupId:com.atguigu.crowd
      • artifact:atcrowdfunding03-admin-component
      • packaging:jar

      • atcrowdfunding04-admin-entity
      • groupId:com.atguigu.crowd
      • artifactI:atcrowdfunding04-admin-entity
      • packaging:jar

      • atcrowdfunding05-common-util
      • groupId:com.atguigu.crowd
      • artifactId:atcrowdfunding05-common-util
      • packaging:jar

      • atcrowdfunding06-common-reverse
      • groupId:com.atguigu.crowd
      • artifactId:atcrowdfunding06-common-reverse
      • packaging:jar

4.工程之前的依赖关系:

父工程信息:

atcrowdfunding02-admin-webui 依赖于

atcrowdfunding03-admin-component 依赖于

5.创建管理员数据库表:

CREATE DATABASE `project_crowd` CHARACTER SET utf8;
use project_crowd; drop table if exists t_admin;
create table t_admin
(
  id int not null auto_increment, # 主键 
  login_acct varchar(255) not null, # 登录账号 
  user_pswd char(32) not null, # 登录密码
  user_name	varchar(255) not null, # 昵称 
  email	varchar(255) not null,	# 邮件地址 
  create_time	char(19),	# 创建时间 
  primary key (id)
);

6.基于 Maven 的 MyBatis 逆向工程

6.1.pom.xml文件配置

<!-- 依赖 MyBatis 核心包 -->
<dependencies>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.8</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>5.1.8</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

6.2 generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration>
    <!-- mybatis-generator:generate -->
    <context id="atguiguTables" targetRuntime="MyBatis3"> <commentGenerator>
        <!-- 是否去除自动生成的注释 true:是;false:否 -->
        <property name="suppressAllComments" value="true" />
    </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection
                driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/project_crowd"
                userId="root"
                password="123">
        </jdbcConnection>
        <!-- 默认 false,把 JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true 时把
        JDBC DECIMAL
        和 NUMERIC 类型解析为 java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- targetProject:生成 Entity 类的路径 -->
        <javaModelGenerator targetProject=".\src\main\java"
                            targetPackage="com.atguigu.crowd.entity">
            <!-- enableSubPackages:是否让 schema 作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:XxxMapper.xml 映射文件生成的路径 -->
        <sqlMapGenerator targetProject=".\src\main\java" targetPackage="com.atguigu.crowd.mapper">
            <!-- enableSubPackages:是否让 schema 作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetPackage:Mapper 接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetProject=".\src\main\java" targetPackage="com.atguigu.crowd.mapper">
            <!-- enableSubPackages:是否让 schema 作为包的后缀 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 数据库表名字和我们的 entity 类对应的映射指定 -->
        <table tableName="t_admin" domainObjectName="Admin" />
    </context>
</generatorConfiguration>

6.3 执行逆向生成操作的 Maven 命令

mybatis-generator:generate

6.4 逆向工程生成的资源各归各位

WebUI 工程将来在 Tomcat 上运行时,现在 resources 目录下的资源会直接放在 WEB-INF/classes 目录(也就是类路径)下,所以放在 resources 目录下运行的时候更容易找到。

逆向工程生成的实体类放在admin-entity

生成的Mapper接口放在admin-component

生成的Mapeer映射文件放在admin-webui

7.父工程依赖管理

7.1 版本声明

<!--版本指定--> 
<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>

        <!-- 声明属性,对 Spring 的版本进行统一管理 -->
        <atguigu.spring.version>4.3.20.RELEASE</atguigu.spring.version>
        <!-- 声明属性,对 SpringSecurity 的版本进行统一管理 -->
        <atguigu.spring.security.version>4.2.10.RELEASE</atguigu.spring.security.version>
        <jsp-api.version>2.3.0</jsp-api.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring 依赖 -->
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --> <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${atguigu.spring.version}</version>
        </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${atguigu.spring.version}</version>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${atguigu.spring.version}</version>
        </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>
            <!-- https://mvnrepository.com/artifact/cglib/cglib -->

            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2</version>
            </dependency>
            <!-- 数据库依赖 -->
            <!-- MySQL 驱动 --> <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.3</version>
        </dependency>
            <!-- 数据源 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.0.31</version>
            </dependency>

            <!-- MyBatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.2.8</version>
            </dependency>
            <!-- MyBatis 与 Spring 整合 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.2.2</version>
            </dependency>
            <!-- MyBatis 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>4.0.0</version>
            </dependency>
            <!-- 日志 -->

            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>${log4j2.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>${log4j2.version}</version>
            </dependency>

                <dependency>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                    <version>1.7.36</version>
                </dependency>

            <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.11</version>
            </dependency>

            <!-- 其他日志框架的中间转换包 -->
            <!-- https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jul-to-slf4j</artifactId>
                <version>1.7.36</version>
            </dependency>

            <!-- Spring 进行 JSON 数据转换依赖 -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.9.8</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.9.8</version>
            </dependency>
            <!-- JSTL 标签库 -->
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- junit 测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <!-- 引入 Servlet 容器中相关依赖 -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            <!-- JSP 页面使用的依赖 -->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>${jsp-api.version}</version>
                <scope>provided</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.8.5</version>
            </dependency>

            <!-- SpringSecurity 对 Web 应用进行权限管理 -->
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <version>4.2.10.RELEASE</version>
            </dependency>

            <!-- SpringSecurity 配置 -->
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>4.2.10.RELEASE</version>
            </dependency>

            <!-- SpringSecurity 标签库 -->
          <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>4.2.10.RELEASE</version>
        </dependency>

        </dependencies>
    </dependencyManagement>

7.2 依赖信息来源

到专门网站搜索

Maven远程仓库

调试
SpringMVC 需要 jackson 的支持,来处理 JSON 数据。但是 SpringMVC 并没有依赖jackson。所以需要我们自己保证 jar 包之间的兼容性。

8 Spring 整合 MyBatis

8.1 目标

adminMapper 通过 IOC 容器装配到当前组件中后,就可以直接调用它的方法,享受到框架给我们提供的方便

8.2 思路

8.3 操作清单

在子工程中加入搭建环境所需要的具体依赖

准备 jdbc.properties

创建 Spring 配置文件专门配置 Spring 和 MyBatis 整合相关

在 Spring 的配置文件中加载 jdbc.properties 属性文件

配置数据源测试从数据源中获取数据库连接

配置 SqlSessionFactoryBean

装配数据源

指定 XxxMapper.xml 配置文件的位置指定 MyBatis 全局配置文件的位置(可选)

配置 MapperScannerConfigurer

测试是否可以装配 XxxMapper 接口并通过这个接口操作数据库

8.4 操作步骤详解

8.4.1在子工程中加入搭建环境所需的具体依赖子工程:

选择 component 工程。原因是具体依赖和 component 工程相关。

 <!-- Spring 依赖 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
         <!--移除-->
         <exclusions>
             <exclusion>
                 <groupId>commons-logging</groupId>
                 <artifactId>commons-logging</artifactId>
             </exclusion>
         </exclusions>
    </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>

        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
        <!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
    </dependency>
        <!-- MySQL 驱动 --> <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
        <!-- 数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!-- MyBatis -->
        <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
    </dependency>
        <!-- MyBatis 与 Spring 整合 -->	 <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
    </dependency>
        <!-- MyBatis 分页插件 --> <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
    </dependency>
        <!-- Spring 进行 JSON 数据转换依赖 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency> <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
        <!-- JSTL 标签库 --> <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
    </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> 			         <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
    </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
</dependencies>

8.4.2 数据库连接信息

jdbc.properties

jdbc.user=root
jdbc.password=123
jdbc.url=jdbc:mysql://localhost:3306/project_crowd?useUnicode=true&characterEncoding=UTF-8 
jdbc.driver=com.mysql.jdbc.Driver

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

</configuration>

8.4.4 创建 spring-persist-mybatis.xml

8.4.5 Spring 具体配置:第一步配置数据源

在 spring-persist-mybatis.xml 配置文件进行配置

<!-- 加载 jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!-- 连接数据库的用户名 -->
<property name="username" value="${jdbc.user}"/>
<!-- 连接数据库的密码 -->
<property name="password" value="${jdbc.password}"/>
	<!-- 目标数据库的 URL 地址 -->	 
<property name="url" value="${jdbc.url}"/>
<!-- 数据库驱动全类名 -->
<property name="driverClassName" value="${jdbc.driver}"/>
</bean>

在做测试之前先在atcrowdfunding02-admin-webui模块的pom.xml添加依赖包

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <!-- junit 测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
     </dependency>

创建 Spring 的 Junit 测试类

// 指定 Spring 给 Junit 提供的运行器类
@RunWith(SpringJUnit4ClassRunner.class)
// 加载 Spring 配置文件的注解	 
@ContextConfiguration(locations = {"classpath:spring-persist-mybatis.xml"}) 
public class CrowdSpringTest {
    
    @Autowired private DataSource dataSource;
    
    @Test
    public void testDataSource() throws SQLException {
        // 1.通过数据源对象获取数据源连接
        Connection connection = dataSource.getConnection();
        // 2.打印数据库连接
        System.out.println(connection);
    }
}

8.4.6 Spring 具体配置:第二步配置 SqlSessionFactoryBean

<!-- 配置 配置SqlSessionFactoryBean整合Mybatis-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
      <!-- 装配数据源 -->
      <property name="dataSource" ref="dataSource"/>
      <!-- 指定 MyBatis 全局配置文件位置 -->
      <property name="configLocation" value="classpath:mybatis-config.xml"/>
      <!-- 指定 Mapper 配置文件位置 -->
      <property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/> 
</bean>	 

8.4.7 Spring 具体配置:第三步配置 MapperScannerConfigurer

<!-- 配置 MapperScannerConfigurer -->
<!-- 把 MyBatis 创建的 Mapper 接口类型的代理对象扫描到 IOC 容器中 -->
<bean	id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 使用 basePackage 属性指定 Mapper 接口所在包 -->
<property name="basePackage" value="com.atguigu.crowd.mapper"/> </bean>	 

测试

 @Autowired
    private AdminMapper adminMapper;

  @Test
    public void addAdmintest(){
        Admin admin = new Admin(null,"admin","123","叶书文","299@qq.com",null);
       int count = adminMapper.insert(admin);
        System.out.println("受影响的行数"+count);
    }

8.4.8 总结

9 日志系统

9.1 重要意义

系统在运行过程中出了问题就需要通过日志来进行排查,所以我们在上手任何新技术的时候,都要习惯性的关注一下它是如何打印日志的。

9.2 技术选型

9.2.1 总体介绍

9.2.3不同日志系统的整合

9.3 具体操作

9.3.1 初始状态

Spring 使用 commons-logging 日志包。打印的日志是下面这样的。不用细看,截图放在这是为了和后面日志打印的情况对比。

9.3.2 加入 slf4j+logback 依赖信息是:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.7</version>
</dependency> <dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>	 
</dependency>

代码不变,日志情况是:

9.3.3 我们主动打印的日志把查询到的 Admin 对象以日志的方式打印出来,代码如下:

Admin admin = adminMapper.selectByPrimaryKey(1);

/ 获取日志记录对象
Logger logger = LoggerFactory.getLogger(CrowdTest.class);
// 按照 Debug 级别打印日志
logger.debug(admin.toString());

※使用日志打印信息和使用 sysout 打印信息的区别:sysout 如果不删除,那么执行到这里必然会打印;如果使用日志方式打印,可以通过日志级别控制信息是否打印。效果

这里我们看到除了 Druid 数据源打印了两条日志,Spring 和 MyBatis 并没有通过 slf4j 打印日志。所以下一步我们要考虑的就是如何将框架所使用的日志系统统一到 slf4j。

9.3.4 在atcrowdfunding03-admin-component模块 pom.xml更换框架的日志系统

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
         <!--移除-->
         <exclusions>
             <exclusion>
                 <groupId>commons-logging</groupId>
                 <artifactId>commons-logging</artifactId>
             </exclusion>
         </exclusions>
    </dependency>

atcrowdfunding02-admin-webui模块 pom.xml同样的

     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
          <!--移除-->
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

这个时候如果运行程序会抛异常,因为我们把 Spring 依赖的 commons-logging 排除了,而这个依赖是必须有的,不是可选的。

第二步:在atcrowdfunding03-admin-component模块 pom.xml加入转换包

     <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>

打印效果局部:

9.3.5 logback 配置文件 logback

工作时的具体细节可以通过 logback.xml 来配置。

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

<configuration debug="true">
    <!-- 指定日志输出的位置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder>
        <!-- 日志输出的格式 -->
        <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
        <pattern>[%d{HH:mm:ss.SSS}]	[%-5level]	[%thread]	[%logger] [%msg]%n</pattern>
    </encoder>

    </appender>
    <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
    <root level="DEBUG">
        <!-- 指定打印日志的 appender,这里通过“STDOUT”引用了前面配置的 appender -->
        <appender-ref ref="STDOUT" />
    </root>
    <!-- 根据特殊需求指定局部日志级别 -->
    <logger name="com.atguigu.crowd.mapper" level="DEBUG"/>
</configuration>

10 声明式事务

10.1 目标

从事务角度:一个事务方法中包含的多个数据库操作,要么一起提交、要么一起回 滚。也就是说事务方法中的多个数据库操作,有任何一个失败,整个事务全部回滚。从声明式角度:由 Spring 来全面接管数据库事务。用声明式代替编程式。

try {
    // 核心操作前:开启事务(关闭自动提交)
    // 对应 AOP 的前置通知
    connection.setAutoCommit(false);
    // 核心操作
    adminService.updateXxx(xxx, xxx);
    // 核心操作成功:提交事务
    // 对应 AOP 的返回通知
    connection.commit();
}catch(Exception e){
    // 核心操作失败:回滚事务
    // 对应 AOP 的异常通知
    connection.rollBack();
}finally{
    
    // 不论成功还是失败,核心操作终归是结束了
    // 核心操作不管是怎么结束的,都需要释放数据库连接
    // 对应 AOP 的后置通知
    if(connection != null){ connection.close();
   
}

10.2 思路

10.3 操作

10.3.1 加入 AOP 依赖包

<!-- AOP 所需依赖 -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
</dependency>
<!-- AOP 所需依赖 -->
<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
</dependency>

10.3.2 第一步:创建 spring-persist-tx配置文件

10.3.3 第二步:配置事物管理

 <!--配置自动扫描的包:主要是为了把Service扫描到Ioc容器里面-->
    <context:component-scan base-package="com.atguigu.crowd.service"/>

    <!--配置事物管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--装配数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

10.3.4 第三步:配置 AOP

<!-- 配置 AOP 事务切面-->
    <aop:config>
        <!-- 配置切入点表达式 -->
        <!-- public String com.atguigu.crowd.service.AdminService.getXxx(Integer id) -->
        <!--考虑到后面我们整合SpringSecurity,避免UserDetailsService加入事务控制,让切入点表达式定位到ServiceImpl-->
        <aop:pointcut expression="execution(* *..*ServiceImpl.*(..))" id="txPointCut"/>
        <!-- 将事务通知和切入点表达式关联到一起 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>

10.3.5 第四步:配置事务属性

    <!-- 配置事务通知 -->
    <!-- id 属性用于在 aop:advisor 中引用事务通知 -->
    <!-- transaction-manager 属性用于引用事务管理器,如果事务管理器的 bean 的 id 正好是 transactionManager,可以省略这个属性 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- name 属性指定当前要配置的事务方法的方法名 -->
            <!-- 查询的方法通常设置为只读,便于数据库根据只读属性进行相关性能优化 -->
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <!-- 增删改方法另外配置 -->
            <!-- propagation 属性配置事务方法的传播行为 -->
            <!-- 默认值:REQUIRED 表示:当前方法必须运行在事务中,如果没有事务,则开启事务,在自己的事务中运行。如果已经有了已开启的事务,则在当前事务中运行。有可能和其他方法共用同一个事务。 -->
            <!-- 建议值:REQUIRES_NEW 表示:当前方法必须运行在事务中,如果没有事务,则开启事务,在自己的事务中运行。和 REQUIRED 的区别是就算现在已经有了已开启的事务,也一定要开启自己的事务,避免和其他方法共用同一个事务。 -->
            <!-- rollback-for 属性配置回滚的异常 -->
            <!-- 默认值:运行时异常 -->
            <!-- 建议值:编译时异常+运行时异常 -->
            <tx:method	name="save*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception" />
            <tx:method	name="remove*" propagation="REQUIRES_NEW"
                          rollback-for="java.lang.Exception" />
            <tx:method	name="update*" propagation="REQUIRES_NEW"
                          rollback-for="java.lang.Exception" />
        </tx:attributes>
    </tx:advice>

测试

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Override
    public void saveAdmin(Admin admin) {
        adminMapper.insert(admin);
    }
}
package com.crowd;

@RunWith(SpringJUnit4ClassRunner.class)
// 加载 Spring 配置文件的注解
@ContextConfiguration(locations = {"classpath:spring-persist-mybatis.xml","classpath:spring-persist-tx.xml"})
public class CrowdSpringTest {
    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private AdminService adminService;

    @Test
    public void testTx(){
        Admin admin = new Admin(null, "jakc", "123", "萧枫", "422@qq.com", null);
        adminService.saveAdmin(admin);
    }

    @Test
    public void testLog(){
        //1.获取Logger对象,这里传入的Class对象就是当前打印日志的类
        Logger logger = LoggerFactory.getLogger(CrowdSpringTest.class);
        //2.根据不同的日志级别打印日志
        logger.debug("Hello I am Debug level!!!");

        logger.info("Info level!!!");

        logger.warn("Warn leven!!!");

        logger.error("Error level!!!");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值