目录
SpringBoot简介
spring缺点:
- 配置繁琐
- 导入maven依赖繁琐。
SpringBoot概述
SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想。
SpringBoot的特点
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求
- 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等
- SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式
SpringBoot的核心功能
-
起步依赖
起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。
简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
-
自动配置
Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。
SpringBoot快速入门
环境搭建步骤:
-
创建一个Maven项目
-
在pom.xml中添加SpringBoot起步依赖
所有SpringBoot工程必须继承SpringBoot起步依赖父类(依赖版本控制和加载SpringBoot配置文件):
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> </parent>
导入springmvc,spring,tomcat,jackson等web环境:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
-
编写SpringBoot引导类
//注解声明该类是一个SpringBoot引导类 @SpringBootApplication public class MySpringBootApplication { public static void main(String[] args) { //run方法参数为引导类的字节码文件 SpringApplication.run(MySpringBootApplication.class); } }
-
编写Controller等并测试
SpringBoot热部署:
-
导入热部署坐标依赖
<!--热部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
-
勾选Settings里的Compiler下的Buld project automatically
-
Shift+Ctrl+Alt+/,选择Registry,勾选compiler.aotomake.allow.when.app.running
-
IEDA工具栏设置为update classes and resources
SpringBoot原理分析
引导类(入口函数)里的**@SpringBootApplication**注解里包含三大注解:
- @SpringBootConfiguration:相当于spring的@Configuration,表明这是一个配置类。
- @EnableAutoConfiguration:自动配置,加载默认提供的自动配置类。
- @ComponentScan():组件扫描,扫描当前类包下的所有包及子包。
SpringBoot CRUD
controller:
@Controller
@RequestMapping("/student")
@ResponseBody
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/find-all")
public List<Student> findAll(){
return studentService.findAll();
}
@GetMapping("/find-by-name")
public List<Student> findByName(String name){
return studentService.findByName(name);
}
@PostMapping("/save")
public int save(@RequestBody Student student){
return studentService.save(student);
}
@PostMapping("/update-by-id")
public int updateById(@RequestBody Student student){
return studentService.updateById(student);
}
@PostMapping("/delete-by-id")
public int deleteById(@RequestBody Map<String,String> map){
return studentService.deleteById(Integer.parseInt(map.get("id")));
}
}
注:@RequestBody表示Post请求中把Json格式的请求参数的直接转化成指定对象。
service:
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> findAll() {
return studentMapper.findAll();
}
@Override
public List<Student> findByName(String name) {
return studentMapper.findByName(name);
}
@Override
public int save(Student student) {
return studentMapper.save(student);
}
@Override
public int updateById(Student student) {
return studentMapper.updateById(student);
}
@Override
public int deleteById(Integer id) {
return studentMapper.deleteById(id);
}
}
mapper:
@Mapper
public interface StudentMapper {
List<Student> findAll();
List<Student> findByName(String name);
int save(Student student);
int updateById(Student student);
int deleteById(Integer id);
}
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo20220917.mapper.StudentMapper">
<select id="findAll" resultType="com.example.demo20220917.dao.Student">
select * from student
</select>
<select id="findByName" resultType="com.example.demo20220917.dao.Student">
select * from student where sname like concat('%',#{sname},'%')
</select>
<insert id="save" parameterType="com.example.demo20220917.dao.Student">
insert into student(sno,sname,sex,age) values (#{sno},#{sname},#{sex},#{age})
</insert>
<update id="updateById" parameterType="com.example.demo20220917.dao.Student">
update student set sname=#{sname},sex=#{sex},age=#{age} where sno=#{sno}
</update>
<delete id="deleteById" parameterType="integer">
delete from student where sno=#{id}
</delete>
</mapper>
SpringBoot配置文件
通过配置文件可以修改自动配置类的默认值。
SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件。
优先级:
由于加载顺序:
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<exclude>**/application*.yml</exclude>
<exclude>**/application*.yaml</exclude>
<exclude>**/application*.properties</exclude>
</excludes>
</resource>
后加载的会覆盖先加载的,故优先级:properties>yaml>yml
YML和Properties自动转换网站www.toyaml.com
YML配置文件语法
YML文件的扩展名可以使用.yml或者.yaml。语法严格缩进,键名冒号后必须有空格。
#--------------------------------
#1,普通数据的配置
name: zhangsan
#--------------------------------
#2,对象的配置
person:
name: zhangsan
age: 18
addr: Beijing
#行内对象配置写法
#person: {name: zhangsan,age: 18,addr: Beijing}
server:
port: 8081
#--------------------------------
#3,数组集合配置(字符串)
city:
- Beijing
- Shanghai
- Guangzhou
#行内配置写法
#city: [Beijing,Shanghai,Guangzhou]
#数组集合配置(对象)
student:
- name: tom
age: 18
addr: Beijing
- name: lucy
age: 20
addr: Shanghai
#行内配置写法
#student: [{name: tom,age: 18,addr: Beijing},{name: lucy,age: 20,addr: Shanghai}]
#--------------------------------
#4,Map集合
map:
key1: value1
key2: value2
key3: value3
从配置文件中取值
- @Value注解注入:
配置文件会被加载到spring容器中,开发时可通过注入从spring容器中取值
@Value("${name}")
private String name;
@Value("${person.age}")
private Integer age;
.......
注意:先需要把该类@Component加容器中才能用@Value从容器中获取值。
静态属性需要通过setter方法注入值:
@Component
public class Constant {
//从springboot配置文件中获取文件上传路径
public static String FILE_UPLOAD_DIR;
@Value("${file.upload.dir}")
public void setFileUploadDir(String fileUploadDir){ //注意:该setter方法没有static关键字
FILE_UPLOAD_DIR=fileUploadDir;
}
}
- @ConfigurationProperties注解注入
@Controller
@ConfigurationProperties(prefix = "person")
public class QuickController {
private String name;
private Integer age;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
......
注意:使用@ConfigurationProperties方式必须提供setter方法
加入@ConfigurationProperties执行器的坐标依赖(yml提示功能):
<!--@ConfigurationProperties执行器的配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
SpringBoot与其他技术的整合
SpringBoot整合MyBatis
-
导入mybatis的起步依赖坐标(由mybatis提供)和数据库驱动坐标
<!--Mybatis起步依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- MySQL连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
创建表,创建表对应实体Bean
-
编写Mapper接口,和对应xml映射文件
@Mapper public interface UserMapper { List<User> findAll(); }
注意:
@Mapper
标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文中。@Mapper
注解使用后相当于@Reponsitory加@MapperScan注解,会自动进行配置加载。<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ycy.mapper.UserMapper"> <select id="findAll" resultType="user"> select * from user </select> </mapper>
-
在springboot配置文件application.properties中配置
#数据库连接信息 spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true spring.datasource.username=root spring.datasource.password=root #集成Mybatis环境 #别名扫描包 mybatis.type-aliases-package=com.ycy.domain #加载Mybatis映射文件 mybatis.mapper-locations=classpath:mapper/*Mapper.xml
-
测试使用
SpringBoot整合Junit
-
导入Junit起步依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
-
编写测试类
@RunWith(SpringRunner.class) @SpringBootTest(classes = MySpringBootApplication.class) //引导类的字节码对象 public class MybatiTest { @Autowired private UserMapper userMapper; @Test public void test(){ List<User> userList = userMapper.findAll(); System.out.println(userList); } }
SpringRunner继承自SpringJUnit4ClassRunner,使用哪一个Spring提供的测试测试引擎都可以
SpringBoot整合SpringDataJPA
整合jpa类似与整合mybatis
-
导入jpa的起步依赖坐标和数据库驱动坐标
<!-- springBoot JPA的起步依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MySQL连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
创建表,创建表对应实体Bean并用注解标注
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String username; private String password; private Date birthday; .......
-
编写Mapper接口继承JpaRepository<>
public interface UserRepository extends JpaRepository<User,Integer> { List<User> findAll(); }
-
在springboot配置文件application.properties中配置
#数据库连接信息 spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true spring.datasource.username=root spring.datasource.password=root #JPA Configuration: spring.jpa.database=MySQL spring.jpa.show-sql=true spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
-
测试使用
SpringBoot整合Redis
一般将对象集合等转成Json格式字符串后再存入Redis中。
-
导入redis的起步依赖坐标
<!-- 配置使用redis启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
在springboot中配置redis的连接信息
#Redis spring.redis.host=127.0.0.1 spring.redis.port=6379
-
注入RedisTemplate并测试
@RunWith(SpringRunner.class) @SpringBootTest(classes = MySpringBootApplication.class) //引导类的字节码对象 public class RedisTest { @Autowired private RedisTemplate<String,String> redisTemplate; @Autowired private UserMapper userMapper; @Test public void test() throws JsonProcessingException { //从redis缓存中获得指定的数据 String userListJson = redisTemplate.boundValueOps("user.findAll").get(); //如果redis中没有数据的话 if (null==userListJson){ //查询数据库获得数据 List<User> all = userMapper.findAll(); //使用jackson转换成json格式字符串 ObjectMapper objectMapper=new ObjectMapper(); userListJson= objectMapper.writeValueAsString(all); //将数据存储到redis中,下次在查询直接从redis中获得数据,不用在查询数据库 redisTemplate.boundValueOps("user.findAll").set(userListJson); System.out.println("======从数据库获得数据======"); }else { //redis中有数据 System.out.println("======从Redis获得数据======"); } System.out.println(userListJson); } }