创建聚合工程
- 聚合工程里可以分为顶级项目(顶级工程/父工程) 与子工程, 这两者的关系其实就是父子继承的关系
子工程在maven里称之为模块(module), 模块之间是平级, 是可以相互依赖的. - 子模块可以使用顶级工程里所有的资源(依赖), 子模块之间如果要使用资源, 必须构建依赖(构建关系)
- 一个顶级工程是可以由多个不同的子工程共同组合而成.
最后还要执行maven install
聚合工程整合Spring Boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<!-- 排除某一个jar包 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot的配置默认只能解析yml, 引入后可以解析xml, properties -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
</dependencies>
Spring Boot自动装配简述
@SpringBootAppliction
注解中的EnableAutoConfiguration
注解
EnableAutoConfiguration
注解中的@Import(AutoConfigurationImportSelector.class)
的自动配置导入选择器类中的selectImports
方法中的getAutoConfigurationEnrty
方法中调用的getCandidateConfigurations
中显示的META-INF/spring.factories
HikariCP数据库连接池
Spring Boot默认选择的数据库连接池, HiKari在springboot2.x上默认使用无需配置
特点: 快
ArrayList<Statement>
was replaced with a custom classFastList
- ConcurrentBag
a custom lock-free collection
数据层HikariCP与MyBatis整合
-
引入
mysql-connector-java
mybatis-spring-boot-starter
依赖 -
application.yml配置
##########################################################################
#
# 配置数据源信息
#
##########################################################################
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/foodie-shop-dev?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=UTC
username: root
password: zhoukuo
hikari:
connection-timeout: 30000 # 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 默认:30s
minimum-idle: 5 # 最小连接数
maximum-pool-size: 20 # 最大连接数
auto-commit: true # 自动提交
idle-timeout: 600000 # 连接超时的最大时长(毫秒), 超时则被释放(retired), 默认:10分钟
pool-name: DataSourceHikariCP # 连接池名字
max-lifetime: 1800000 # 连接的生命时长(毫秒), 超时而且没被使用则被释放(retired), 默认:30分钟
connection-test-query: SELECT 1 # 连接测试的SQL语句
##########################################################################
#
# mybatis 配置
#
##########################################################################
mybatis:
type-aliases-package: com.zk.pojo # 所有POJO类所在路径
mapper-locations: classpath:mapper/*.xml # mapper映射文件
MyBatis逆向生成工具
生成POJO实体类, *mapper.xml, *mapper.java接口
-
在pom中引入通用mapper工具
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency>
-
在yml中引入通用mapper配置
########################################################################## # # mybatis mapper 配置 # ########################################################################## # 通用 Mapper 配置 mapper: mappers: com.zk.my.mapper.MyMapper not-empty: false # 在进行数据库操作的时候, 判断表达式 username != null, 是否追加 username != '' identity: MYSQL
-
引入MyMapper通用Mapper接口类
import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.MySqlMapper; /** * 继承自己的MyMapper */ public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> { }
通用Mapper接口所封装的常用方法
-
首先先来看一下MyMapper 所继承的父类,如:
interface MyMapper<T> extends Mapper<T>,MySqlMapper<T>
这里有两个父类, Mapper<T> 与 MySqlMapper<T>, 我们可以打开 MySqlMapper<T> 看一下:
interface MySqlMapper<T> extends InsertListMapper<T>,InsertUseGeneratedKeysMapper<T>{}
这里面又继承了两个mapper, 从类名上可以看得出来, 是用于操作数据库的, 这两个类里又分别包含了如下方法, 简单归类一下:insertList(list)
数据批量插入 主键须自增insertUseGeneratedKeys(record)
插入表数据 主键须自增
很明显, 在传统JavaWeb开发, 这两个方法使用是没有问题的, 但是我们的数据库表主键设计肯定是全局唯一的, 所以不可能使用自增长id, 所以这两个方法在我们开发过程中是不会使用的, 这一点需要注意噢~!
-
随后再来看一下Mapper<T> 中所继承的父类,如下:
interface Mapper<T> extends BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>
分别来看一下各个父类中的方法有些啥?
BaseMapper<T>
- BaseSelectMapper<T>类
T selectOne(T record)
- 根据实体类中的属性查询表数据, 返回单个实体List select(T record)
- 根据实体类中的属性查询表数据, 返回符合条件的listList selectAll()
- 返回该表的所有记录int selectCount(T record)
- 根据条件查询记录数T selectByPrimaryKey(Object key)
- 根据主键查询单条记录
- BaseInsertMapper类
int insert(T record)
- 插入一条记录, 属性为空也会保存int insertSelective(T record)
插入一条记录, 属性为空不保存, 会使用默认值
- BaseUpdateMapper类
int updateByPrimaryKey(T record)
根据实体类更新数据库, 属性有null会覆盖原记录int updateByPrimaryKeySelective(T record)
根据实体类更新数据库, 属性有null该属性会忽略- BastDeleteMapper类
int delete(T record)
- 根据实体类中属性多条件删除记录int deleteByPrimaryKey(Object key)
- 根据主键删除记录
ExampleMapper<T>, Example类是用于提供给用户实现自定义条件的, 也就是 where 条件, 主要方法如下:
RowBoundsMappe<T> , 这个是用于做分页的, 我们在后续阶段中会使用page-helper这个组件来替代这个分页实现。
总结
通用mapper所提供的CRUD方法对单表操作, 大大提高开发效率, 当然复杂的多表操作还是需要在mapper.xml中自己去编写sql代码实现。
Restful Web Service
- 通信方式
- 信息传递
- 无状态, 请求是无状态的
- 独立性
Rest设计规范
- GET - 查询 -> /order/{id} -> /getOrder/{id}
- POST - 插入 -> /order -> /saveOrder
- PUT - 更新 -> /order/{id} -> /modifyOrder
- DELETE - 删除 -> /order/{id} -> /deleteOrder?id=1001
详解事务的传播
事务传播 - Propagation
- REQUIRED: 使用当前的事务, 如果当前没有事务, 则自己新建一个事务
如果当前存在事务, 则加入这个事务, 成为一个整体 - SUPPORTS: 如果当前有事务, 则使用事务, 如果当前没有事务, 则不使用事务
- MANDATORY: 该传播属性强制必须存在一个事务, 如果不存在, 则抛出异常
- REQUIRES_NEW: 如果当前有事务, 则挂起该事务, 并且自己创建一个新的事务给自己使用; 如果当前没有事务, 则同 REQUIRED
- NOT_SUPPORTED: 如果当前有事务, 则把事务挂起, 自己不使用事务去运行数据库操作
- NEVER: 如果当前有事务存在, 则抛出异常
- NESTED: 如果当前有事务, 则开启子事务(嵌套事务), 嵌套事务是独立提交或者回滚
如果当前没有事务, 则同 REQUIRED
但是如果主事务提交, 则会携带子事务一起提交
如果主事务回滚, 则子事务会一起回滚. 相反, 子事务异常, 则父事务可以回滚或不回滚
为何不使用@EnableTransactionManagement
就能使用事务?
因为在@SpringBootApplication
注解里包含了自动装配了TransactionAutoConfiguration