目录html
SpringBoot入门 (一) HelloWorld. 2前端
一 什么是springboot 1java
二 入门实例... 1mysql
SpringBoot入门 (二) 属性文件读取... 16web
一 自定义属性... 15正则表达式
二 自定义属性配置文件... 18redis
SpringBoot入门 (三) 日志配置... 21spring
日志格式及内容... 21sql
日志输出... 22数据库
输出文件... 22
集成log4j 23
SpringBoot入门 (四) 数据库访问之JdbcTemplate. 29
一 JDBC回顾... 28
二 JdbcTemplate使用示例... 29
三 测试,使用Junit Test 34
四 链接池配置... 36
SpringBoot入门 (五) 数据库访问之spring data jpa. 39
一 什么是Spring Data JPA.. 38
二 简单示例... 38
三 测试... 42
SpringBoot入门 (六) 数据库访问之Mybatis. 46
一 什么是Mybatis. 46
二 SpringBoot集成Mybatis. 47
三 测试... 51
SpringBoot入门 (七) Redis访问操做... 53
一 什么是Redis. 53
二 SpringBoot集成Redis. 54
三 测试... 55
SpringBoot入门 (八) Cache使用... 60
一 为何要使用缓存... 59
二 使用Cache. 60
1 @Cacheable. 61
2 @CachePut 62
3 CacheEvict 63
一 什么是MQ.. 64
二 SpringBoot集成Active MQ.. 65
一 邮件发送过程... 72
二 发送邮件示例... 73
一 什么是数据校验... 80
二 使用示例... 82
一 SpringBoot 提供的定时任务... 87
二 SpringBoot集成Quartz. 90
springboot是一个全新的框架,它设计的目的简化spring项目的初始环境的搭建和开发,主要有如下几个特色:
一、简化初始配置 ,可与主流框架集成;
二、内置Servlet容器,无需在打War包;
三、使用了Starter(启动器)管理依赖并版本控制;
四、大量的自动配置,简化开发,方便集成第三方;
五、提供准生产环境运行时的监控,如指标,健康,外部配置等;
六、无需XML配置,减小冗余代码 。
未使用springboot时,若是咱们要搭建一个springweb项目环境,咱们须要配置web.xml及各类xml的配置文件来集成其余第三方的框架,而这些springboot已经帮咱们作了集成,咱们再也不须要去配置。
建立springboot项目有2中方式,1种是经过ide来建立,一种是官方网站建立(https://start.spring.io建立完成后会将工程下载到本地)而后导入ide便可,本文咱们经过idea建立项目。
1 在idea的工具栏 file-->new project 以下图
会弹出选择工程类型的框,以下图
这个时候咱们有2种选择,一种是使用Spring Initializr建立,一种是使用Maven或者Gradle建立。这两种方式的不一样的地方是使用方法二建立的是空项目,咱们须要本身去修改添加所须要的依赖,方式一在建立的过程当中,咱们能够在ide中直接选择须要的依赖且会生成一个项目的根启动类。本文咱们使用Spring Initializr来建立项目。点击上图的Next
输入Group、Artifact、Package的对应的信息,再点击next
这是咱们能够选择咱们的项目要运行的springboot的版本和须要的依赖包(本文咱们只选择依赖web),而后点击Next
这是弹框会显示咱们项目的名称及项目的路径,点击Finish。初始时会下载springboot默认依赖的一些jar包,须要一会时间,咱们等待它下载完成。以后咱们能够看到项目的结构
pom.xml内容以下,2.0.8版本不是一个发布版本,在咱们的实际项目中,最好仍是要引用release版本的。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.allen.demo</groupId>
<artifactId>springboot-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-helloworld</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
</project>
生成的启动类,一个可执行的main方法。
package org.wl.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
默认在类上边使用了@SpringBootApplication注解,这个注解是一个符合注解,至关于同时使用
@SpringBootConfiguration 指定类为配置类
@EnableAutoConfiguration 开启自动配置
@ComponentScan 指定扫描路径
下来建立一个能够访问的控制器,使用@RestController注解,它是一个复合注解,至关于同时使用了@Controller和@ResponseBody注解
package org.wl.demo.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello world";
}
}
执行main方法,启动项目,在控台可能够看到启动的日志信息
[ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
[ main] org.wl.demo.HelloWorldApplication : Started HelloWorldApplication in 3.591 seconds (JVM running for 4.784)
内嵌的tomcat服务器已经启动,启动端口是8080,更路径是'',咱们访问控制器的hello方法
这样一个web项目环境就搭建成功了,使用起来仍是很简单方便的。
在上边的日志信息中,默认启动端口是8080,访问根路径是‘’,若是咱们但愿修改的话也是能够的,只须要在application.properties中修改
修改端口,从默认的8080修改成8090
server.port=8090
修改根路径 修改前是‘’,修改后为‘/helloworld’
server.servlet.context-path=/helloWorld
在上一篇中介绍了在idea中建立springboot工程及使用web工程输出“helloworld”到前端页面,本文学习在springboot工程中读取属性文件中的属性值。
在application.properties文件中添加属性配置项
myapp.name=helloworld
可使用@Value 注解来读取,在以前的helloworld工程的控制器中添加属性并读取,以下
@RestController
public class HelloController {
@Value("${myapp.name}")
private String name;
@RequestMapping("/hello")
public String hello(){
System.out.println("myapp name :" + name);
return "helloworld";
}
}
@Value 注解会去application.properties文件中配置属性为myapp.name的属性,并将值赋值给name属性。访问hello方法,能够看到控制台上打印出来的信息
自定义的属性比较少时使用@Value读取仍是比较方便的,若是咱们的属性比较多的时候,好比咱们要读取数据库链接池配置的不少的属性值,再这样读取的话,就显得不是很美观了。这种状况咱们通常定义一个对象,把属性字段做为对象的属性来接收,在属性文件中在增长一个属性
myapp.age=2
咱们定义一个对象MyAppProperties来接收属性值
@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name;
private int age;
@Override
public String toString() {
return "MyAppProperties{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//省略getter和setter方法
}
@Component 表示指定当前类为实例,以即可以在spring中使用
@ConfigurationProperties(prefix = "myapp") 表示把application中的myapp开头的属性自动赋值给当前对象的属性,好比把myapp.name的值赋值给name属性,访问hello方法能够看到。
有的时候,咱们须要把本身的属性配置信息写在本身的配置文件中,以便和系统的application.properties分开,咱们能够在resources目录下新建本身的属性文件my.properties,并添加属性
my.name=helloworld2
my.age=22
定义读取属性的对象类,使用 @PropertySource("classpath:my.properties") 来指定咱们当前类要读取的属性文件
@Component
@PropertySource("classpath:my.properties")
@ConfigurationProperties(prefix = "my")
public class MyAppProperties2 {
private String name;
private int age;
@Override
public String toString() {
return "MyAppProperties2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// 省略getter和setter方法
}
修改控制器hello方法测试
@RestController
public class HelloController {
@Resource
private MyAppProperties myAppProperties;
@Resource
private MyAppProperties2 myAppProperties2;
@RequestMapping("/hello")
public String hello(){
System.out.println(myAppProperties.toString());
System.out.println(myAppProperties2.toString());
return "helloworld";
}
}
访问hello方法,能够看到控制台输出的打印信息
上一篇博文记录了再springboot项目中读取属性文件中配置的属性,本文学习在springboot项目中记录日志。
日志记录在项目中是很常见的一个功能了,对排查问题有很大帮助,也能够作分类分析及统计。SpringBoot内部使用的是Commons Logging作日志的记录,可是对其余的日志框架也提供了默认的配置,如:Java util Logging,Log4j2,Logback,每一种状况下日志记录器都预先配置为使用控制台输出和可选的文件输出。
若是咱们的SpringBoot项目使用的是Starters启动器,默认使用LogBack作日志记录。如咱们启动项目时在控制台上看到的
输出的信息有如下几点
日期和时间:精确到毫秒,如 2019-01-24 14:03:14.260
日志级别:日志级别有ERROR,WARN,INFO,DEBUG,TRACE,如上边的INFO
进程号:如上边的 10348
分割线:如上边的 ---
线程名:如上边用[]括起来的
日志名:通常使用的是代码的类名
日志信息:咱们在代码中要输出的内容
Spring Boot中默认配置了ERROR、WARN和INFO级别的日志输出到控制台,咱们也是能够修改的日志级别的,好比咱们修改成debug级别,有两种方式
1 使用命令 $ java -jar myapp.jar --debug
2 在application.properties中添加配置debug=true 开启debug,此配置只会对核心Logger(如内嵌的tomcat容器、hibernate、spring)有效,可是咱们本身应用的日志并不会输出为DEBUG级别,须要本身配置,如 logger.level.root=debug
日志级别
能够经过logger.level.*=LEVEL来改变对应日志级别,如
1 2 3 4 5 6 7 8 |
logging.level.root=warn logging.level.org.springframework.web=info logging.level.org.hibernate=error
######修改mubatis日志级别 logging.level.org.mybatis=info #mapper接口为debug级别 logging.level.mybatis mapper接口所在包=debug |
SpringBoot默认只在控制台输出日志信息,若是想把日志信息写入文件中记录,须要在application.properties中配置,如
1 2 3 4 5 6 7 8 |
##文件存放路径 logging.path=/usr/local/log ##写入的文件 logging.file=myapp.log ##日志文件大小,超过大小时会在新的文件中记录 logging.file.max-size=10Mb ##日志保存时间 天 logging.file.max-history=15 |
SpringBoot在高版本中已经不支持log4j了,支持的是log4j2。在pom.xml中引入须要的log4j2的jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
因为web依赖包中已经有了log的依赖,因此咱们选去掉web中的log依赖,避免jar包冲突。
而后配置log4j2的属性,在官方文档中能够看到集成的日志文件的命名以下
在resources目录下建立一个log4j2-spring.xml文件
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<properties>
<!-- 文件输出格式 -->
<property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} |-%-5level [%thread] %c [%L] -| %msg%n</property>
</properties>
<appenders>
<!--添加一个控制台追加器-->
<Console name="Console" target="system_out">
<PatternLayout pattern="${PATTERN}" />
</Console>
<!--添加一个文本追加器,文件位于E:\\logs目录下,名为HelloWorld.log-->
<File name="File" fileName="E:\\logs\\HelloWorld.log">
<PatternLayout>
<pattern>${PATTERN}</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</File>
</appenders>
<loggers>
<root level="info">
<appenderref ref="File" />
<!--为了直观,在控制天中也输出info级别的日志-->
<appenderref ref="Console" />
</root>
<!--把org.springframework包下的全部日志输出到log文件,additivity="false"表示不输出到控制台-->
<Logger name="org.springframework" level="debug" additivity="true">
<appenderRef ref="File" />
</Logger>
</loggers>
</configuration>
正式项目中,咱们须要对上述xml文件中的配置信息作些修改。写一个控制器访问,看看输出的信息
@RestController
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/hello")
public String hello(){
logger.info("使用log4j输出日志!");
return "helloworld";
}
}
控制台和生成的log文件中输出的信息一致
最先是在上学时接触的使用JDBC访问数据库,主要有如下几个步骤:
1 加载驱动 Class.forName(Driver)
2 获取数据库链接 conn = DriverManager.getConnection(url, user,password)
3 建立一个statement对象来访问操做数据库 statement = conn.createStatement();
4 执行SQL,访问操做数据库 rs = statement.execute(sql)
5 获得结果集,业务处理
6 关闭链接,释放资源 statement.close(); conn.close();
使用jdbc访问并操做数据库时比较麻烦,后来也作了必定的封装,主要是对statement的建立前和sql执行后进行的封装。
目前咱们使用的主流的开源的数据库访问框架主要有Hibernate,Mybatis,SpringJdbc。SpringJdbc时spring对JDBC封装后的一个ORM框架,JdbcTemplate就是SpringJdbc对外提供的一个访问数据库的接口类,咱们经过它能够很容易的实现数据库的访问操做。可是须要咱们本身根据业务手写相关的SQl,而后执行。
在spring boot项目中引入依赖,本文练习中使用的时MySql数据库
1 2 3 4 5 6 7 8 9 |
|
|
|
在application.properties中配置数据库链接相关信息
1 2 3 4 5 6 7 8 9 |
|
完成以上配后,在启动springboot项目时,会自动把数据源信息注入到JdbcTemplate中,咱们只须要在使用的地方注入JdbcTemplate就能够了
定义要操做数据库的相关方法接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
1 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
|
|
能够看到,使用JdbcTemplate时咱们彻底省去了使用JDBC时的建立链接,释放资源等操做。不一样数据库的分页查询不同,MySql中用的limit关键字,第一个参数表明获取数据的起点,第二个是要查询的数量,如:limit 5,5 咱们查询出来的是第6行到10行 共5条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
在启动项目时,能够看到在控制台上输出的日志信息中有如下内容
在咱们没有配置数据库链接池时,springboot默认给咱们提供的Hikari链接池。若是咱们像使用其余的,咱们能够本身配置,好比咱们想使用阿里的Druid链接池,咱们须要引入依赖
1 2 3 4 5 |
|
为了测试方便,我这里直接用@Value注解来获取配置信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
@SpringBootConfiguration 这个注解说明当前类是一个配置类,须要被特殊处理,在扫描时发现有@Bean 注解,会把当前方法返回的类Bean注入的容器中,方法名会别标记为注入的Bean的别名,如上JdbcTemplate使用的DataSource就从默认的Hikari修改成Druid了,启动项目能够看到控制台日志信息
本文记录学习使用spring data jpa访问数据库
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象、关联映射工具来管理Java应用中的关系数据。主要是为了简化现有的持久化开发工做和整合ORM技术,对不一样的ORM框架提供统一的规范标准。
Spring Data JPA 是Spring基于Hibernate框架和JPA(Java Persistence API)规范的基础上封装的一套JPA应用框架,它提供了增、删、改、查等一些经常使用得方法供开发者调用,能够轻松实现实现对数据的访问和操做。
要使用spring data jpa,咱们首先须要在pom.xml中引入所须要的依赖jar包
1 2 3 4 5 6 7 8 9 |
|
在application.properties文件配置数据源链接信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
建立一个实体对象,完成与数据库表之间的映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
@Entity 说明当前类为一个实体类,默认属性name能够不输入,默认就是当前类名
@Table(name="t_user") 说明当前类映射的数据库表是t_user
@Id 说明该字段是表的主键
@GeneratedValue(strategy = GenerationType.AUTO) 说明主键的生成策略是 GenerationType.*,*有AUTO、INDENTITY、SEQUENCE 和 TABLE可供选择
@Column(name = "name", nullable = true, length = 30) 说明当前字段在数据库表中对应的列属性,name:表中的列名,nullable:容许为空,length:长度不超过30
前边已经说过了,Spring Data JPA 已经给咱们提供了具体的接口供调用,因此只须要继承他的方法来使用就能够了,建立接口并继承JpaRepository
1 2 3 |
|
在IDEA中打开类图(如上图),能够看到咱们继承的JpaRepository 经过继承关系已经有了增删该查(CrudRepository)和分页排序(PagingAndSortingRepository),因此咱们的UserRspository也就有了对应的方法
使用Junit作个简单的测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
|
本文记录学习在SpringBoot中使用Mybatis。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎全部的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录(官方定义);
官方使用示例代码以下:
1 2 3 4 5 6 7 8 9 10 |
|
经过示例程序能够看到它的执行过程主要有如下几个步骤:
1 应用程序启动时,根据配置文件生成一个SqlSessionFactory;
2 经过SqlSessionFactory的到一个SqlSession;
3 SqlSession内部经过Excutor执行对应的SQl;
4 返回处理结果;
5 释放资源;
Mybatis使用有2中方式,一种是使用注解,即在接口定义的方法上经过注解写入要执行的SQL和要完成的数据映射;一种是使用xml配置文件即在xml文件中写相关SQL和完成表与实体的映射。本文咱们使用xml文件。
首先须要引入SpringBoot集成Mybatis的依赖jar包,这里咱们只引入了Spring与Mybatis集成的包,springboot默认会自动帮咱们引入其余依赖的jar包。
1 2 3 4 5 |
|
在application.properties文件中配置数据库链接信息和指定mybatis的接口对应的xml
1 2 3 4 5 6 7 |
|
如上,咱们的mapper xml文件放在reources目录下的mybatis文件夹下
写一个接口,定义咱们要完成的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
@Mapper 该注解说名当前类是一个Mybatis的Mapper接口类,交给spring管理,令一种方式是使用注解 @MapperScan(basePackages="...") 说明basePackages及其子包下的接口都交给spring管理,咱们多数状况下都会使用@MapperScan这个注解,这样咱们就不用在每个Mapper接口上写注解了。
在xml文件中完成SQl,实现具体的方法,以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
从这个xml文件,咱们能够看到如下几点:
1 namespace="org.allen.demo.dao.UserMapper" 经过namespace来指定将当前xml文件的SQL实现的对应的接口Mapper
2 经过 resultMap 完成实体类与数据库表字段的映射
3 xml中的SQL语句都必须写在<select> <insert> <update><delete>内部
4 每个标识的id都必须与接口中的方法名保持一直
5 insert 中使用的 useGeneratedKeys 设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。若是设置了true,咱们就能够在insert完成后直接经过当前操做的实体类获取数据库主键。
使用Junit作测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
本文记录学习在SpringBoot中使用Redis。
Redis 是一个速度很是快的非关系数据库(Non-Relational Database),它能够存储键(Key)与 多种不一样类型的值(Value)之间的映射(Mapping),能够将存储在内存的键值对数据持久化到硬盘,可使用复制特性来扩展读性能,还可使用客户端分片来扩展写性能。Redis主要有如下几个优势:
1 性能极高,它每秒可执行约 100,000 个 Set 以及约 100,000 个 Get 操做;
2 丰富的数据类型,Redis 对大多数开发人员已知的大多数数据类型提供了原生支持,这使得各类问题得以轻松解决;
3 原子性,由于全部 Redis 操做都是原子性的,因此多个客户端会并发地访问一个 Redis 服务器,获取相同的更新值;
4 丰富的特性,Redis 是一个多效用工具,有很是多的应用场景,包括缓存、消息队列(Redis 原生支持发布/订阅)、短时间应用程序数据(好比 Web 会话、Web 页面命中计数)等。
目前咱们经常使用的Value的数据类型有String(字符串),Hash(哈希),List(列表),Set(集合),Zset(有序集合)。
SpringBoot提供了对Redis的集成的模块,包是spring-boot-starter-data-redis,它依赖于 spring-data-redis 和 lettuce,lettuce是一个线程安全的redis客户端。
在pom.xml中引入依赖
1 2 3 4 |
|
在application.properties中配置Redis的链接信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
有了上边这两个步骤以后,咱们启动服务后,SpringBoot就会帮咱们链接到Redis服务器,并给咱们提供了一个RedisTemplate类供咱们使用操做Redis。咱们在须要用的地方注入RedisTemplate就能够轻松完成操做。
使用Junit作测试,在咱们的单元测试类中注入RedisTemplate
1 2 3 4 5 6 7 8 |
|
String字符串操做,value是一个字符串,经过delete(key)删除
1 2 3 4 5 6 7 8 9 |
|
对象操做,value是一个对象
1 2 3 4 5 6 7 8 |
|
设置key的过时时间,在set时加上过时时间,经过hasKey(key)来判断key是否还存在
1 2 3 4 5 6 7 8 9 10 |
|
hash哈希操做
1 2 3 4 5 6 |
|
在上边的代码中能够看出,Hash Set的时候就是在哈希表 Key 中的域(Field)的值设为 value。若是 Key 不存在,一个新的哈希表被建立并进行 Hash set 操做;若是域(Field)已经存在于哈希表中,旧值将被覆盖。
List列表操做
1 2 3 4 5 6 7 8 |
|
列表操做时咱们经过 leftPush 或者 rightPush 来将数据存入列表中,经过 leftPop 或者rightPop将数据取出来,咱们能够利用它来实现一个队列。
Set集合操做
1 2 3 4 5 6 7 8 9 |
|
Set是一个没有顺序的集合,key相同时,若是value已经存在了,后边进入的会把前边的覆盖掉
ZSet有序集合操做
1 2 3 4 5 6 7 8 9 10 |
|
add 方法的3个参数分别是key,value,数据插入位置。ZSet中存储的数据都是有顺序的,输出时顺序按照存储时设置的从小到大,若是遇到key相同,Value和顺序同样的,后边的会把前边的覆盖掉,range方法后边的2个参数时插入的位置。如上的输出
本文记录学习在SpringBoot中使用Cache。
缓存是一个数据交换的缓冲区,在一些条件下能够替代数据库。举个例子:咱们有一个查询的业务,访问数据的频率特别高,且每次访问时的查询条件都同样,数据库的数据一直保存不变,这样咱们每次查询出来的结果都是同样的。为了下降高频率访问数据库给数据库带来的压力,咱们能够在第一次访问后把数据缓存起来,之后再作相同查询时只去缓存中取数据,而不用取数据库再作查询。
SpringBoot对缓存作了支持以供咱们方便快速的使用,咱们只须要引入相关依赖就能够了。在项目启动时会自动根据配置进行识别和初始化操做。
在pom.xml文件中引入对Cache支持的依赖
1 2 3 4 |
|
要使用Cache,咱们必须在启动时开启Cache,
@EnableCaching 说明开启缓存
1 2 3 4 5 6 7 8 9 |
|
Spring Cache有3个比较重要的注解@Cacheable,@CachePut,@CacheEvict,咱们一个一个说明:
这个注解代表对操做进行缓存,它能够放在类上,代表对当前类中全部的方法的结果进行缓存;也能够放在方法上,代表对当前方法的结果进行缓存。它有3个参数:
Value 缓存的名称
Key 缓存的键,能够为空,若是指定要按照 SpEL 表达式编写;若是不指定,则缺省按照方法的全部参数进行组合
Condition 缓存触发的条件,返回值是true和false,只有知足条件的状况(true)才会加入缓存,默认为空,既表示所有都加入缓存,支持 SpEL表达式。
实现代码
|
咱们的方法中有一个参数,模拟数据库查询时的条件,如上,当咱们的参数name的长度大于2时,参数加入的缓存中。若是咱们请求http://localhost:8080/hello?name=ch,无论咱们请求多少次控制台中都会打印出‘没有走缓存,去数据库查询数据’,说明缓存没有触发,若是咱们请求http://localhost:8080/hello?name=cache,第一次请求时控制台会打印出‘没有走缓存,去数据库查询数据’,以后不会再有,说明在方法执行前会先去缓存中看是否有结果,有则返回结果,没则执行请求方法,如第一次请求时执行后已经对结果进行了缓存,咱们再请求时会直接去缓存中取结果,不会再去执行方法请求数据库了。
它与@Cacheable相似,都是说明要作缓存,并且属性Key,Value,Condition的用法都同样,也可使用在类或者方法上,区别是它每次都会执行实际方法(如查询数据库)
代码实现
1 2 3 4 5 6 |
|
当咱们请求http://localhost:8080/hello1?name=cache时,无论咱们请求第几回,都会在控制台输出‘没有走缓存,去数据库查询数据’。若是数据库数据发生了变化,则会用新的数据替换以前的同value同Key缓存的数据。
它是用来清除缓存的,一样是能够标记在类和方法上,标记在类上时说明全部方法都会清除缓存。Key,Value,Condition属性用法与Cacheable同样,还有2个属性allEntries和beforeInvocation。
allEntries表示是否删除缓存中的全部属性,默认是false,表示不,true表示是。当被指定为true时,会忽略掉指定的Key而删除全部。
beforeInvocation表示删除缓存的时机,默认是false,表示在方法执行完后才删除缓存,true表示在方法执行前就先删除缓存。在方法执行过程当中若是发生了异常,默认设置下(false)将不能删除掉缓存。
代码实现
|
使用一样的参数如cache,先请求执行hello方法进行数据缓存,在执行hello2进行删除缓存操做,而后再执行hello1方法会发如今控制台上又输出了‘没有走缓存,去数据库查询数据’,说明执行hello2方法时已经将缓存删除掉了。
注:SpEL(Spring Expression Language)是一个支持运行时查询和操做对象图的强大的表达式语言,其语法相似于统一 EL,但提供了额外特性,显式方法调用和基本字符串模板函数。
本文记录学习在Spring Boot中使用MQ。
MQ全称(Message Queue)又名消息队列,是一种异步通信的中间件。它的做用相似于邮局,发信人(生产者)只须要将信(消息)交给邮局,而后由邮局再将信(消息)发送给具体的接收者(消费者),具体发送过程与时间发信人能够不关注,也不会影响发信人作其它事情。目前常见的MQ有activemq、kafka、rabbitmq、zeromq、rocketmq等。
使用MQ的优势主要有:
1 方法的异步执行 使用MQ能够将耗时的同步操做经过以发送消息的方式进行了异步化处理,减小了因为同步而等待的时间;
2 程序之间松耦合 使用MQ能够减小了服务之间的耦合性,不一样的服务能够经过消息队列进行通讯,只要约定好消息的内容格式就行;
JMS(Java Message Service)即java消息服务,是一个Java平台中关于面向消息中间件(MOM)的 API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通讯。JMS的消息机制有2种模型,一种是1对1(Point to Point)的队列的消息,这种消息,只能被一个消费者消费;另外一种是一对多的发布/订阅(Topic)消息,一条消息能够被多个消费者消费。ActiveMq是对JMS的一个实现。
官网下载一个服务程序,解压后直接启动服务就能够了,下载地址:http://activemq.apache.org/activemq-5158-release.html
SpringBoot也对Active MQ提供了支持,咱们使用时引入具体的依赖便可,修改pom.xml文件,添加依赖
1 2 3 4 |
|
在application.properties文件中配置Active MQ服务器的链接信息
1 2 3 4 5 |
|
完成以上配置信息后,当咱们在启动SpringBoot项目时,会自动帮咱们完成初始化操做,并提供一个JmsMessagingTemplate,提提供了咱们经常使用发送消息的各类方法供咱们使用。咱们只须要在使用的地方注入JmsMessagingTemplate便可使用。
发送队列消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
消息的接收方,监听消息队列,当队列中有消息时就能够获取到消息
|
执行测试方法发送消息能够看到,控制台输出的消费者接受到消息
队列消息只能有一个消费者,若是有多个消费者同时监听一个队列时,只能有一个拿到消息,咱们测试,修改发送方法,循环发送10调消息
|
在Consumer 类中再添加一个消费者,监听队列zyQueue
|
执行发送消息,看到控制台输出的结果,2个消费者平分了这10条消息
若是但愿监听同一个队列的多个消费者都能接收到全部消息,咱们就只能发送Topic消息了,咱们修改application.properties中的
|
咱们在Consumer 类中添加两个消费者来监听zyTopic队列,接受消息
|
执行发消息方法,能够看到控制台输出的内容,2个消费者都完整的接收到了5条消息
咱们在测试发送消息时修改了属性文件中的配置信息,才能够发送对应的类型的消息,这是因为SpringBoot中默认的是队列消息(查看源码能够知道,监听器默认使用的DefaultJmsListenerContainerFactory),若是咱们想在不修改配置信息的状况下能够同时发送Queue和Topic消息怎么办呢,咱们须要手动的更改初始的配置类,分别针对Queue和Topic消息提供JmsListenerContainerFactory
新建一个配置类,以下
|
在容器启动时会针对两种消息类型,初始化获得两个不一样的JmsListenerContainerFactory。下来再修改消费者类,在 @JmsListener 注解中指定 containerFactory,如
|
Queue消息使用 queueListenerFactory,Topic消息使用 topicListenerFactory,而后注释掉属性文件中的消息模式配置就能够了。
本文记录学习在SpringBoot中发送邮件。
发送邮件是一个咱们在项目中常常会用到的功能,如在用户注册时发送验证码,帐户激活等都会用到。完整的一个邮件发送过程主要包含如下几个步骤:
1 发件人在用户邮件代理上写邮件内容及收件人的邮箱地址;
2 用户邮件代理根据发件人填写的邮件信息,生成一封符合邮件格式的邮件;
3 用户邮件代理把邮件发送到发信人的邮件服务器上;
4 发件人的邮件服务器使用 SMTP 协议把这封邮件发送到收件人的邮件服务器上;
5 收件人的邮件服务器收到邮件后,把这封邮件放到收件人在这个服务器上的信箱中;
6 收件人使用用户邮件代理来收取邮件。
之前发送邮件时,调用 JavaMail 的相关 API 来开发实现,须要咱们本身去组装消息体,代码量比较大,实现起来也不是很容易;Spring 提供的JavaMailSender 对JavaMail的Api作了必定的封装,简化了发邮件的过程。JavaMailSender 提供了强大的邮件发送功能,可支持各类类型的邮件发送。Spring Boot在JavaMailSender 的基础上又作了进一步的封装,让咱们的使用更加的简单。
在pom.xml文件中引入须要得依赖
|
在application.properties中配置邮件服务相关信息(测试使用得是QQ邮件服务)
|
完成了上边得配置后,在启动服务得时候,SpringBoot会根据咱们得配置,为咱们初始化好一个JavaMailSender类供咱们调用,咱们只须要在要使用得地方注入就能够了。
定义一个邮件服务接口,提供咱们得邮件服务方法,其余业务中用到发邮件功能时,调用这个接口就能够了
|
|
如上,咱们在实现类中注入JavaMailSender后直接调用它send方法就能够完成发邮件。其余业务中用到发邮件业务了,直接调用EmailSenderService 接口得方法便可。咱们彻底也能够把JavaMailSender直接注入到咱们得各个业务模块中去,在发邮件时直接调用JavaMailSender得send方法发邮件。可是仍是推荐将邮件发送相关功能独立起来,便于维护。
上边咱们实现了发送一个文本邮件,有时候咱们还须要在发送邮件时附带发送附件,这种也是支持的,咱们添加接口及实现方法
|
|
若是咱们发送邮件时,除了收件人以外,还想让某些人知道即抄送某些人,这种也是支持得,接口及实现方法以下:
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
如上方法就实现了向多人发送邮件而且抄送多人
本文记录学习在SpringBoot中作数据校验。
数据校验就是在应用程序中,对输入进来得数据作语义分析判断,阻挡不符合规则得数据,放行符合规则得数据,以确保被保存得数据符合咱们得数据存储规则。
在SpringMvc中作数据校验有2中方式:一种是 Spring 自带的验证框架,另一种是利用 JSR 实现。JSR 是一个规范,提供了完整得一套 API,经过标注给对象属性添加约束。Hibernate Validator 就是 对JSR 规范全部注解的具体实现,以及一些附加的约束注解。用户还能够自定义约束注解。Hibernate Validator提供得注解以下:
注解 |
做用目标 |
检查规则 |
@Length(min=, max=) |
属性(String) |
检查字符串长度是否符合范围 |
@Max(value=) |
属性(以 numeric 或者 string 类型来表示一个数字) |
检查值是否小于或等于最大值 |
@Min(value=) |
属性(以 numeric 或者 string 类型来表示一个数字) |
检查值是否大于或等于最小值 |
@NotNull |
属性 |
检查值是否非空(not null) |
@Future |
属性(date 或 calendar) |
检查日期是不是将来 |
@Pattern(regex="regexp", flag=) |
属性(string) |
检查属性是否与给定匹配标志的正则表达式相匹配 |
@Range(min=, max=) |
属性(以 numeric 或者 string 类型来表示一个数字) |
检查值是否在最小和最大值之间(包括临界值) |
|
|
|
|
|
|
|
|
|
@Size(min=, max=) |
属性(array,collection,map) |
检查元素大小是否在最小和最大值之间(包括临界值) |
@AssertFalse |
属性 |
检查方法的演算结果是否为 false(对以代码方式而不是注解表示的约束颇有用) |
@AssertTrue |
属性 |
检查方法的演算结果是否为 true(对以代码方式而不是注解表示的约束颇有用) |
@Valid |
属性(object) |
对关联对象递归进行验证。若是对象是集合或数组,就递归地验证其元素;若是对象是 Map,则递归验证其值元素 |
|
属性(String) |
检查字符串是否符合有效的 email 地址规范 |
@Past |
属性(date 或 calendar) |
检查日期是不是过去 |
SpringBoot对数据校验也作了支持,默认提供的参数校验依赖于 hibernate-validator来实现。使用 Hibernate Validator校验数据,须要定义一个接收的数据模型,使用注解的形式描述字段校验的规则。经过前台页面提交form表单保存数据,后台作校验。
在pom.xml文件中引入依赖
1 2 3 4 5 6 7 8 |
|
写一个实体类,对相关属性字段经过注解添加校验规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
每一个注解中得属性message是数据校验不经过时咱们要给出得提示信息,如 @Email(message="邮件格式不正确") 当邮件格式校验不经过时,提示邮件格式不正确。
控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
咱们经过访问info方法,跳转到信息输入页面,提交数据时访问save方法,Person前得注解@Valid 说明当前对象要作数据校验,BindingResult 中会存储数据校验得结果,@Valid和BindingResult必须成对出现。若是校验不经过时即有错误信息,会进入if略记判断中,返回信息输入页面,展现错误提示信息。
信息输入页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
th:object 要与后台接收校验得对象保持一致。访问info方法在页面随便输入一些信息,在提交数据,会看到校验结果
若是各项数据都符合规则,则校验经过,跳转至success页面
返回第一篇
本文记录在SpringBoot中使用定时任务。
在咱们的项目中,常常须要用到定时任务去帮咱们作一些事情,好比服务状态监控,业务数据状态的更改等,SpringBoot中实现定时任务有2中方案,一种是自带的,咱们只须要加上注解便可;另外一种是集成Quartz来实现定时任务。
在SpringBoot的starter包中已经提供了对定时任务的支持,咱们很容易实现定时任务。修改pom.xml文件,加入以下内容,引入依赖:
|
在启动类上加注@EnableScheduling 注解,开启定时任务
|
建立定时任务类及要定时执行的方法
1 2 3 4 5 6 7 8 9 10 11 12 |
|
@Component 注解 将当前类交给Spring容器管理
@Scheduled 注解标明方法是一个定时执行的方法
启动项目后能够看到控制台打印出的信息
@Scheduled 注解有几个参数可使用,每一个参数的意义不同,参数及执行规则说明以下:
fixedRate @Scheduled(fixedRate = 5000) 上一次开始执行时间点以后每5秒执行一次;
fixedDelay @Scheduled(fixedDelay = 5) 上一次执行完毕时间点以后每5秒执行一次;
initialDelay @Scheduled(initialDelay = 1, fixedDelay = 6) 第一次延迟1秒后执行,以后按照fixedRate的规则执行;
cron @Scheduled(cron = "*/5 * * * * ?") 一个表达式,一共有7位,通常只须要设置6为就能够了
第一位:秒,取值范围是0-59;
第二位:分,取值范围是0-59;
第三位:时,取值范围0-23;
第四位:日,取值范围1-31;
第五位:月,取值范围1-12;
第六位:星期,取值范围1-7,1表明星期日,2表明星期一,7表明星期六;
第七位:年,取值范围1970-099,能够不设置。
cron表达式也能够在http://cron.qqe2.com进行在线生成。
Quartz是用Java编写的一个开源的任务调度框架。提供了丰富的Api供调用,支持集群环境和持久化,支持多种配置,与SpringBoot能够无缝集成。
Quartz几个关键元素:
Job 表明要执行的任务,是个接口,提供了一个方法 execute(JobExecutionContext context);
JobDetail 表明具体的要执行的任务;
Trigger 表明调度任务的触发器,配置调度任务的执行规则;
Scheduler 表明调度容器,一个调度容器中能够注册多个JobDetail和Trigger。
元素关系以下图:
SpringBoot对Quartz已经提供了支持,咱们能够很容易的使用,在pom.xml文件中引入依赖
1 2 3 4 |
|
在启动类上加注解 @EnableScheduling ,开启定时执行。
建立一个要执行的任务继承QuartzJobBean,输出任务执行时间
1 2 3 4 5 6 7 8 9 10 |
|
建立一个配置类,初始化MyTask1任务所须要的JobDetail和Trigger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
启动项目,能够看到控制台输出的内容
在上边的方法,咱们使用的定时执行方法是在代码中写的固定值,这种局限性比较大,难以知足一些复杂的定制任务执行时间。咱们使用Cron表达式来完成定时任务执行时间配置。
建立任务类,继承QuartzJobBean
1 2 3 4 5 6 7 8 9 10 |
|
在配置类QuartzConfig中建立任务所需的JobDetail和Trigger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
重启项目,看到控制台输出内容,任务1每5秒执行一次,任务2每10秒执行一次
备注:此文档借鉴其余博客的,若有问题请及时联系,谢谢