项目实战——尚筹网项目笔记

    科技2022-08-06  107

    文章目录

    1. 基础环境搭建1.1 创建工程1.2 创建数据库表1.3 MyBatis逆向工程1.4 父工程依赖管理1.5 Spring整合Mybatis1.6 日志系统1.7 声明式事务1.8 表述层

    1. 基础环境搭建

    1.1 创建工程

    更改右键目录:window-perspective-customize perspective-menu visibility-file-new-勾选需要模块创建父工程:new maven project-create a simple project-finish group id:com.cc.crowdfunding artifact id:mycrowdfunding01-admin-parent packaging:pom

    创建子工程webui:new maven module-module name:mycrowdfunding02-admin-webui-maven-archetype-webapp,注意是web工程

    创建子工程component:new maven module-module name:mycrowdfunding03-admin-component-maven-archetype-quickstart

    创建子工程entity:new maven module-module name:mycrowdfunding04-admin-entity-maven-archetype-quickstart

    创建独立工程:new maven project-create a simple project-finish

    group id:com.cc.crowdfunding artifact id:mycrowdfunding05-comon-util packaging:jar 创建独立工程:new maven project-create a simple project-finish group id:com.cc.crowdfunding artifact id:mycrowdfunding06-comon-reverse packaging:jar 配置模块依赖关系(配置pom文件): webui 依赖 componet <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding03-admin-component</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> componet 依赖 entiy componet 依赖 util <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding04-admin-entity</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding05-common-util</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> 结果

    1.2 创建数据库表

    CREATE DATABASE `db_crowd` CHARACTER SET utf8; USE db_crowd; DROP TABLE IF EXISTS t_admin; CREATE TABLE t_admin ( id INT NOT NULL AUTO_INCREMENT, # 主键 login_acct VARCHAR(25) NOT NULL, # 登录账号 user_pswd CHAR(32) NOT NULL, # 登录密码 user_name VARCHAR(25) NOT NULL, # 昵称 email VARCHAR(25) NOT NULL, # 邮件地址 create_time CHAR(19), # 创建时间 PRIMARY KEY (id) );

    1.3 MyBatis逆向工程

    reverse工程中编写:pom.xml,注意因为使用mysql8.0+版本,把mysql-connector-java改成了8.0.15,否则是5.1.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.cc.crowdfunding</groupId> <artifactId>mycrowdfunding06-common-reverse</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 依赖 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>8.0.15</version> </dependency> </dependencies> </plugin> </plugins> </build> </project> reverse工程中编写:generatorConfig.xml,注意mysql-connector-java版本是8.0.15时,jdbcConnection-connectionURL需要添加时区 <?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/db_crowd?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT" userId="root" password="0824"> </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.cc.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.cc.crowd.mapper"> <!-- enableSubPackages:是否让 schema 作为包的后缀 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:Mapper 接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetProject=".\src\main\java" targetPackage="com.cc.crowd.mapper"> <!-- enableSubPackages:是否让 schema 作为包的后缀 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 数据库表名字和我们的 entity 类对应的映射指定 --> <table tableName="t_admin" domainObjectName="Admin" /> </context> </generatorConfiguration>

    执行逆向生成操作的 Maven 命令:pom.xml右键 --- run as-maven build --- Goals:mybatis-generator:generate

    会在指定目录的entity包下生成Admin.java、AdminExample.java,在mapper包下生成AdminMapper.java、AdminMapper.xml,在Admin.java补充有参无参构造器+tostring方法

    将生成的逆向工程文件放到子工程中:com.cc.crowd.entity包整体移动到entity子工程下;component子工程src/main/java目录下创建com.cc.crowd.mapper包,将AdminMapper.java移过来;webui子工程src/main/resources目录下创建mybatis.mapper包,将AdminMapper.xml移过来

    1.4 父工程依赖管理

    parent工程 — pom.xml

    <?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.cc.crowdfunding</groupId> <artifactId>mycrowdfunding01-admin-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>mycrowdfunding02-admin-webui</module> <module>mycrowdfunding03-admin-component</module> <module>mycrowdfunding04-admin-entity</module> </modules> <properties> <!-- 声明属性, 对 Spring 的版本进行统一管理 --> <atguigu.spring.version>4.3.20.RELEASE</atguigu.spring.version> <!-- 声明属性, 对 SpringSecurity 的版本进行统一管理 --> <atguigu.spring.security.version>4.2.10.RELEASE</atguigu.spring.security.version> </properties> <dependencyManagement> <dependencies> <!-- 1.Spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${atguigu.spring.version}</version> </dependency> <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> <!-- 使aop正常工作 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> <!-- 2.数据库依赖 --> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</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> <!-- 3.日志依赖 --> <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> <!-- 其他日志框架的中间转换包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- 4.其他依赖 --> <!-- 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> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</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>jsp-api</artifactId> <version>2.1.3-b06</version> <scope>provided</scope> </dependency> <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <!-- SpringSecurity 标签库 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>4.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.webjars.bower</groupId> <artifactId>jquery</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>4.2.10.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>4.2.10.RELEASE</version> </dependency> </dependencies> </dependencyManagement> </project>

    1.5 Spring整合Mybatis

    在component子工程中加入搭建环境所需要的具体依赖 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding01-admin-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding03-admin-component</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mycrowdfunding03-admin-component</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding04-admin-entity</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding05-common-util</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- 1.Spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <!-- 使aop正常工作 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> </dependency> <!-- 2.数据库依赖 --> <!-- 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> <!-- 3.日志依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <!-- 其他日志框架的中间转换包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <!-- 4.其他依赖 --> <!-- Spring 进行 JSON 数据转换依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> <!-- JSTL 标签库 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> </dependency> <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <!-- SpringSecurity 标签库 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> </project> 在webui子工程中加入搭建环境所需要的具体依赖 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding01-admin-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding02-admin-webui</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>mycrowdfunding02-admin-webui Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.cc.crowdfunding</groupId> <artifactId>mycrowdfunding03-admin-component</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <finalName>mycrowdfunding02-admin-webui</finalName> </build> </project> 在webui工程下准备jdbc.proerties,注意是mysql8的版本 jdbc.user=root jdbc.password=0824 jdbc.url=jdbc:mysql://localhost:3306/db_crowd?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT jdbc.driver=com.mysql.cj.jdbc.Driver 在webui工程下准备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> 在webui工程下创建配置文件spring-persist-mybatis.xml专门配置 Spring 和 MyBatis 整合相关 <?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:context="http://www.springframework.org/schema/context" 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-4.3.xsd"> <!--1.配置数据源--> <!--加载外部属性文件--> <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder> <!-- 配置数据源 --> <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> <!-- 2.配置SqlSessionFactoryBean整合Mybatis --> <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--指定Mybatis全局配置文件的位置--> <property name="configLocation" value="classpath:mybatis-config.xml"></property> <!--指定Mapper.xml的位置--> <property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"></property> <!--装配数据源--> <property name="dataSource" ref="dataSource"></property> <!-- 配置插件--> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageHelper"> <property name="properties"> <props> <!--配置数据库方言,告诉PageHelper当前使用的数据库--> <prop key="dialect">mysql</prop> <!--配置页码的合理化修正--> <prop key="reasonable">true</prop> </props> </property> </bean> </array> </property> </bean> <!-- 3.配置MapperScannerConfigurer来扫描Mapper接口所在的包--> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.cc.crowd.mapper"></property> </bean> </beans> 文件结构(logback.xml是后面创建的)

    测试数据库连接与接口连接,创建CrowdTest.java //Spring整合junit进行测试模块 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-persist-mybatis.xml"}) public class CrowdTest { @Autowired private DataSource dataSource; @Autowired private AdminMapper adminMapper; @Test public void testConnection() throws SQLException { // 1.通过数据源对象获取数据源连接 Connection con=dataSource.getConnection(); // 2.打印数据库连接 System.out.println(con); } @Test public void testInsertAdmin() { Admin admin=new Admin(null, "tom", "123456", "汤姆", "tom@qq.com", null); int count=adminMapper.insert(admin); System.out.println("受影响的行数:"+count); } }

    1.6 日志系统

    不同日志系统的整合

    转换日志框架

    修改日志框架,修改component子工程下pom.xml,添加如下依赖

    <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <!-- 其他日志框架的中间转换包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> 由于webui工程依赖component工程,需要把两个工程中Spring自带的comons-loging日志框架移除 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> webui:pom.xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> 配置日志框架 <?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <!-- 指定日志输出的位置 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <!-- 日志输出的格式 --> <!-- 按照顺序分别是:时间、日志级别 -5占5个字符、线程名称、打印日志的类、日志主体内容、换行 --> <pattern>[%d{HH:mm:ss}] [%-5level ] [%thread ] [%logger] %msg%n</pattern> </encoder> </appender> <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR --> <root level="INFO"> <!-- 指定打印日志的appender,这里通过"STDOUT"引用了前面配置的appender --> <appender-ref ref="STDOUT"/> </root> <!-- 根据特殊需求指定局部日志级别:sql需要debug级别才会打印日志--> <logger name="com.cc.crowd.mapper" level="DEBUG"/> </configuration>

    1.7 声明式事务

    从事务角度:一个事务方法中包含的多个数据库操作,要么一起提交、要么一起回滚。也就是说事务方法中的多个数据库操作,有任何一个失败,整个事务全部回滚。 从声明式角度:由 Spring 来全面接管数据库事务。用声明式代替编程式。 编程式事务 try { // 核心操作前:开启事务(关闭自动提交) // 对应 AOP 的前置通知 connection.setAutoCommit(false); // 核心操作 adminService.updateXXX(x,x); // 核心操作成功:提交事务 // 对应 AOP 的返回通知(寿终正寝) connection.commit(); }catch(Exception e){ // 核心操作失败:回滚事务 // 对应 AOP 的异常通知(死于非命) connection.rollBack(); }finally{ // 不论成功还是失败,核心操作终归是结束了 // 核心操作不管是怎么结束的,都需要释放数据库连接 // 对应 AOP 的后置通知(料理后事) if(connection != nul){ connection.close(); } }

    声明式事务

    基于注解的声明式事务

    @Transactional(xxx) public class adminService{ public void insert(){ //... } } 配置数据源dataSource 配置事务管理器DataSourceTransactionManager 开启<tx:annotation-driven>注解驱动 基于xml的声明式事务思路

    切入点表达式:定位在核心操作上 切入点表达式包含 tx:advice 和 aop:pointcut tx:advice 配置传播行为、隔离级别、回滚异常、只读属性、超时属性

    创建 Spring 配置文件:spring-persist-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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" 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-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 配置自动扫描的包:主要是为了把Service扫描到IOC容器中 --> <context:component-scan base-package="com.cc.crowd.service"/> <!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源在 spring-persist-mybatis.xml 文件中 现在报错但是实际运行在IOC容器中能找到--> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务通知 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- 查询方法:配置只读属性,让数据库知道这是一个查询操作,能够进行一定优化 --> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="count*" read-only="true"/> <!-- 增删改方法:配置事务传播行为、回滚异常 --> <!-- propagation属性: REQUIRED:默认值,表示当前方法必须工作在事务中,如果当前线程上没有已经开启的事务,则自己开新事务。如果已经有了,那么就使用这个已有的事务。 顾虑:用别人的事务有可能被因为别人回滚从而导致自己回滚。 REQUIRES_NEW:建议使用的值,表示不管当前线程上有没有事务,都要自己开事务,在自己的事务中运行。 好处:不会受到其他事务回滚的影响。 --> <!-- rollback-for属性:配置事务方法针对什么样的异常回滚 默认:运行时异常回滚 建议:编译时异常和运行时异常都回滚 --> <tx:method name="save*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="remove*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> <tx:method name="batch*" propagation="REQUIRES_NEW" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <!-- 配置事务切面 --> <aop:config> <!-- 考虑到后面我们整合 SpringSecurity,避免把 UserDetailsService 加入事务控制,让切入点表达式定位到ServiceImpl --> <!-- 定位到具体方法 expression="execution(public void com.cc.crowd.service.AdminService.saveAdmin(Admin admin)"--> <aop:pointcut expression="execution(* *..*ServiceImpl.*(..))" id="txPointcut"/> <!-- 将切入点表达式和事务通知关联起来 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/> </beans>

    1.8 表述层

    Processed: 0.019, SQL: 8