由于目前社区版IDEA还不能直接创建SpringBoot项目,所以我得通过SpringAssisant这个插件,才能创建SpringBoot项目。
引入插件过程很简单,略。
1)新建module
(IDEA中的Project:项目,就相当于Eclipse中的WorkSpace:工作区)
(IDEA中的module:模块,就相当于Eclipse中的Project:项目)
由于我的maven中设置了默认的jdk就是1.8。
所以这里选择哪个都可以。
2).编辑项目内容
IDEA中会通过springboot官网的模板的结构,引导我去创建SpringBoot项目
OK,第一种方式OVER。
1).选择maven项目,直接点下一步。
2).构建项目
3).通过这种形式产生的pom.xml文件里内容不全,需要手动补全。
org.springframework.boot
spring-boot-starter-parent
2.3.3.RELEASE
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
4).再手动创建个主启动类
package com.jt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //添加SpringBoot注解
public class SpringBootRun {
public static void main(String[] args) {
SpringApplication.run(SpringBootRun.class,args);
}
}
OK,第二种方式OVER。
注意:SpringBoot项目的pom文件中的配置说明:
4.0.0
com.jt
springboot_demo1
0.0.1-SNAPSHOT
springboot_demo1
入门案例
org.springframework.boot
spring-boot-starter-parent
2.3.3.RELEASE
1.8
true
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
SpringBoot项目只需要引入少量的jar包及配置,即可拥有引入的依赖的功能。
spring-boot-starter-web
spring-boot-start 看到了这个字段,就说明这个spring项目具有开箱即用的能力
至于具体开的是什么箱,具有什么能力,就看后面接的是啥了
比如 -web:就是jar包配置文件的相关内容,spring-boot-starter-web 说明引入的是springMVC框架
-jdbc就是连接数据库的能力;
-aop就是spring-boot拥有了aop的功能
Maven项目中依赖具有传递性
规则:
A项目 依赖于 B项目 ,B项目 依赖于 C项目
这时 只要倒入A项目的jar包,B和C就都有了。
spring-boot-starter-test
这句话是说:springboot通过这个依赖,重构了测试方法。可以在测试类中,直接引入依赖对象。
org.springframework.boot
spring-boot-maven-plugin
这个配置,是在项目打包部署时生效。
如果不配置这几行,那么程序在发布时,会报错:项目中找不到main方法。
SpringApplication.run()方法中加载了SpringbootDemo1Application这个本主类。
但这不是主要目的,主要目的是为了加载主类上的@SpringBootApplication这个注解。(因为注解也是类)
点进@SpringBootApplication这个注解的底层源码 可见:
这个SpringBootApplication类上有7个注解!!!
其中上面4个是元注解,是为了描述,解释,说明下面3个注解的用途用法的。
这个注解是说明 类启动时 要进行组件扫描。括号中的参数 说明的是,虽然扫描,但是 在主类SpringBootApplication加载时,像这种像过滤器这样的配置类就不要去加载了。
因为主类SpringBootApplication会比别的类最先执行,而配置过滤器filter的类肯定会在后面才会被执行。
在主类SpringBootApplication加载时,这些过滤器的配置类还没读取到自身有啥规定时,不知道自己要以什么规则去过滤。
所以,在主类SpringBootApplication加载时,这些配置过滤器的类还不能执行,只能先exclude掉。
点进@SpringBootConfiguration这个注解的源码 可见:
SpringBootApplication是一个接口,它头上有@Configuration这个注解。
说明SpringBootApplication就是一个配置类。
所以@SpringBootApplication修饰的类,也是一个配置类。
意义
在SpringbootDemo1Application的包以及子包中,的类头上,只要有@Configuration这个注解,那么这个类在启动类启动时都会被“扫描”到。
配置类的前身,就是 配置文件。
主启动类本身就是一个超大的配置文件
点进@EnableAutoConfiguration这个注解的源码 可见:
@AutoConfigurationPackage意思是 按照包扫描的方式 去实例化对象们
先会找到SpringbootDemo1Application这个启动类所在的包,然后配进@ComponentScan,这样以后所有的子孙包就能啥时候用啥时候加载了。
知识点:所有的配置类必须在主启动类的子孙包下完成。
@Import(AutoConfigurationImportSelector.class)
开箱即用的功能就是由这个类完成的。
当程序启动时,根据SpringBoot中的选择器Seletor,去检查POM.xml文件中是否添加了启动项的包们。
等等。
启动项的包们一开始都是静静的躺在项目中的,得有人去加载它们,它们才能去干活。
谁去加载它们的呢?
就是这个AutoConfigurationImportSelector选择器
AutoConfigurationImportSelector选择器会专门挑选启动项们(spring的启动项有20个多)的包进行加载。
1.本身是K-V结构,都是在定义字符串。
2.SpringBoot程序读取pro问价默认使用ISO-8859-1格式编码。如果需要读取properties文件,则需手动地去将类名上的注解中指定为UTF-8格式。
eg:
1.本身也是K-V结构
2.K和V之间用“ :空格 ” 方式连接。(注意不要丢了空格)
3.注意上级和下级之间的缩进效果
4.默认使用UTF-8格式编码
eg:
org.springframework.boot
spring-boot-devtools
按组合键:CTRL+ALT+SHIFT+/ 弹出如下框,找到这个compiler…把后面勾选上。
OK,完成。
一般开发时使用的都是“测试环境”.当项目上线时需要在“生产环境”下部署项目.
问题: 在测试环境中的配置与生产环境下的配置可能不一致,经常需要修改IP地址及端口.
想法:能否简化该操作?
策略:指定多个运行环境. 当现在处于测试环境时,让配置文件指向测试. 反之做相同的操作.
# 测试环境 /jt 端口号 8095 生产环境: / 端口号8090 配置必须完整.
#设定默认的环境
spring:
profiles:
active: test
---
# yml 1.key-value结构
# 2.key-value之间使用": "方法链接
# 3.YML配置文件有缩进的效果.
# 4.YML配置文件默认采用utf-8编码.
#定义环境名称
spring:
profiles: prod
server:
servlet:
context-path: / #设定项目发布路径
port: 8090
#配置图片上传路径
#image:
#localDir: D:/JT-SOFT/images
#设定分割线
---
# 设定环境名称
spring:
profiles: test
server:
servlet:
context-path: /jt #设定项目发布路径
port: 8095
org.projectlombok
lombok
这时,就可以通过在程序的类上添加Lombok提供的注解,替我生成各属性的get,set方法,有参,无参构造,重写toString()等
package com.jt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data //set/get/toString方法只会重写自己的属性,不会添加父级的属性
@Accessors(chain = true) //链式加载规则
@NoArgsConstructor //无参构造
@AllArgsConstructor //全参构造
public class User {
private Integer id;
private String name;
private Integer age;
private String sex;
//accessors重写了set方法
/* public User setId(Integer id){
this.id = id;
return this;
}*/
}
注意这里的这个注解:@Accessors(chain = true)
它叫链式加载。
它重写了set方法
让我可以在为属性赋值时,可以写在一句代码中。
User user = new User();
user.setName("张三").setAge(88).setSex("男");
问:项目发布是在Linux中发布的,要想使用LomBok,一般都需要安装插件.那么:如果在Linux中发布项目,是否需要重新安装LomBok插件?
答案: 不需要
原有: Lombok是在编辑期有效工作的.它重写了set/get/toString等方法.
编辑期指代码由.java文件编译为.class文件.
在Linux中发布的是.class文件,已经是成品了。没Lombok啥事了。
由于Mybatis中封装了JDBC的操作,于是整合后这个项目就可以从数据库中 CURD数据了。
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
server:
port: 8090
servlet:
context-path: /
spring:
datasource:
#driver-class-name: com.mysql.jdbc.Driver 驱动注释,采用默认的方式
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#Mybatis整合
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#添加xml文件的依赖
mapper-locations: classpath:/mybatis/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示着额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。
概括: 利用对象的方式操作数据库.
在YML中进行别名包配置
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200827160620133.png#pic_center
定义这个的作用就是,在Mapper文件中,resultType不用写包的全路径了,简单点。
通常实体对象类(Entity)们,都定义在同一个包下,所以可以将共性部分提取出来
eg:com.jt.pojo
当查询结果时,底层会自己拼接包路径 com.jt.pojo.User
虽然使用了别名包,但是也可以自己指定包路径
结论:自己不写执行别名包
自己写了就执行自己的.
目的:主要简化mybatis 映射的过程
规则:user_id(字段名) (pojo中的属性名是:userId)
1.去除下划线(userid)
2.之后首字母大写(userId)
最终就与属性中的名称一致了,这样就可以正常映射了。
注意:一旦配置 中 使用了驼峰规则,必须按照驼峰规则走。
比如:如果开启了驼峰映射规则。
最开始
表中字段名:userId pojo中属性名也是userId
这样就不符合驼峰映射的规则,字段名中没有下划线可去。所以没法进行驼峰映射。
网址:https://baomidou.com
我是一个开发10年的老鸟.,但是我也有我的困扰.后端开发的实质就是如何"优雅"的书写CURD操作,作为老鸟特别喜欢有难度的业务. 但是某些需求执行单表的CURD操作(特别没有营养).
能否有一种框架可以帮助我们自动的实现单表的CURD操作呢?提高开发的效率???
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
说明:以对象的方式操作数据库。
需求分析:
1.对象 与 数据库表如何映射?
利用 注解 实现 对象 与 表 进行绑定,以及 属性 与 字段 绑定。
2.如何解决众多接口编辑 雷同的CRUD操作?
定义一个公共的Mapper接口,定义公共的CRUD操作,利用泛型区分对象。
3.数据库只认识Sql语句,不认识对象。(如何将对象转化为Sql)
思想:按照特定的语法,将对象转化为sql语句。
例子:将User对象插入数据库中。
userMapper.insert(user对象); //我写的代码
sql: insert into 表名(字段…) values (属性值…); //由mp动态拼接后,交由mybatis执行。
com.baomidou
mybatis-plus-boot-starter
3.2.0
注意:MP的jar包和Mybatis的jar包不能共存,在pom文件中只能有一个
这样就可以用MP啦。
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@TableName("user") //实现表与对象的关联 如果名称一致(忽略大小写)可以省略表名
public class User implements Serializable {
//但凡定义pojo实体对象中的属性类型必须使用包装类型.
@TableId(type = IdType.AUTO)
private Integer id; //主键,并且主键自增
//@TableField(value = "name")
private String name;
//@TableField(value = "age")
private Integer age;
private String sex;
//动态生成get和set方法及构造方法 快捷键 alt+insert
}
这其中的@TableName注解 @TableId注解 @TableField注解 就是通过引入MP之后,才能用的。
一般只会用到@TableName和@TableId 。
如果表中字段名和pojo属性名相同,@TableField注解就可以省略不写。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200827163409424.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mjc1MjQwMg==,size_16,color_FFFFFF,t_70#pic_center由此可见,只有引入了MP之后,我写的Mapper才能继承BaseMapper类,还得注意泛型!
对于后3个方法中,userMapper调用的方法都不是我写的,都是从BaseMapper中继承来的,我都没有写对应的sql语句。
执行后也输出了正确的结果。
这就是MP的强大的作用。
spring:
datasource:
#driver-class-name: com.mysql.cj.jdbc.Driver #驱动注释,采用默认的方式
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
1).时区 数据库驱动的高版本需要使用时区操作.
serverTimezone=GMT%2B8 %2B +
2).使用useUnicode=true编码
characterEncoding=utf8 字符采用utf-8编码
3).autoReconnect=true 如果mysql链接断掉之后是否重连.
4).allowMultiQueries=true 是否允许批量操作.
DELETE FROM user WHERE ( name is NULL )
假如 有这么一个需求:
实现文件上传的操作。
那么就需要 指明 这个要被上传的文件在哪个目录中。
假如我要把我电脑中的一个图片上传,它在这里。
从图中可知它的路径为: D:\demoimg\demo.png
如果我将这个路径 直接写死到代码中,这样代码的耦合性非常高,不便于扩展。我如果有好几个资源要上传,就要写好几行这样的代码。
问题:
怎么才能设置成将不同资源的路径 动态地 赋值给localDir呢?
答:
**方式1:**用得最多的方式:通过@Value这个注解。
主要分为两步:
①.在yml配置文件中,配置要上传的文件所在的路径
注意:在windows操作系统中 它对路径中的“/”校验的不是很严格。
但在linux系统中,对路径中的“/”要求很严格,必须是“/”。
②.在程序中,往localDir上加个@Value注解,注解中的V就是通过spel表达式,对应着如上图中,yml文件中我配置的那个黄色字体的Key。
把这部分复制到@Value中的${ } 中。
再将这部分内容去掉,用“.”代替,就成了:
至此,我就用第一种方式,@Value注解的方式完成了动态的把yml文件中我自己配置的路径,赋值给了程序中的变量localDir。
以后我如果想上传别的文件夹下的资源,就把yml中D:/demoimg替换掉就行了,就不用去修改程序中的代码了。
eg:
方式二:
(潜规则:YML配置文件中配置的一般都是SpringBoot框架整合第三方资源的一些配置信息。如果将业务配置与这些配置混写在一起,则不方便管理。一般会单独再新建一个配置文件,这个文件中只填写业务相关的配置信息。一般业务配置的信息写到.properties文件中)
于是,我就新建了一个properties配置文件的文件夹,用来存放各个业务配置的pro文件。
我要是想用这种pro配置文件的方式,我就要把刚才那个yml文件中的配置注释掉,免得重复。
我在properties文件中进行如下配置:
我自己写的这个image.properties文件现在还跟我的程序没关联上。还是独立的个体。
问:我该怎么把image.properties文件与我的程序关联上呢?
答:通过在程序的类上加@PropertySource注解,但属性上的@Value("${image.localDir}")也得留着。
注意点:
①.@PropertySource代表配置源的意思,说到“源”,我就要先写上classpath:/ (潜规则!)
后面再接我这个pro配置文件具体的路径。
怎么快速得到我这个pro配置文件的路径?
小技巧:
这个得到的结果就是:properties/image.properties
把它写到classpath:/ 后面就行了。
②.由于properties配置文件默认的编码方式是ISO-8859-1。
我如果往我的pro配置文件中写了中文,就要在@PropertySource()中加入encoding=“utf-8”,否则会出现乱码
eg:
不加encoding=“utf-8”,效果:
加上encoding=“utf-8”,效果:
此处讨论的是springboot项目打jar包。
最常用的两个功能是:clean和install
先说install:打包
在当前项目下,点击打包后,idea就开始帮我把项目打成jar包的形式。
注意:我提前在pom.xml文件中设置了跳过测试类不打包。
打完包后,如果看到控制台显示
初步可以说明打包成功了。
FAQ1:idea帮我打出了几个jar包?
答:2个!!!
FAQ2:它们在哪?
答:
一个在target目录下:
另一个在本地库中:
这俩jar文件其实是一模一样的。
再说另一个功能:clean
clean的是target目录。把target目录整合都清除了。
老版本的spring会把本地库中的jar包也删除,不过升级到现在的版本后,本地库中的jar包已经不删除了。
找到打好包的项目后,直接在jar包所在的文件夹的地址栏输入cmd,就可以在控制台中直接定位到当前文件夹
再在控制台中通过 java -jar -jar包名称 按回车 就开始发布了。
FAQ:idea为啥要给我打两份 jar包?(target文件夹中1份,本地仓库中1份)
本地仓库中的那份jar包是为了让别的项目调用我这个项目时用的。
就好比我引入的众多依赖,它们就是我从下载到本地仓库中的,我会在我的项目中调用到它们。
而这些依赖就是前人们写的项目。
而引入依赖只能从本地仓库引。
target目录下的那个jar包是不能被当做依赖引入的。