导航
[封装01-设计模式] 设计原则 和 工厂模式(简单抽象方法) 适配器模式 装饰器模式
[封装02-设计模式] 命令模式 享元模式 组合模式 代理模式
[React 从零实践01-后台] 代码分割
[React 从零实践02-后台] 权限控制
[React 从零实践03-后台] 自定义hooks
[React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql
[React 从零实践05-后台] Gitlab-CI使用Docker自动化部署
[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 - 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend
[源码-vue06] Vue.nextTick 和 vm.$nextTick
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI
[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数
[深入21] 数据结构和算法 - 二分查找和排序
[深入22] js和v8垃圾回收机制
[深入23] JS设计模式 - 代理,策略,单例
[前端学java01-SpringBoot实战] 环境配置和HelloWorld服务
[前端学java02-SpringBoot实战] mybatis + mysql 实现歌曲增删改查
[前端学java03-SpringBoot实战] lombok,日志,部署
[前端学java04-SpringBoot实战] 静态资源 + 拦截器 + 前后端文件上传
[前端学java05-SpringBoot实战] 常用注解 + redis实现统计功能
[前端学java06-SpringBoot实战] 注入 + Swagger2 3.0 + 单元测试JUnit5
[前端学java07-SpringBoot实战] IOC扫描器 + 事务 + Jackson
[前端学java08-SpringBoot实战总结1-7] 阶段性总结
[前端学java09-SpringBoot实战] 多模块配置 + Mybatis-plus + 单多模块打包部署
(一) 前置知识
(1) 一些单词
batch 批 分批
Stalled 停滞
pratices 实践,通常的做法 // best practices 最佳实践
key map 键盘映射
artifact 人工制品
look up 查找 查阅 // lookup parent from repository
property 属性
annotation 注解 // java中的注解
surefire 万全 可靠的
verify 验证 校验
(2) mac版 idea快捷键记录
1. 全局查找
command + shift + r
2. 调出actions
command + 3
3. 设置
command + ,
4. 文件间的跳转
command + e
5. 信息提示
command + 1
6. 跳转到别的类
control + 鼠标左键
7. 复制文件的引用路径
鼠标右键 - copy path - copy reference
8. 左右移动代码块
- 左移动 shift + tab
- 右移动 tab
9. 查找文件
- ctrl + h
1. command + k 查找下一个
2. ctrl + h 查找文件
3. 设置快捷键 ( command + , ) => ( keymap ) => ( 搜索find ) => ( 添加查找快捷键 ) => ( command + f )
(3) pom.xml配置项
- 项目的打包类型
-
packaging
- pom jar war
- 默认打包类型packaging=jar,即默认是打成jar包
-
packaging
- pom模型版本
- modelVersion
- 项目信息
- 项目唯一标识
groupId
,包括几个字段,比如com.wu7,com是域,wu7是域名 - 项目名或者模块名
artifactId
- 项目版本
version
- 项目名称 name
- 打包方式(项目的打包类型) packaging pom jar war
- 一般来说,( 包名根目录 ) = ( groupId ) + ( artifactId ),不允许重复
packageName = groupId + artifactId
- 项目唯一标识
- 父级项目 parent
- 也包括 groupId, artifactId,version,relativePath
-
relativePath
- relativePath用来指定查找该父项目 pom.xml 的相对路径
- 默认:
../pom.xml
- 优先级:
relativePath > 本地仓库 > 远程仓库
- 1.设定一个空值,将始终从仓库中获取,而不从本地路径获取,
如 <relativePath/>
- 2.没有relativePath标签表示从
../pom.xml
来查找
- 属性信息 properties
- java的版本:java.version
- 编译字符编码 project.build.sourceEncoding
- 输出字符编码 project.reporting.outputEncoding
-
打包时跳过test
<skipTests>true</skipTests>
- ================================= 依赖关系 dependencies
- 编译 build
- 插件集 plugins
- 插件 plugin
-
================================= 模块 modules
- 在父模块中用来表示包含的 ( 子模块 )
(4) jackson
jackson fastjson gson
-
安装
- 一般在web开发中使用了
spring-boot-starter-web
启动器的话,已经包含了jackson
- 如果没有使用上边的starter,则需要自己安装
spring-boot-starter-json
依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </dependency>
- 一般在web开发中使用了
-
jackson常用注解
- @JsonFormat
- @JsonPropertyOrder
- @JsonProperty
- @JsonInclude
- @JsonIgnore
-
@JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "GMT+8")
- 格式化时间,用于类的属性 -
@JsonPropertyOrder(value = {"singer", "album"})
- 调整属性的顺序,用于类 -
@JsonProperty("aaa")
- 修改返回数据的属性名称,修改为aaa -
@JsonInclude(JsonInclude.Include.NON_NULL)
- 包含则不返回该属性,包含null则不返回该属性 -
@JsonIgnore
- 返回的属性不包括该字段
-
@JsonFormat - 格式化时间
- ( 全局配置 ) 和 ( bean中单独配置@JsonFormat() )
- 日期格式化配置优先级 ( bean对象中属性 @JsonFormat 注解 > 全局配置)
@JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "GMT+8")
1. 全局配置
- 在application.yml中全局配置jackson
spring:
jackson:
date-format: YYYY-MM-dd HH:mm:ss # 全局时间格式化
time-zone: GMT+8 # 时区
2. 局部配置
- 实体中使用 @JsonFormat()
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("music")
public class MpMusicBean {
Integer id;
String name;
String album;
String singer;
@TableField(value = "startTime") // value是数据库字段名
@JsonFormat(pattern = "YYYY-MM-dd") // jackson格式化时间,优先级 ( bean中设置 > 全局配置 )
Timestamp startTime;
@TableField(value = "endTime") // value是数据库字段名
@JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss") // jackson格式化时间,优先级 ( bean中设置 > 全局配置 )
Timestamp endTime;
}
- @JsonPropertyOrder - 调整属性顺序
@JsonPropertyOrder(value = {"singer", "album"}) // jackson调整属性顺序,singer在album前面
public class MpMusicBean {
Integer id;
String name;
String album;
String singer;
}
结果:
未使用前
{
"album": "七里香112233",
"singer": "周杰伦112233",
},
使用后
{
"singer": "周杰伦112233", //----------------- 1
"album": "七里香112233", // ---------------- 2
},
- @JsonProperty
@JsonProperty("start") // jackson修改返回数据的属性名
@TableField(value = "startTime") // value是数据库字段名
@JsonFormat(pattern = "YYYY-MM-dd") // jackson格式化时间,优先级 ( bean中设置 > 全局配置 )
// 这三个注解的最终效果:将数据库中的startTime列的数据key对应实体的startTime,然后将返回值修改成star,并格式化时间
Timestamp startTime;
- @JsonInclude
@JsonInclude(JsonInclude.Include.NON_NULL) // jackson,包含null,则不返回该字段
String singer;
- @JsonIgnore
@JsonIgnore // jackson返回值中不包含该属性,忽略该属性
String name;
(5) SimpleDateFormat,sring,Timestamp,datetime 几个的关系
-
Timestamp
- (
java中的Timestamp
) 相当于 (数据库中的datetime
) -
Timestamp.valueOf(String v)
将string转成Timestamp
- (
-
SimpleDateFormat
- 主要用来格式化时间
-
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
生成实例,然后再调用实例上的方法
@Test
void testDate() {
Date date = new Date(); // 获取时间实例
SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); // 生成实例
String format = dateFormat.format(date); // 调用实例实例上的format()方法,返回一个字符串
log.info("SimpleDateFormat: {}", format);
}
(二) 多模块配置 module
- 我们将一个项目分成以下模块
-
父模块
- 7-react-admin-java-pro
-
子模块
- mapper
- service
- controller
- common
-
父模块
- 多模块配置 - 测试项目github仓库地址
(2.1) 多模块的优点
- 每个模块具有 ( 高内聚 ) 性,方便校验,调试,测试
(2.2) 模块的依赖关系
common 一般不依赖任何模块,除非common封装的方法涉及到其他模块
mapper => 依赖 common
service => 依赖 common mapper
controller => 依赖 common service mapper
注意点:
1. 需要删除 ( 父模块的src ) 文件夹,因为父模块不需要写代码
2. controller 模块是需要建 ( srping-boot ) 项目
3. 除了controller模块,其他模块都是建 ( maven ) 项目
(2.3) idea 做相关设置
- 字符编码设置:
ctrl + ,
=>File Encodings
=>utf-8
- 注解生效激活:
compiler
=>annotation processors
=>Enable annotation processing
(2.4) 多模块配置具体过程
(1) 父模块
1.1 首先新建父模块 ----------------------------------- 【 创建的类型为springboot项目 】
1.2 修改父模块的 pom.xml,将 ( packaging ) 类型从jar改为pom,即打包类型为pom
1.3 dependences 交给父模块来打理
1.4 注意区分 ( dependencies ) 和 ( dependencyManagenment )
- dependencyManagenment => dependencies => dependency
- dependencyManagenment 只是声明依赖,并不实际导入package,子模块需要显示的引入
1.5 创建好子模块后,父项目的pom.xml中会自动生成 ( modules ) 标签,并显示所有子模块
(2) 子模块
2.1 创建module - mapper service controller ---------- 【 创建类型事maven项目 】
(3) 模块的依赖关系
common 一般不依赖任何模块,除非common封装的方法涉及到其他模块
mapper => 依赖 common
service => 依赖 common mapper
controller => 依赖 common service mapper
(4) 具体配置
4.1在子模块中的pom.xml中配置好模块的依赖关系即可
4.2 所有模块的 groupId 都是一样的
4.3 controller
<dependencies>
<!-- controller 依赖 service -->
<dependency>
<groupId>com.woow.wu7</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
</dependencies>
(三) Mybatis-plus
(1) Mybatis-plus ( Mapper
) 的基本使用
(1.1) 安装idea插件 - MyBatisX
-
command + ,
选择plugins
,搜索MyBatisX
安装 - 好处就是点击图标能直接跳转mapper和xml配置文件
(1.2) 添加 maven 依赖
- 注意:
Mybatis-plus 包中已经包含了 mybatis 和 jdbc 的start包了,所以不需要再安装这两个包
- 包含 mybatis-spring-boot-starter
- 包含 spring-boot-starter-data-jdbc
- 在
application.yml
文件中通过mybatis-plus: xxx
对其进行定制配置-
mapperLocations: 自动配置好了
- 默认值是:
classpath*:/mapper/**/*.xml
,表示在resources/mapper
中 - 所以sql映射文件,建议放在
resrouces/mapper
文件中
- 默认值是:
- SqlSessionFactory:自动在容器中配置好了,底层是容器中的默认数据源
- SqlSessionTemplate:自动在容器中配置好了
-
@Mapper 标注也会被自动扫描
- 建议使用@MapperScan进行指定扫描的包,进行批量扫描,就不用一个个@Mapper了
-
mapperLocations: 自动配置好了
<!-- mybatis plus包含了 ( mybatis-spring-boot-starter ) 和 ( spring-boot-starter-data-jdbc ) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
(1.3) 配置 @MapperScan
- 指定扫描的mapper包,就不用在一个个@Mapper了
- @MapperScan注解的 ( 参数 ) 是 ( mappe文件夹路径引用 )
@SpringBootApplication
@MapperScan("com.example.demo.mapper") // 指定mapper的目录,将自动扫描,则不用在每个类上都加@Mapper
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
(1.4) 准备一个bean对象即user类 - MybatisPlusUserBean
- 注意注意注意:(
实体类名
) 必须和 (数据库表名
) 保持一致,否则需要指定数据库名称 - 这里实体名叫
MybatisPlusUserBean
,那么数据库名就要叫mybatis_plus_user_bean
- @TableName 指定数据库表名,默认情况下mp会将实体名首字母小写,用_连接,作为表名
@Data
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Component
@TableName("mybatis_plus_user_bean")
// @TableName
// 指定数据库表名,默认情况下mp会将实体名首字母小写,用_连接,作为表名
// @TableName 是mybatis-plus中的注解
public class MybatisPlusUserBean {
private Long id;
private String name;
private Integer age;
private String email;
@TableField(exist = false) // mybatis-plus的注解,表示该属性在数据库中不存在
private String other;
}
(1.5) 编写一个mapper - 继承BaseMapper
- 继承
extends BaseMapper<bean对象>
就具有crud的能力,不用在手写crud了 - bean对象的命名需要和数据库的表一致
- 比如实体名叫
MybatisPlusUserBean
,那么数据库名就要叫mybatis_plus_user_bean
- 可以不用再写 @Mapper,因为配置了 @MapperScan
@Mapper
public interface MybatisPlusUserMapper extends BaseMapper<MybatisPlusUserBean> {
}
(1.6) 准备好数据库和user表
- 1.注意注意注意:(
实体类名
) 必须和 (数据库表名
) 保持一致 - 2.也可以通过 @TableName 指定数据库表名,默认情况下mp会将实体名首字母小写,用_连接,作为表名
(1.7) 测试是否已经配置成功
@SpringBootTest
@Slf4j
public class MybatisPlusUserTest {
@Autowired
MybatisPlusUserMapper mybatisPlusUserMapper;
// mapper相关测试
// 查询
@Test
void getUser() {
MybatisPlusUserBean user = mybatisPlusUserMapper.selectById(1);
log.info("用户信息{}", user);
}
// mapper相关测试
// 添加
@Test
void addUser() {
MybatisPlusUserBean user = new MybatisPlusUserBean();
long a = 11;
MybatisPlusUserBean user2 = user.builder()
.name("周杰伦2")
.age(200)
.email("woow.wu7@gmail.com")
.id(a)
.build();
int status = mybatisPlusUserMapper.insert(user2);
log.info("Mybatis-plus插入insert()方法的返回值{}", status);
}
// mapper相关测试
// 删除
@Test
void deleteUser() {
int id = 11;
int status = mybatisPlusUserMapper.deleteById(id);
}
// mapper相关测试
// 更新
@Test
void editUser() {
MybatisPlusUserBean user = new MybatisPlusUserBean();
long userId = 11;
MybatisPlusUserBean user2 = user.builder()
.name("周杰伦13000")
.age(3000)
.email("woow.wu3000@gmail.com")
.id(userId)
.build();
int status = mybatisPlusUserMapper.updateById(user2);
}
}
-
mybatis-plus 的 mapper 查询 selectById
-
mybatis-plus 的 mapper 插入 insert
-
mybatisx插件如下
(2) Mybatis-plus ( Service
) 的基本使用
(2.1) 以上 1 步,测试了extends BaseMapper
,继续测试 extends IService
- (
mapper
) 是除了继承mybatis-plus的 (BaseMaper
) -
Interface接口 - (
interface
) 也可以继承mybatis-plus的 (IService
) -
Implements实现类 - (
implements service
) 继承 (ServiceImpl<mapper bean>
)
(2.2) 编写一个 Interface Service
MpIService - 是一个interface
-------
public interface MpIService extends IService<MybatisPlusUserBean> {
}
(2.3) 编写一个实现类
MpIServiceImpl - 是一个实现类
------
@Service
public class MpIServiceImpl extends ServiceImpl<MybatisPlusUserMapper, MybatisPlusUserBean> implements MpIService {
}
-------
// extends ServiceImpl<MybatisPlusUserMapper, MybatisPlusUserBean>
// - MybatisPlusUserMapper 是上面继承了 BaseMapper 的 mapper
// MpIServiceImpl 除了继承 ServiceImpl 外,还需要实现我们自己定义的 MpIService
// - MpIService 需要继承 IS而ver
(2.4) 测试
@SpringBootTest
@Slf4j
public class MpIServiceTest {
@Autowired
MpIService mpIService;
@Test
void mpIServiceTest() {
List<MybatisPlusUserBean> data = mpIService.list();
log.info("{}", data);
}
}
(3) Mybatis-plus 开启日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启mybatis-plus日志
(四) springboot 单模块项目打包和部署
(4.1) package 和 install 的区别
-
package
是简单的打包 -
install
除了打包,还会把这个打包好的包安装到maven仓库中 -
注意:如果 (
其他项目依赖a项目
),则应该使用 (install
) 来进行打包a项目
打包
(4.2.1) 单模块打包过程
- 如果springboot项目中有jsp页面,就只能打成war包,没有则可以达成jar包
- 步骤 ( idea方式 )
- 1.添加 srping boot 的打包插件
spring-boot-maven-plugin
<!-- maven插件 --> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins>
- 2.在idea中关闭项目,清楚缓存,然后选择
Lifecycle
=>clean compile package
,package打包说明没有依赖关系,不会打包后不会放在maven仓库中 - 3.打完包,会生成
target
文件夹,里面就会有.jar
包
- 1.添加 srping boot 的打包插件
- 步骤( 使用命令的方式打包,不用idea来操作 )
1. mvn -Dmaven.test.skip -U clean package
-D 是指定参数的意思
-D maven.test.skip 表示跳过test检查
-U 表示强制去远程更新插件或依赖
clean package 表示清楚target然后再打包
这个命令能执行的前提是需要插件:Spring-boot-maven-plugin
(4.2.2) 多模块打包过程
(1) 将父模块的pom.xml文件中的build标签的所有内容复制到controller模块,因为controller其实已经变成了主模块
(2) 想build标签中添加 configuration => mainClass => application主类的引用路径
(3) 最终的controller模块中的build标签内容如下
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.woow.wu7.Application</mainClass>
</configuration>
</plugin>
</plugins>
</build>
(4) 然后在利用idea或者mvn命令来打包即可
(4.3) 如果打包过程报错:提示test没通过,则可以设置忽略测试
- 有两种方式跳过test进行打包
- 1.在
pom.xml
中做如下配置
<properties> <skipTests>true</skipTests> </properties>
- 2.添加plugin
maven-surefire-plugin
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <!-- 打包时跳过检查 --> <!-- surefire 是万全,可靠的意思 --> <configuration> <skip>true</skip> </configuration> </plugin>
- 1.在
部署jar包
(4.4) 使用命令运行 jar 包
结尾是否有 &
---
(1) java -jar 7-react-admin-java-0.0.1-SNAPSHOT.jar
// ssh通过 ( ctrl+c ) 则可以终止java服务
// 缺点:当退出命令行工具后,java服务将不在运行
(2) java -jar 7-react-admin-java-0.0.1-SNAPSHOT.jar &
// 1. 在尾部加上 ( & ) 表示该命令在后台执行,ssh通过 ( ctrl+c ) 则无法终止java服务
// 2. 只有 ( 关闭命令窗口 ) 才会终止java程序
指定环境
---
(3) java -jar -Dspring.profiles.active=production target/7-react-admin-java-0.0.1-SNAPSHOT.jar
// -Dspring.profiles.active=production 指定环境变量是生产环境
// 则需要在 src/main/resources/application-production.properties 文件来配置生产环境中的配置
// -D 表示指定参数
(4.5) 持久化
- nohup 和 & 的区别
-
不加&
当ctrl+c后就会终止java程序执行 -
&
后台运行,但是 ( 关闭了终端或者ssh窗口 ) 就还是会终止java程序执行 -
nohup + &
( 关闭终端或窗口 ) 仍然运行,即持久化操作
-
nohup java -jar -Dspring.profiles.active=production target/7-react-admin-java-0.0.1-SNAPSHOT.jar >temp.txt &
(4.6) 查看已部署的java项目的后台运行进程
-
ps -ef | grep java > a.txt
- 检查java程序是否存在,可以看到 PID PPID CMD等信息,即可以根据PID关闭相关进程,比如java
-
ps 将某个进程显示出来
- -e 显示所有进程
- -f 全格式
- grep 表示查找
-
ps -ef | grep java > a.txt
表示将查到的java后台进程结果写进 a.txt 文件中
(4.7) 杀掉java进程,终止java程序在后台运行
kill 进程号
- 进程号可以通过
ps -ef | grep java
来查看 - kill 76619
部署war包
1. 如果是多模块,并且想用war包的方式进行部署,那么
2. 首先需要将controller模块中的pom.xml中的 ( packaging ) 改成 ( war )
3. 然后需要在 ( src/main ) 中新建 ( webapp/WEB-INF/web.xml ) 文件
4. 然后输入命令打包即可
资料
- mapper相关
- mybatis-plus常用操作 https://www.cnblogs.com/l-y-h/p/12859477.html
- mybatis-plus插入 https://blog.csdn.net/pipizhen_/article/details/111654273
- service相关
- 为什么提供了mapper还要提供service https://blog.csdn.net/pingfandehaozai/article/details/103537250
- 打包