脚手架(将脚手架项目导入IDEA中的操作教程):

用脚手架可以创建SpringBoot项目

软件工程中的脚手架指的是用来快速搭建一个小的可用的应用程序的骨架,将开发过程中要用到的工具,环境都配置好,同时生成必要的模板代码。

Spring Initializr是创建SpringBoot项目的脚手架。快速建立SpringBoot项目的最好方式,是一个web应用,能够在浏览器中使用。IDEA中继承了此工具,用来快速创建SpringBoot项目以及SpringCloud项目。

https://start.spring.io

SpringBoot的依赖添加:

都弄完了之后将这个下载后的压缩包解压,然后在IDEA当中,选择File->Project Structure->选择Modules,点击加号,然后选择import Modules,将我们刚才的包导入进来。

这叫做启动类,也叫做入口类,这里是进入SpringBoot项目的入口。

这里面application.properties是项目的配置文件。

static和templates是和Web应用相关的。

static放的是静态资源:图片,样式表,HTML文件。可以直接访问,不需要做别的操作。

templates是模板:和视图技术相关的。

如果不是web应用程式,这俩可以直接删除掉,但是为什么自带这两个呢,因为前面选中的依赖有

Spring Web。

上面的方法还是偏于繁琐,所以可以用IDEA中内置的脚手架。

在IDEA中,选择File->NEW->Module->Spring Initializr(脚手架)

Server URL:代表当前默认的地址,此选项可以修改,比如可以修改成阿里云的。

然后通过此方法也可以设置脚手架到项目中去。(此过程没有设置任何的依赖)

设置成功之后,显示如下:

上面,由于我没有选中Spring Web的依赖,就代表我不是Web应用程序,所以没有static和templates。

即使什么依赖都不选择,依然会有Spring相关的所有依赖自动生成,因为SpringBoot生成的是Spring的应用程序。

使用阿里云的脚手架:

https://start.aliyun.com

代码结构(SpringBoot推荐的代码的结构):

在项目中构建单个模块。

推荐的单一模块的构建方式。

com.example.模块名称

+—-Application.java 启动类

+—-controller 控制器包

—StudentController.java

—ScoreController.java

+—-service 业务层包

—inter 业务层接口

—impl 接口实现包

+—-repository 持久层包

+—-model 模型包

—entity 实体类包

在项目中构建多个模块。

Starter:是一组依赖描述,应用中包含starter,可以获取spring相关技术的一站式的依赖和版本。start包含:

依赖坐标,版本

传递依赖的坐标,版本

配置类,配置项

一个starter里面包含了很多的跟web相关的依赖 ,我们不再需要一个一个依赖去导入。

无父项目的方式如何创建SpringBoot应用?

把父项目那部分注释掉,然后加上依赖管理的标签,替代父项目。

推荐还是使用父项目的方式构建SpringBoot应用。

核心注解:

通过run方法是可以得到Spring容器的,然后从容器里面得到对象。

运行SpringBoot的项目方式有以下三种:

1.IDEA中执行启动类的main方法。

2.Maven插件 mvn spring-boot:run

打开终端,进入到合适的项目路径下,然后执行 mvn spring-boot:run 代码

3.java -jar jar 文件的路径

在pom文件里面加上myweb

之后点击maven里面的Lifecycle里面的package,给它打个包!

然后点击target里面的myweb.jar文件。找到这个jar包,然后打开DOS命令窗口,执行

java -jar myweb.jar 命令即可。

SpringBoot中的jar文件和普通jar文件有什么区别呢?

Springboot jar:

比普通的jar多一个spring-boot-loader,这个文件可以执行jar的spring boot类。而且还多一个BOOT-INF,里面有应用的类和lib。

外部化配置:

应用程序 = 代码+数据(数据库,文件,url)

配置文件格式:propertie和yaml(yml),properties是Java中的常用的一种配置文件格式,key=value。key是唯一的,扩展名为properties。

yaml(YAML Ain’t Markup Language)也看作是yml,是一种做配置文件的数据格式,基本的语法 key:[空格]值。yml文件的文件扩展名是yaml或yml(常用)。

YAML基本语法规则:

大小写敏感

使用缩进表示层级关系(空格)

缩进只可以使用空格,不允许使用Tab键

缩进的空格数目不重要,相同层级的元素左侧对齐即可。(只要是左对齐就是同一级别)

#字符表示注释,只支持单行注释。#放在注释行的第一个字符。

建议YAML文件的编写只用小写和空格。

YAML支持三种数据结构:

对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary)

数组:一组按次序排列的值,又称为序列(sequence)/列表(list)

标量:单个的,不可再分的值,例如数字,字符串,true/false等需要掌握数据结构完整内容,可从https://yaml.org/type/index.html获取详细介绍。

推荐使用yml文件,可读性更高。

在使用YAML文件的时候,首先记得先把properties文件废掉。!!!!

Environment:

Environment是外部化的抽象,是多种数据来源的集合。从中可以读取application配置文件,环境变量,系统属性。使用方式在Bean中注入Environment。调用它的getProperty(key)方法。

1.首先如果想要使用yml文件,就只能先将properties作废,否则会默认执行properties文件的。

2.第一种可以通过@Value的方式,从配置文件中去找属性值。

第二种就是使用environment.getProperty(“”)方法来获取配置文件当中的属性值。

默认值这个东西就是说,如果配置文件里面有的话,那么永远使用配置文件里面的,如果没有的话,那才会使用默认值的。

如果既有properties和yml,那么我想取得一个属性值,如果properties里面没有,那我就会从yml里面找,所以有可能我取得的一些数据有一部分是来自properties,有一部分是来自yml的。如果properties和yml里面都没有,那才会采用默认值。

组织多文件:

每个框架独立一个配置文件,就可以做集成开发了。

在resource底下新建一个目录conf,然后将redis.yml和db.yml都导入进去!!!

多环境配置:

首先在resource包下,创建application-dev.yml和application-test.yml文件,然后在里面进行编写:

在application.yml中加入环境配置:

绑定Bean:

嵌套Bean:

看这个 address和user类,然后再看application.yml配置即可!!!

使用EnableConfigurationProperties注解来使用ConfigurationProperties:(还有别的办法)

使用ConfigurationPropertiesScan注解来使用ConfigurationProperties:

绑定第三方对象:

这个第三方对象说的就是没有源码的对象,我现在就是想要创建一个出来,并且要给他赋值成功。

绑定Map-List-Array:

指定数据源:

总结外部化配置:

绑定Bean:用于多个属性。

注解:@ConfigurationProperties

位置:1.在类的上面,需要有源代码。

2.方法的上面,使用第三方对象。配置@Bean(无源码的情况下是这样的)

数据来源 application文件(properties或者yml)

指定数据的来源@PropertiesSource(value=”classpath:/group-info.properties)

注意:1.类中有无参数构造方法

2.属性有setXXX方法

3.static属性无效

@ConfigurationProperties使用需要配合其他注解:

1.@Configuration

2.@EnableConfigurationProperties——–>推荐

3.@ConfigurationPropertiesScan

application配置文件的位置:

1.resource/conf

2.resources目录

使用ImportResource导入外部的文件到我们当前的SpringBoot中,当我们的一个类放置到XML文件中,但是想在SpringBoot项目中用,就可以利用这种方式。

ImportResource加载XML文件注册Bean对象。

AOP:

Aspect:表示切面,开发自己编写功能增强代码的地方,这些代码会通过动态代理加入到原有的业务方法中。@Aspect注解表示当前类是切面类。切面类是一个普通类。

joinpoint:表示连接点,连接切面和目标对象。

切入点(Pointcut):其实就是筛选出的连接点。

Advice:通知,表示增强的功能执行时间。

@Before 在切点方法之前执行 @After 在切点方法之后执行 @AfterReturning 切点方法返回后执行 @AfterThrowing:切点方法抛异常执行 @Around 属于环绕增强,能控制切点执行前,执行后。

想使用aop的话必须加上spring-boot-starter-aop的依赖

增强的内容:

切面类要实现@Component 这样才可以被扫描到

也要实现@Aspect 这样才能表明我是一个增强类

接口的实现类:

直接调用实现类的方法即可:

自动配置:

JdbcTemplate:

需要导入依赖分别是 JDBC API,Lombok,MySQL Driver。

实体类

测试类,首先记得导入JdbcTemplate才行,用@Resource

第一种测试:

单行查询,使用?占位符:

第二种测试:

增删改语句:

第三种测试:

命名参数模板类的使用:

第四种测试:

NamedParameterJdbcTemplate:

多表查询:

多表查询关注是查询结果如何映射为Java Object。常用两种方案:

一种是将查询结果转为Map。列名字是key,列值是value,这种方式比较通用,适合查询任何表。

一种是根据查询结果中包含的列,创建相对的实体类。属性和查询结果的列对应。将查询的结果自定义RowMapper,ResultSetExtractor映射为实体类对象。

需要依靠命名参数模板来完成,并且要重新修改内部匿名类继承RowMapper接口。

重写mapRow方法:返回终极包装类,ArticleMainPO。

Mybatis:

要增加三个依赖,分别是:Lombok,MyBatis Framework,MySQL Driver。

在根包下要有两个包,分别是:mapper,po。

mapper包下面装接口,po包下面装pojo类。

同时也要注意需要配置数据源,直接从jdbcTemplate里面的数据源复制过来的,但是要加上一个mybatis的配置:

注意需要加这个@MapperScan的配置,标明需要去扫描mapper下面的所有接口,然后通过动态代理技术,自动创建新的对象,最后完成注入。

在mapper类下面编写select语句。

在这里可以自己写一个Results映射,返回去看看代码哦!!!!

这里需要Param注解的原因是,id和articleId的名字不一样,如果一样的话,就只需要占位符就够了

上面的是查,下面的是增:

这里是增删改查中的 改:

这里是增删改查中的 删:

MyBatis注解开发

1.加入MyBatis的starter,mysql驱动(8.0.32)

2.创建实体类XXXPO,XXXEntity,XXXDomain

3.创建Mapper接口,在接口中定义方法,在方法的上面使用合适的注解

@Select:查询 使用@Results和@Result做结果映射。

@Insert:新增

@Update:更新

@Delete:删除

4.在启动上面,加入@MapperScan(),标明需要扫描的mapper类的位置。

5.application.properties

1)定义数据库连接,连接数据源

2)mybatis设置:日志,驼峰命名支持。

@ResultMap()的使用方法:

ResultMap可以复用之前的Results映射类。

@ResultMap使用方式:

第一种:先通过@Results定义列的映射关系,@ResultMap(value=”@Result的id”)

第二种:在xml文件中定义,在代码中使用@ResultMap(value=”xml的id”)

SQL提供者:也可以实现MyBatis中的CRUD

SQL提供者有4类:@SelectProvider,@InsertProvider,@UpdateProvider,@DeleteProvider

SqlProvider类

mapper下的接口类

MyBatis一对一查询:@One注解

单独写一个Mapper类,包含ArticleDetail和Article:

MyBatis一对多查询:@Many注解 其实用法和@One注解基本上是一样的

创建的一个完整的ArticleEntity类

测试代码:

关于连接池的配置:看视频

声明式事务:

事务控制的属性:

Propagation:传播行为

Isolation: 隔离级别

Timeout:超时时间

Read-only:只读状态

创建模块的时候,也是需要加入三个依赖:分别是MyBatis Framework,MySQL Driver,Lombok。

在article这个表和article_detail这两个表中,添加Article的时候也要添加ArticleDetail成功。要有一个事务来保证这两个同时实现。

mapper配置文件里面需要有@Options注解,说白了就是将id值拿出来,赋值到属性里面,等到后期用。(还得赋值给articleId)

举例两种无效的事务:

无效事务1:
再mapper中新加一个方法

在Service层的实现类里面实现这个新的方法,并且将Transactional注解加到方法上面,而不是加到类上面,加到类上面的话就代表下面所有的方法都可以使用事务机制。

测试文件:

总的来说,就是A方法有事务机制,但是B方法调用了A方法,B方法没有事务机制,那么调用B方法的时候,虽然也用到了A方法,但是就是没有事务。

无效事务2:

就是说,当我们在一个方法上面加了@Transactional注解,只代表在这个方法的主线程中遵守事务机制,如果在这个方法里面新启动了别的线程,那么那个新的线程是不遵守事务机制的。

在Service层的实现类中加入的方法实现:

@Transactional@Overridepublic boolean insertArticleThread(ArticlePO articlePO, String content) {System.out.println("当前线程:"+Thread.currentThread().getId());Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("当前新的线程:"+Thread.currentThread().getId());int count1 = 0;int count2 = 0;count1 = mapper.insertArticle(articlePO);if(articlePO.getReadCount()<1){throw new RuntimeException("最少也得是1啊!!!!!");}ArticleDetailPO articleDetailPO = new ArticleDetailPO();articleDetailPO.setArticleId(articlePO.getId());articleDetailPO.setContent(content);mapper.insertArticleDetail(articleDetailPO);}});t1.start();try {//当前线程先阻塞,让t1线程先执行!!!t1.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("新的线程执行结束了!!!");System.out.println("当前线程也执行结束了!!!");return true;}

测试方法:

事务回滚原则:

RuntimeException的实例或子类时回滚事务

Error会导致回滚

已检查异常不会回滚。默认提交事务。

@Transactional注解的属性控制回滚:控制哪些异常出现需要回滚,哪些异常出现不需要回滚。

1.rollbackFor

2.noRollbackFor

3.rollbackForClassName

4.noRollbackForClassName