SpringBoot入门

SpringBoot入门

学习目标

  1. SpringBoot简介
  2. SpringBoot快速入门
  3. SpringBoot原理分析
  4. SpringBoot的配置文件:application.properties,和application.yml
  5. SpringBoot集成其它项目:MyBatis、SpringData JPA、SpringDataRedis、定时器
  6. SpringBoot测试
  7. SpringBoot打包部署

1 SpringBoot简介
Spring 诞生时是 Java 企业版(Java Enterprise Edition,JEE,也称 J2EE)的轻量级代替品。无需开发重量级的 Enterprise JavaBean(EJB),Spring 为企业级Java 开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java 对象(Plain Old Java Object,POJO)实现了 EJB 的功能。
虽然 Spring 的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring 用 XML 配置,而且是很多 XML 配置。Spring 2.5 引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式 XML 配置。Spring 3.0 引入了基于 Java 的配置,这是一种类型安全的可重构配置方式,可以代替 XML。所有这些配置都代表了开发时的损耗。因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。和所有框架一样,Spring 实用,但与此同时它要求的回报也不少。
除此之外,项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。
Spring Boot 让这一切成为了过去。
Spring Boot 是 Spring 社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于 Spring 的应用程序和服务,让更多人的人更快的对 Spring 进行入门体验,为 Spring 生态系统提供了一种固定的、约定优于配置风格的框架。

1.1 JaveEE开发方式的转变
1农业时代Java开发方式:
 基于Java底层原生API,纯手动去实现,典型技术Servlet,JDBC,Socket…
 框架是拯救者,解放了农业时代的程序猿们,框架为我们做的更多,程序员主要负责业务的实现。

  1. 工业时代Java开发方式:
     各种框架一顿搞:典型代表SSM,SSH,Freemaker,Netty…
     微服务是拯救者,解放了工业时代的程序猿们,微服务让我们过上了小康生活

  2. 现代化Java开发方式:
     各种微服务解决方案:服务注册与发现,负载均衡与熔断,网关和集群
     微服务的基石则是SpringBoot,各种组件一起上:springboot、springcloud…

  3. 人工智能化的Java开发方式
    在未来谁说得准呢,但AI肯定是一个方向,看过钢铁侠都知道,里面有个人工智能程序,贾维斯和星期五,作为钢铁侠的智能管家,贾维斯和星期五的功能都是一样的,都能够帮助主人处理各种事项。

1.2 SpringBoot特点

  1. 约定优于配置思想
  2. 专注与业务逻辑之间思维切换
  3. 基于Spring的开发提供更快入门体验
  4. 开箱即用,没有代码生成,无需XML配置。
  5. 支持修改默认配置满足特定需求
  6. 提供大型项目中常见的非功能性特性,如嵌入Tomcat服务器、安全、指标、健康检测、外部配置等

总结起来就是一个成语,化繁为简。
1.3 核心功能
 起步依赖:本质是Maven项目对象模型中的标签。它定义其SpringBoot对他库的传递依赖,依赖加在一起即可支持某项功能。使得SpringBoot具备了构建一切的能力:整合所有牛逼框架。
 自动配置:基于约定优于配置思想,配置基本都可以走默认值。配置基本都是SpringBoot自动完成。

后续章节会详细介绍这两个核心。
2 SpringBoot快速入门
目标:手动搭建一个SpringBoot开发环境。实现web的请求响应,完成SpringMVC入门案例在请求中返回Hello SpringBoot!

2.1 没有使用SpringBoot之前怎么做Web开发

  1. 添加pom.xml一堆的jar依赖
  2. 配置 web.xml,加载 Spring 和 Spring mvc
  3. Spring 配置数据库连接、配置事务
  4. 配置加载配置文件的读取,开启注解
  5. 配置日志文件
  6. 开发Controller…
  7. 配置完成之后部署 Tomcat 调试

但是如果使用 Spring Boot 呢? 很简单,我不需要配置,不需要Tomcat容器就可以,迅速搭建起来一套 Web 项目!
到底多简单,现在揭晓。

2.2 方式一:使用原始Maven工程
2.2.1 不选骨架创建空Maven工程,名称为springboot_helloworld
2.2.2 添加SpringBoot起步依赖

<?xml version="1.0" encoding="UTF-8"?>


4.0.0
com.itheima
springboot_helloworld
1.0-SNAPSHOT

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
</parent>
<dependencies>
    <!--web 开发的相关依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
2.2.3 编写SpringBoot引导类 /** * @SpringBootApplication 标识当前类为SpringBoot引导类 * @author Steven * @description com.itheima */ @SpringBootApplication public class DemoApplication { public static void main(String[] args) { //启动SpringBoot-run(当前启动的引导类字节码,main函数传入的参数) SpringApplication.run(DemoApplication.class,args); } }

2.2.4 编写Controller
@RestController
public class HelloController {
/***
* 请求 /hello 输出hello springboot!
* @return
*/
@RequestMapping(value = “hello”)
public String hello(){
return “hello springboot!”;
}
}

2.2.5 启动与测试
在DemoApplication里运行主方法,日志输出如下图

访问:http://localhost:8080/hello

2.3 方式二:使用Idea的Spring Initializr
目标:使用Spring Initializr 方式创建SpringBoot工程,实现入门案例的需求。
2.3.1 准备工程
2.3.1.1 新建模块,选择spring initializr,然后下一步

2.3.1.2 填写项目相关信息

2.3.1.3 勾选需要的依赖启动器

2.3.1.4 完成,查看工程的目录结构如下

2.3.2 测试工程
2.3.2.1 创建HelloController
工程的src目录下创建com.itheima.controller.HelloController
@RestController
public class HelloController {
/***
* 请求 /hello 输出hello springboot!
* @return
*/
@RequestMapping(value = “hello2”)
public String hello(){
return “hello springboot2!”;
}
}
2.3.2.2 启动引导类

2.3.2.3 访问: http://localhost:8080/hello2

2.4 小结

  1. 搭建SpringBoot工程有2种方式
     Maven工程直接创建
     Spring Initializr方式
  2. 使用SpringBoot,我们只需关注业务逻辑实现,而不用关注工程依赖。

2.5 SpringBoot工程热部署
我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间,能不能在我修改代码后不重启就能生效呢?可以,在pom.xml中添加如下配置就可以实现这样的功能,我们称之为热部署。

org.springframework.boot spring-boot-devtools 赶快试试看吧,是不是很爽。 注意在idea中,默认情况下不会自动编译代码。如果要使用自动部署功能,需要编译一下。

或者开启idea的自动编译功能:
1、CTRL + SHIFT + A --> 查找MAKE PROJECT AUTOMATICALLY --> 选中

2、CTRL + SHIFT + A --> 查找 Registry --> 找到并勾选compiler.automake.allow.when.app.running

最后重启idea
高版本的idea(测试机版本2018.3.6)还要设置一下启动加载方式才行:

测试要点:idea需要切换window窗口,才会自动编译。所以改完代码后,需要切换到浏览器窗口。

3 SpringBoot原理分析
为什么SpringBoot只需要很少的代码就实现了以前配置非常繁琐的spring mvc入门案例呢?接下来我们一起揭开SpringBoot的神秘面纱:起步依赖和自动配置。
 起步依赖:本质是Maven项目对象模型中的标签。它定义其SpringBoot对他库的传递依赖,依赖加在一起即可支持某项功能。使得SpringBoot具备了构建一切的能力:整合所有牛逼框架。
 自动配置:基于约定优于配置思想,配置基本都可以走默认值。配置基本都是SpringBoot自动完成。

3.1 起步依赖
我们可以打开pom.xml中的parent,并查看spring-boot-starter-parent信息。

我们接着打开Spring-boot-dependencies.pom文件,发现了坐标的版本,依赖管理,插件管理已经预先定义好了。

从上面的spring-boot-dependencies的pom.xml中可以看出,坐标的版本,依赖管理,插件管理已经预先定义好了。SpringBoot工程继承Spring-boot-starter-parent后,已经锁定了版本等配置。
起步依赖的作用是进行依赖传递 。用啥取啥,随用随取即可。我们开发中彻底不用关心:jar包的版本、依赖等问题了,大大降低版本冲突,版本过期,更新一个jar一下就需要升级一个tree的jar包。

相当于我们之前学习的过程中创建的父工程,在之前创建的父工程中,其中一个功能是用来统一管理jar包。这里的父工程其实作用是一样的。
3.2 自动配置
3.2.1 @SpringBootApplication
该注解是一个组合注解,包括如下注解

 @SpringBootConfiguration:与之前@Configuration注解一样,声明为一个配置类
 @ComponentScan:spring IoC容器的扫描包,默认扫描引导程序下的包以及子包,如果我们写的程序不在该包范围内,可以通过该注解指定。
 @EnableAutoConfiguration:springboot实现自动化配置的核心注解。
3.2.2 @SpringBootConfiguration

通过这段代码我们可以看出,这说明 @SpringBootConfiguration 也是来源于 @Configuration,二者功能都是将当前类标注为配置类,并将当前类里以 @Bean 注解标记的方法的实例注入到 spring 容器中,实例名即为方法名。
至于 @Configuration,我想在非 SpringBoot 时代大家应该不陌生吧,作用是配置 Spring 容器,也即 JavaConfig 形式的 Spring IoC 容器的配置类所使用。 @Configuration相当于xml的,@Bean相当于xml中的

3.2.3 @EnableAutoConfiguration
@EnableAutoConfiguration的作用启动自动的配置,@EnableAutoConfiguration注解的意思就是Springboot根据你添加的 jar 包来配置你项目的默认配置,比如根据spring-boot-starter-web ,来判断你的项目是否需要添加了webmvc和tomcat,就会自动的帮你配置 web 项目中所需要的默认配置。简单点说就是它会根据定义在 classpath 下的类,自动的给你生成一些 Bean,并加载到 Spring 的 Context 中。

可以看到 import 引入了 AutoConfigurationImportSelector 类。该类使用了 Spring Core 包的 SpringFactoriesLoader 类的 loadFactoryNamesof() 方法。

AutoConfigurationImportSelector 类实现了 DeferredImportSelector 接口,并实现了 selectImports 方法,用来导出Configuration 类。

导出的类是通过 SpringFactoriesLoader.loadFactoryNames() 读取了 ClassPath 下面的 META-INF/spring.factories 文件。

3.3 小结
 起步依赖:坐标的版本,依赖管理,插件管理已经预先定义好了,我们选择好启动器就可直接使用。
spring-boot-starter-parent继承了spring-boot-dependencies
spring-boot-dependencies实现了jar包管理和版本锁定。工程引入spring-boot-starter-web依赖,该工程又依赖了其他web所需的jar包,maven依赖有传递性。
 自动配置:基于约定优于配置思想,配置基本都可以走默认值。配置基本都是SpringBoot自动完成。主要通过@SpringBootApplication注解完成自动配置,会将当前类作为一个配置类,并且会根据我们所引入的依赖猜测我们的配置,并实现自动配置。

4 SpringBoot配置文件使用
我们知道SpringBoot是基于约定的,所以很多配置都有默认值。如果想修改默认配置,可以使用application.properties或application.yml(application.yaml)自定义配置。SpringBoot默认从Resource目录加载自定义配置文件。application.properties是键值对类型(一直在用,而且默认生成)。application.yml是SpringBoot中一种新的配置文件方式。

4.1 目标
 掌握application.properties配置
 掌握application.yml语法
 理解@value与@ConfigurationProperties的使用

4.2 application.properties
4.2.1 语法
格式:key=value
如果是修改SpringBoot中的默认配置,那么key则不能任意编写,必须参考SpringBoot官方文档。
application.properties官方文档:
https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/htmlsingle/#common-application-properties

4.2.2 案例
在resources目录下新建application.properties
#配置tomcat端口号
server.port=18080
#配置项目根目录
server.servlet.context-path=/demo

此时运行,tomcat端口发生了变化,每次请求,需要加上/demo。

4.3 application.yml
4.3.1 简介
YML文件格式是YAML(YAML Aint Markup Language)编写的文件格式,是一种标记语言。可以直观被电脑识别的格式。容易阅读。容易与脚本语言交互。可以支持各种编程语言(C/C++、Ruby、Python、Java、Perl、C#、PHP)。以数据为核心,比XML更简洁。扩展名为.yml或.yaml
4.3.2 语法
简单理解起来就是,在yml的语法中是把数据描述成树型结构。
4.3.2.1 普通数据
语法:key: value
注意:Value之前有一个空格。
案例:
#配置普通数据
name: steven
4.3.2.2 对象数据
语法:
#配置对象数据
key:
key1: value1
key2: value2
#或者
key2: {key1: value1,key2: value2}

案例:
#配置对象数据
user:
name: steven
age: 18
addr: shenzhen
#或者
user2: {name: steven, age: 18, addr:shenzhen}
4.3.2.3 集合数据
语法:
#配置集合数据
key:
#value1与-之间存在一个空格

  • value1
  • value2
    #或者
    key2: [value1,value2]

案例:
#配置集合数据
userList:
#value1与-之间存在一个空格

  • steven
  • lucy
    #或者
    userList2: [steven,lucy]

#集合中是对象时
userListObj:
#value1与-之间存在一个空格

  • name: steven
    age: 18
    sex: boy
  • name: lucy
    age: 17
    sex: girl

4.3.3 简单实战
目标:把之前application.properties中tomcat相关配置改成yml格式
#yml简单实战-配置tomcat相关内容
server:
port: 18080
servlet:
context-path: /demo

4.4 配置文件与配置类的属性映射方式(了解)
4.4.1 使用注解@Value映射
@value注解将配置文件的值映射到Spring管理的Bean属性值
4.4.2 使用注解@ConfigurationProperties映射
通过注解@ConfigurationProperties(prefix=’’配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映射。
使用@ConfigurationProperties方式要注意的问题:
 创建的对象必须提供getter与Setter方法
 添加该注解需要的Maven依赖
4.4.2.1 创建User.java
/**

  • 用户信息
  • @author Steven
  • @version 1.0
  • @description com.itheima.pojo
    */
    @Component
    @ConfigurationProperties(prefix = “user”)
    public class User {
    //注意,此处的属性名要与yml声明的属性名一致
    private String name;
    private Integer age;
    private String addr;
    //省略getter与setter
    }
    4.4.2.2 在项目的pom.xml添加maven依赖
org.springframework.boot spring-boot-configuration-processor true 4.4.2.3 UserController.java添加测试返回读取内容 @RestController public class HelloController {
@Value("${user2.name}")
private String name;
@Autowired
private User user;

/***
 * 请求 /hello  输出hello springboot!
 * @return
 */
@RequestMapping(value = "hello2")
public String hello(){
    return "hello springboot2! name:" + name +",user:" + user;
}

}

4.4.3 集合映射方式
在SpringBoot中yml声明的集合映射需要包装在对象中来读取。

4.4.3.1 修改User.java
@Component
@ConfigurationProperties(prefix = “user”)
public class User {
//注意,此处的属性名要与yml声明的属性名一致
private String name;
private Integer age;
private String addr;
private List userListObj;

@Override
public String toString() {
    return "User{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", addr='" + addr + '\'' +
            ", userListObj=" + userListObj +
            '}';
}

//省略getter与setter…
}

4.4.3.2 修改yml文件
#yml简单实战-配置tomcat相关内容
server:
port: 18080
servlet:
context-path: /demo

#配置普通数据
name: steven

#配置对象数据
user:
name: steven
age: 18
addr: shenzhen
#集合中是对象时
userListObj:
#value1与-之间存在一个空格
- name: steven
age: 18
sex: boy
- name: lucy
age: 17
sex: girl
#或者
user2: {name: steven, age: 18, addr:shenzhen}

#配置集合数据
userList:
#value1与-之间存在一个空格

  • steven
  • lucy
    #或者
    userList2: [steven,lucy]

5 SpringBoot与其他框架集成
5.1 集成Mybatis
5.1.1 目标
 SpringBoot集成MyBatis
 SpringBoot集成MyBatis实现查询所有用户信息

5.1.2 表结构介绍


– Table structure for user


DROP TABLE IF EXISTS user;
CREATE TABLE user (
id INT(11) NOT NULL AUTO_INCREMENT,
username VARCHAR(50) DEFAULT NULL,
password VARCHAR(50) DEFAULT NULL,
address VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;


– Records of user


INSERT INTO user VALUES (‘1’, ‘zhangsan’, ‘123’, ‘北京’);
INSERT INTO user VALUES (‘2’, ‘lisi’, ‘123’, ‘上海’);

5.1.3 搭建工程
通过spring initializr创建maven工程 springboot_integration ,并且勾选相关依赖(web、数据库驱动、mybatis)

springboot_integration的pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE


com.itheima
springboot_integration
0.0.1-SNAPSHOT
springboot_integration
SpringBoot集成测试

<java.version>1.8</java.version>



org.springframework.boot
spring-boot-starter-web


org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0


org.springframework.boot
spring-boot-devtools
runtime
true


mysql
mysql-connector-java
runtime


org.springframework.boot
spring-boot-starter-test
test





org.springframework.boot
spring-boot-maven-plugin



5.1.4 功能实现
5.1.4.1 创建实体对象
package com.itheima.integration.domain;

public class User {
private Integer id;
private String username;//用户名
private String password;//密码
private String name;//姓名
//getter setter…
//toString
}

5.1.4.2 编写mapper接口以及映射文件
MyBatis的Dao:Dao接口、Dao接口对应的映射文件(xml)
1、编写mapper接口:创建UserMapper
在接口中添加@Mapper注解(标记该类是一个Mapper接口,可以被SpringBoot自动扫描)
@Mapper
public interface UserMapper {
/**
* 查询所有用户
* @return
*/
List findAll();
}

2、编写映射文件:在工程的resources/mapper目录下创建UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?> SELECT * FROM user

5.1.4.3 编写service接口以及实现类
service接口
public interface UserService {
/***
* 查询所有
* @return
*/
List findAll();
}
实现类
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;

/**
 * 查询所有
 * @return
 */
@Override
public List<User> findAll() {
    return userMapper.findAll();
}

}

5.1.4.4 编写controller
@RestController
@RequestMapping(“user”)
public class UserController {
@Autowired
private UserService userService;
/***
* 查询所有用户
* @return
*/
@RequestMapping("/findAll")
public List findAll(){
return userService.findAll();
}
}

5.1.4.5 配置application.properties
#配置数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

#配置Mybatis
#-别名包扫描
mybatis.type-aliases-package=com.itheima.integration.domain
#-映射文件加载
mybatis.mapper-locations=classpath:/mapper/*.xml

#配置日志输出-主要是输出sql语句
logging.level.com.itheima.integration.mapper=debug

5.1.5 启动与测试
启动引导类,并访问地址:http://localhost:8080/user/findAll

5.1.6 小结
 引入相关依赖
 编写实体类
 编写Dao接口,接口上需要添加==@Mapper==注解
 编写Dao接口和接口对应的XML映射文件
 编写对应的Service,注入Dao,并调用Dao
 编写Controller,调用Service
 配置文件中配置数据源、指定别名包扫描、映射文件路径、日志输出等
5.2 集成SpringDataRedis
5.2.1 概念介绍
5.2.1.1 SpringData
Spring Data是一个用于简化数据访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。 Spring Data可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
Spring Data的官网:http://projects.spring.io/spring-data/
Spring Data常用的功能模块如下:

5.2.1.2 Redis
redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写。企业开发通常采用Redis来实现缓存。同类的产品还有memcache 、memcached 、MongoDB等。
5.2.1.3 Jedis
Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用。可以在Redis官网下载,当然还有一些开源爱好者提供的客户端,如Jredis、SRP等等,推荐使用Jedis。
5.2.1.4 Spring Data Redis
SpringDataRedis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
SpringDataRedis针对Jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
 ValueOperations:简单K-V操作
 SetOperations:set类型数据操作
 ZSetOperations:zset类型数据操作
 HashOperations:针对map类型的数据操作
 ListOperations:针对list类型的数据操作

5.2.2 目标
 集成SpringDataRedis
 查询用户,先去Redis中查询,如果有数据直接返回数据,没数据,则查询数据,并存入到Redis缓存,再返回数据
5.2.3 实现
5.2.3.1 添加Redis启动器依赖

org.springframework.boot spring-boot-starter-data-redis

5.2.3.2 在application中配置redis
#配置Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

5.2.3.3 更新服务方法,使用缓存
@Override
public List findAll() {
//1、先查询缓存
List userList = (List) redisTemplate.boundValueOps(“userList”).get();
//2、缓存没有查询数据库,并把数据加入缓存
if(userList == null || userList.size() < 1){
userList = userMapper.findAll();
//把数据加入缓存
redisTemplate.boundValueOps(“userList”).set(userList);
}else{
System.out.println(“从缓存中读取了用户列表…”);
}
return userList;
}
5.2.3.4 测试
请求http://localhost:8080/user/findAll如果发生如下异常,说明javabean没有序列化,修改User对象,实现Serializable即可。

5.2.3.5 小结
 引入SpringDataRedis依赖
 application.properties中配置Redis链接信息
 注入RedisTemplate,RedisTemplate实现了对Redis的增删查询操作
5.3 集成SpringDataJPA
5.3.1 什么是JPA
JPA(Java Persistence API)即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338,这些接口所在包为javax.persistence,详细内容可参考https://github.com/javaee/jpa-spec)。

JPA规范本质上就是一种ORM规范,注意不是ORM框架。因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现,常见实现JPA范围的产品有:Hibernate、OpenJPA、TopLink。
5.3.2 什么是SpringDataJPA

ORM框架都实现了JPA规范,但是在不同ORM框架之间切换是需要编写的代码有一些差异,而通过使用Spring Data JPA能够方便大家在不同的ORM框架中间进行切换而不要更改代码。并且Spring Data Jpa对Repository层封装的很好,可以省去不少的麻烦。

5.3.3 目标
 集成SpringDataJPA
 完成对user表的CRUD操作。

5.3.4 实现
5.3.4.1 创建工程
创建工程springboot_jpa,并且勾选相关依赖(Spring Data JPA)

pom.xml完整信息如下

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE


com.itheima
springboot_jpa
0.0.1-SNAPSHOT
springboot_jpa
SpringDataJPA集成

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

5.3.4.2 创建实体对象
@Entity //告诉Spring当前对象为实体类
@Table(name = “user”) //关联数据库表名
public class User implements Serializable {
@Id //标识当前属性为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //标识主键策略为数据库自增
private Integer id;
@Column(name = “username”) //关联表的字段名
private String username;//用户名
//如果属性名与数据库字段名称一致时,可以省略@Column
private String password;//密码
private String name;//姓名
//getter setter…
//toString
}

注解说明:
@Entity:表明为一个实体对象
@Table:指定映射的表
@Id:指定为主键
@GeneratedValue:指定注解的生成策略
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制
@Column:指定表的列明

5.3.4.3 编写Dao,Dao需要继承JpaRepository<T,ID>
在工程src目录下创建dao接口,需要继承JpaRepository对象(该对象完成对数据库的CRUD过程,并且支持分页查询、排序等功能)
/**

  • 用户信息持久化接口
  • @author Steven
  • @version 1.0
  • @description com.itheima.jpa.dao
  • JpaRepository<T,ID> T:操作的实体对象 ID:实体对象的主键类型
    */
    public interface UserDao extends JpaRepository<User,Integer> {
    }

5.3.4.4 编写service接口以及实现类
业务接口
public interface UserService {

List<User> findAll();

User findById(Integer id);

void save(User user);

void update(User user);

void deleteById(Integer id);

}
业务实现
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List findAll() {
return userDao.findAll();
}

@Override
public User findById(Integer id) {
    Optional<User> user = userDao.findById(id);
    return user.get();
}

@Override
public void save(User user) {
    userDao.save(user);
}

@Override
public void update(User user) {
    // 并不提供update方法,如果id存在则执行更新操作
    userDao.save(user);
}

@Override
public void deleteById(Integer id) {
    userDao.deleteById(id);
}

}

5.3.4.5 编写controller
@RestController
@RequestMapping(“user”)
public class UserController {

@Autowired
private UserService userService;

@RequestMapping("findAll")
public List<User> findAll(){
    return userService.findAll();
}

@RequestMapping("findById/{id}")
public User findById(@PathVariable Integer id){
    return userService.findById(id);
}

@RequestMapping("save")
public void save(User user){
    userService.save(user);
}

@RequestMapping("update")
public void update(User user){
    userService.update(user);
}

@RequestMapping("deleteById/{id}")
public void deleteById(@PathVariable Integer id){
    userService.deleteById(id);
}

}

5.3.4.6 配置application
这里可以只配置数据库连接信息就可以跑起来了,也可以扩展配置一下JPA相关内容
#配置数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

#jpa 相关配置

数据库类型

spring.jpa.database=mysql

是否显示sql

spring.jpa.show-sql=true

hibernate.ddl-auto,hibernate初始化数据库表策略:

update:每次运行程序,没有表会新建表,表内有数据不会清空,只会更新

create:每次运行程序,没有表会新建表,表内有数据会清空

create-drop:每次程序结束的时候会清空表

validate:运行程序会校验数据与数据库的字段类型是否相同,不同会报错

spring.jpa.hibernate.ddl-auto=update

是否生成数据库定义表语句

spring.jpa.generate-ddl=true

5.3.4.7 测试
请求http://localhost:8080/user/findAll 可以得到同样结果
5.3.4.8 小结
 Dao需要继承JpaRepository<T,ID>
 JpaRepository<T,ID>中已经实现了增删改查,可以拿着直接使用

5.4 集成定时器
在SpringBoot中自带定时器,所以在实现定时任务时,我们无需导入maven依赖。

5.4.1 目标
实现在SpringBoot定时执行一个方法

5.4.2 实现
5.4.2.1 引导类开启定时支持
在SpringBoot引导程序中添加开启定时任务注解:@EnableScheduling
@SpringBootApplication
@EnableScheduling //开启定时任务
public class SpringbootJpaApplication {

public static void main(String[] args) {
    SpringApplication.run(SpringbootJpaApplication.class, args);
}

}

5.4.2.2 编写与设置定时任务程序
@Component
public class TaskWork {

/**
 * cron:表达式是一个字符串,教案详细介绍,案例:cron = "1/2 * * * * *"
 * zone:时区接收一个java.util.TimeZone#ID,
 *        cron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区
 *
 * 注意:以下参数设置的单位都是毫秒
 * fixedDelay:上一次执行完毕时间点之后多长时间再执行,案例:fixedDelay = 1000
 * fixedDelayString:与 fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符,
 *      点位符中内容可以来源属性文件,案例:fixedDelayString = "${task.work.delay}"
 * fixedRate:上一次开始执行时间点之后多长时间再执行,案例:fixedRate = 2000
 * fixedRateString:与fixedRate意思相同,类似上面的fixedDelayString
 * initialDelay:第一次延迟多长时间后再执行,案例:@Scheduled(initialDelay = 1000,fixedDelay=2000)
 * initialDelayString:与initialDelay意思相同,类似上面的fixedDelayString
 */
@Scheduled(cron = "1/2 * * * * *")
public void taskDoSomthing(){
    System.out.println("定时任务执行了taskDoSomthing,当前时间:" + LocalDateTime.now());
}

}

5.4.2.3 Cron表达式
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:
(1)Seconds Minutes Hours DayofMonth Month DayofWeek Year
(2)Seconds Minutes Hours DayofMonth Month DayofWeek
cron从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份
各字段的含义

字段 允许值 允许的特殊字符
秒(Seconds) 0~59的整数 , - * / 四个字符
分(Minutes) 0~59的整数 , - * / 四个字符
小时(Hours) 0~23的整数 , - * / 四个字符
日期(DayofMonth) 1~31的整数(但是你需要考虑你月的天数) ,- * ? / L W C 八个字符
月份(Month) 1~12的整数或者 JAN-DEC , - * / 四个字符
星期(DayofWeek) 1~7的整数或者 SUN-SAT (1=SUN) , - * ? / L C # 八个字符
年(可选,留空)(Year) 1970~2099 , - * / 四个字符

注意事项:
每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:
(1):表示匹配该域的任意值。假如在Minutes域使用, 即表示每分钟都会触发事件。
(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。
(3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
(4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
(5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
(6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

5.4.3 小结
 @EnableScheduling //开启定时器
 配置定时器注解@Scheduled:传值
initialDelay,初始化延迟多久执行
fixedRate,固定频率执行
fixedDelay,固定延迟多久执行
cron,使用表达式

5.5 扩展了解:除此之外还可以整合什么?

  1. 集成 MongoDB
  2. 集成 ElasticSearch
  3. 集成 Memcached
  4. 集成邮件服务
  5. 集成RabbitMQ消息中间件
  6. 集成Freemarker或者Thymeleaf
  7. …….

6 SpringBoot如何代码测试
6.1 目标
SpringBoot集成JUnit测试功能,进行查询用户接口测试。

6.2 实现
6.2.1 添加起步依赖

org.springframework.boot
spring-boot-starter-test
test

6.2.2 编写测试类
SpringRunner继承SpringJUnit4ClassRunner,使用哪一个Spring提供的测试引擎都可以。指定运行测试
的引擎
@SpringBootTest的属性值指的是引导类的字节码对象
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootJpaApplicationTests {

@Autowired
private UserService userService;

@Test
public void testFindAll() {
    List<User> all = userService.findAll();
    for (User user : all) {
        System.out.println(user);
    }
}

@Test
public void testFindById() {
    User user = userService.findById(1);
    System.out.println(user);
}

}

7 Spring Boot 如何打包部署
启动方式有两种,一种是打成jar直接执行(推荐),另一种是打包成war包放到Tomcat服务下,启动Tomcat。
7.1 打成Jar包部署
执行maven打包命令或者使用IDEA的Maven工具打包。
注意打包前,要在项目的pom文件中指定项目的打包类型(可以不指定,默认就是jar)。

7.1.1 使用idea打包

7.1.2 通过命令行打包
1、通过cmd进入到工程的目录中,与pom.xml同级
2、然后执行命令:mvn clean package [-Dmaven.test.skip=true] —>[]内为可选操作,排除测试代码,也就是说打包时跳过测试代码
如下命令打包:mvn clean package -Dmaven.test.skip=true
7.1.3 启动项目
启动报错问题解决:

Maven pom.xml没有添加插件。

org.springframework.boot spring-boot-maven-plugin https://blog.csdn.net/banjing_1993/article/details/83073210

java -jar springboot_jpa-0.0.1-SNAPSHOT.jar
-Xmx:最大堆内存
-Xms:初始堆内存
java -Xmx80m -Xms20m -jar springboot_jpa-0.0.1-SNAPSHOT.jar

启动日志保存 方法:
https://blog.csdn.net/qq_35860138/article/details/82701919
7.2 打成war包部署

  1. 执行maven打包命令或者使用IDEA的Maven工具打包,需要修改pom.xml文件中的打包类型。
    war

  2. 注册启动类
    创建 ServletInitializer.java,继承 SpringBootServletInitializer ,覆盖 configure(),把启动类 Application 注
    册进去。外部 Web 应用服务器构建 Web Application Context 的时候,会把启动类添加进去。
    /**

  • 此类的作用相当于之前普通工程的web.xml
  • @author Steven
  • @description com.itheima.jpa.init
    */
    public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    return builder.sources(SpringbootJpaApplication.class);
    }
    }
  1. 然后执行打包操作。同7.1 小节打包是一样的
    拷贝到Tomcat的webapp下,启动Tomcat访问即可
    因为访问地址不再是根目录了,所有路径中需要加入项目名称:
    http://localhost:8080/ springboot_jpa-0.0.1-SNAPSHOT/user/findAll

Tomcat 启动:

8 Spring Boot jar 方式启动配置文件
8.1 前言
正常启动 ,下面会选择application.properties 中配置默认的启动文件进行启动,下面这种情况不能根据实际情况进行启动项目
java jar admin-1.0-SNAPSHOT.jar
1、测试环境和生产环境启动

  1. 主要观察priperties中配置文件的名字
  2. 测试环境:java -jar my-spring-boot.jar --spring.profiles.active=test
  3. 生产环境:java -jar my-spring-boot.jar --spring.profiles.active=prod
    后台启动并配置log日志
    2.1、测试库启动
  4. #!/bin/bash
  5. echo starting
    
  6. java -jar admin-1.0-SNAPSHOT.jar --spring.profiles.active=test  > log.file 2>log.error &
    

2.2、正式库启动

  1. #!/bin/bash
  2. echo starting
    
  3. java -jar admin-1.0-SNAPSHOT.jar --spring.profiles.active=prod > log.file 2>&1 &
    

2.3、停止正在运行的项目

  1. #!/bin/bash
  2. PID=$(ps -ef | grep admin-1.0-SNAPSHOT.jar | grep -v grep | awk '{ print $2 }')
    
  3. if [ -z “$PID” ]
  4. then
  5.  echo Application is already stopped
    
  6. else
  7.  echo kill $PID
    
  8. kill $PID
    
  9. fi

2.4、重启项目

  1. #!/bin/bash
  2. echo stop application
  3. source stop.sh
  4. echo start application
  5. source start.sh
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值